difference/relation between str and print-str in Clojure - clojure

I was reading Volkmann's Clojure tutorial, in that tutorial it says the function print-str prints the content to a string that is returned. So does this mean that:
(print-str a b c ... ) == (str a " " b " " c " " ... )
I tried with my REPL and it behaved like I assumed above, but I just want to know if it really is, or I am missing something here...

The function print-str will return a string similar to what REPL would report if asked to evaluate the argument, e.g. for human consumption. The function str invokes the .toString of the object. In the case of a string argument, the result is the same as you point out.
This is not in general true for other objects
((juxt print-str str) 1N)
;=> ["1N" "1"]
((juxt print-str str) (java.util.Date.))
;=> ["#inst \"2013-07-19T01:47:00.784-00:00\"" "Thu Jul 18 20:47:00 CDT 2013"]

Related

Keep quotation marks in a formatted list Racket

How do you print a formatted string with quotation marks, and without the backward slashes?
For example, when I enter
(format "say ~a" "hello there!")
I want to get
" say "hello there!" "
I want the quotation marks wrapped around "hello there" as the way I typed in. However, if I format it as a string, it turns out like this:
"say \"hello there!\""
Is there a way to keep the quotation marks without having the backward slash?
evaluating strings, and print/println print the quote " as\".
Maybe you're looking for display/displayln:
(displayln (format "say \"~a\"" "hello there!"))
; => say "hello there!"
use ~s instead of ~a
> (format "say ~s" "hello there!")`
"say \"hello there!\""

How to read input from the end of printed line in Clojure?

(println "The number is: " (read-line))
(read-line) reads coming input from a new line.
How to read from the end of printed string instead of a newline?
Like in C:
printf("The number is: ")
scanf("%d", &value)
If you do the (read-line) inside the print it will be executed first (blocks and waits for the user-input, then the "question" and the user input will be printed).
Instead use do to execute multiple things one after another. To force the output of the print (not println), use flush:
(do
(print "The number is: ")
(flush)
(read-line))
; The number is: 666
; => "666"
do returns with the last result.

Converting a javascript function using Clojure

I'm kind new in the Lisp/Functional/Clojure world and I've a JS function:
function buildString(someInteger) {
var question = "Initial text";
if (someInteger == 1) {
question += " put this string ";
} else if(someInteger == 2) {
question += " oh! another string ";
} else if(someInteger == 3) {
question += " guess what? ";
}
return question;
}
What could be a good way to rewrite this to a Clojure function? I already have some code using the "cond" Clojure macro, but I'm not sure about the immutable string "question":
(defn build-string [some-integer]
(let [question "Initial text"]
(cond
(= some-integer 1) (str question "Add string one")
(= some-integer 2) (str question "Add string two")
(= some-integer 3) (str question "Add string three"))))
You want the cond-> macro:
(defn build-string [some-integer]
(let [question "Initial text; "]
(cond-> question
(= some-integer 1) (str "Add string one")
(= some-integer 2) (str "Add string two")
(= some-integer 3) (str "Add string three"))))
(build-string 1) => "Initial text; Add string one"
(build-string 2) => "Initial text; Add string two"
(build-string 3) => "Initial text; Add string three"
although in this case plain old cond will work:
(defn build-string [some-integer]
(let [question "Initial text; "]
(cond
(= some-integer 1) (str question "Add string one")
(= some-integer 2) (str question "Add string two")
(= some-integer 3) (str question "Add string three"))))
#cfrick makes a good point:
(defn build-string-map [some-integer]
(let [question "Initial text; "
data {1 "Add string one"
2 "Add string two"
3 "Add string three"}
suffix (get data some-integer)
result (str question suffix)]
result))
(build-string-map 1) => "Initial text; Add string one"
(build-string-map 2) => "Initial text; Add string two"
(build-string-map 3) => "Initial text; Add string three"
Be sure to look at the
Clojure CheetSheet
ClojureScript CheetSheet
clojure.org
clojurescript.org
Your cond form is fine, but you can use case here:
(defn build-string [some-integer]
(str "Initial text"
(case some-integer
1 "Add string one"
2 "Add string two"
3 "Add string three")))
Your “immutable string question”: in contrast to your JavaScript version, none of the operators you or I have been using modify any of their arguments. For example, Clojure's str builds a new string, but JavaScript's += modifies a variable. You need not worry: it is not a mistake to modify things in Clojure that you would need to keep an eye out for, but rather the language makes it difficult to do it in the first place. If you see a simple function using standard operators, it is very improbable for it to be doing something unsafe.
If you have just some "equal number" checks, i'd just go with a map. E.g.
(str "Initial text" ({1 "Add string one" 2 "Add string two" 3 "Add string three"} some-integer))
Or just go with condp. E.g.
(defn build-string
[some-integer]
(str "Initial text"
(condp = some-integer
1 "Add string one"
2 "Add string two"
3 "Add string three"
nil)))
(map build-string (range 4))
; => ("Initial text" "Initial textAdd string one" "Initial textAdd string two" "Initial textAdd string three")
I think the keypoint here is to eliminate duplication; not only eliminate the "length" but also eliminate the "width" of your code.

CLIPS - if then else function gives [CSTRCPSR1] err

Here is the error summary:
CLIPS> (load "C:/Users/labor/Desktop/Witek/projekt.CLP")
Defining defrule: R1 +j+j
Defining defrule: R2 +j+j
Defining defrule: R3 =j+j+j
Defining defrule: imie-if =j=j+j+j
[CSTRCPSR1] Expected the beginning of a construct.
And here is the code for my CLIPS program. Basically I want it to react different if the name and last name are different from Abraham Lincoln.
(defrule R1
(initial-fact)
=>
(printout t "Enter your name:" crlf)
(bind ?name (read))
(assert (name ?name)))
(defrule R2
(name ?name)
=>
(printout t "Enter your last name" crlf)
(bind ?lastnm (read))
(assert (lastnm ?lastnm)))
(defrule R3
(and(name ?name)(lastnm ?lastnm))
=>
(printout t "How old are you " ?name "?" crlf)
(bind ?age (read))
(assert (age ?age)))
(defrule name-if
(name ?name)(lastnm ?lastnm)(age ?age)
=>
(if(and(eq ?name Abraham)(eq ?lastnm Lincoln))
then (printout t "Hello " ?name " " ?lastnm ", you are " ?age " years old bro" crlf))
else (printout t "Hello " ?name " " ?lastnm ", you are " ?age " years old" crlf)))
I copied the if statement logic from some webpage and I am not quite sure what, in this case, 'eq' stands for... i'd appreciate if you could additionally explain the role of it.
Regards,
W
You have an extra right parenthesis at the end of the then clause that is causing the issue. The Mac OS and Window CLIPS IDEs have a balance command that you can use to see if the parentheses are properly balanced within a construct. Just click inside a construct and apply the balance command several times until the entire construct is selected. If you place the cursor by the then keyword and balance, you'll see that the if statement is closed by the parenthesis at the end of the then clause and the else clause is left dangling.
The corrected rule is:
(defrule name-if
(name ?name)
(lastnm ?lastnm)
(age ?age)
=>
(if (and (eq ?name Abraham)
(eq ?lastnm Lincoln))
then
(printout t "Hello" ?name " " ?lastnm ", you are " ?age " years old bro" crlf)
else
(printout t "Hello " ?name " " ?lastnm ", you are " ?age " years old" crlf)))
The eq predicate is short for equals. Unlike the = predicate that expects numeric arguments, eq compares values of any type.

What is the Python 3 equivalent of %s in strings?

I've made some basic progress in python before, nothing more than command land algebra calculators to do math homework, using user-defined functions, inputs, and basic stuff. I've since taken the Python 2 course that codeacademy has, and I'm finding no equivalent of using % and %s for PY3.
I've narrowed it down to having some relation to format() , but that's as far as I could find on Google.
As a beginner, I'd really appreciate a watered down explanation to how to translate this into Python 3:
str1 = "Bob,"
str2 = "Marcey."
print "Hello %s hello %s" % (str1, str2)
EDIT: Also, I'm aware that print("Hello " + str1 + "hello " + str2) would work.
str.__mod__() continues to work in 3.x, but the new way of performing string formatting using str.format() is described in PEP 3101, and has subsequently been backported to recent versions of 2.x.
print("Hello %s hello %s" % (str1, str2))
print("Hello {} hello {}".format(str1, str2))
This should work as intended:
str1 = "Bob,"
str2 = "Marcey."
print("Hello {0} hello {1}".format(str1, str2))
While the use of % to format strings in Python 3 is still functional, it is recommended to use the new string.format(). It is more powerful and % will be removed from the language at some point.
Go on the Python website to see changes from Python 2.7 to Python 3 and the documentation contains everything you need.
:)
The % operator is not related to print; rather, it is a string operator. Consider this valid Python 2.x code:
x = "%s %s" % (a, b)
print x
Nearly identical code works in Python 3:
x = "%s %s" % (a, b)
print(x)
Your attempt would be correctly written as
print("%s %s" % (a, b))
The % operator is analogous to the C function sprintf, not printf.
Use f-strings in Python 3
prefix the string with f or F for variables and expressions inserted between curly braces inside the string to be evaluated inline:
str1 = "John Cleese"
str2 = "Michael Palin"
age1 = 73
age2 = 78
print(f"Hello {str1}, hello {str2}, your ages add to {age1 + age2}.")
Note the Python3 brackets in print(). Apparently, string interpolation is faster than the .format() syntax of Python 2.
The method you are using is still available in Python 3 (str.mod()).
In addition to this you can make use of string formatting in Python.
e.g:
print("This is {}".format("sparta")) #gives output
"This is sparta"
or
a = "Sparta"
b = "King"
print("This is {} and I am its {}".format(a,b)) #gives output
"This is Sparta and I am its King"