print and return another value in Clojure - clojure

I have a Clojure beginner question about why the following code doesn't work :
(defn aFun [n]
(if (< -10 n 10)
((println "Single digit" n) "A return value")
((println "More digits" n) "Another return value")))
I get a NullPointerException at runtime. Why ?
This function works :
(defn aFun [n]
(if (< -10 n 10)
"A return value"
"Another return value"))
And this one too :
(defn aFun [n]
(if (< -10 n 10)
(println "Single digit" n)
(println "More digits" n)))
I'd like to do both at the same time however : (compute and) return a value, while printing some things first. I'm sure this is pretty basic (not even sure how to title my question), but I can't get what I am doing wrong.

((println "Single digit" n) "A return value")
... attempts to apply (println "Single digit" n), which returns nil, as a function, to "A return value".
You probably intend
(do (println "Single digit" n) "A return value")
Try, where you can, to separate side-effects from pure functional computation. Here, for example,
(defn single-digit? [n]
(< -10 n +10))
... is pure. You can wrap it in stuff that prints what you like.

Related

Clojure is-prime function?

I am doing is-prime? function that should return true if n is prime and false otherwise, it also should check to see if n is 1 or 2 and respond accordingly; if not, it should call no-divisors function. At the moment I get this output :
Can anyone see what's wrong, would be much appreciated
expected result is false,current false
expected result is true,current true
expected result is true,current false
expected result is false,current false
expected result is true,current false
no-divisors?
(->> (range 2 n)
(filter #(Divides % n))
empty? ))
(println (no-divisors? 4))
is-prime?
(defn is-prime? [n]
(and (< 1 n)
(not-any? (filter #(no-divisors? % n))
(range 2 n))))
(println "expected result is false,current"( is-prime? 1))
(println "expected result is true,current"( is-prime? 2))
(println "expected result is true,current" ( is-prime? 3))
(println "expected result is false,current"( is-prime? 4))
(println "expected result is true,current"( is-prime? 101))
If you format your code per Clojure conventions, it's pretty clear what the problem is:
(defn is-prime? [n]
(and (< 1 n)
(not-any? (filter #(no-divisors? % n))
(range 2 n))))
You're calling filter with a single argument which with return a transducer. Your call to not-any? then tries to treat that transducer as a predicate and since a transducer, given a single argument, returns a function -- and a function is "truthy" (not nil or false) then not-any? will return false per its definition.
The reason it returns true for 2 is that (range 2 2) is an empty sequence and not-any? returns true for an empty sequence without calling the predicate.
Some suggestions:
Several people have asked you for complete, well-formatted code. Provide
it. It will help you think clearly.
Use integer? and < to make sure you are testing a possible prime.
A prime is a number with no proper factors. Define it as such. You
are doing the work twice - Russian doll style.
It is easier to test your function on a range of possibles. I used (filter prime? (range -20 20)), yielding (2 3 5 7 11 13 17 19).
Name the function prime?. That's the Clojure convention. The initial is- is redundant. This may seem nit-picking, but simpler is clearer.
Best of luck!

Clojure set string value

I have a variable "testtext".
Depending on a other variable "testvalue", thats always the value 1 or 2, it needs to be set to something.
So if testvalue is 1, i need to set testtext to "its one".
And when testvalue is 2, i need to set testtext to "its two".
Right now i have:
(cond
(= testvalue 1) (var-set testtext "its one")
(= testvalue 2) (var-set testtext "its two")
:else (var-set testtext "ERROR")
)
But i get the error "String cannot be cast to clojure.lang.Var"
So my question is, how do i properly set a string value, assuming that's what I did wrong.
You want something more like this:
(let [result (cond
(= testvalue 1) "its one"
(= testvalue 2) "its two"
:else "ERROR" ) ]
(println "result:" result))
Using var-set is very rare in Clojure. I can't answer in too much more detail without knowing your exact use-case.
If you really need something like a Java variable, you could use a Clojure atom:
(def result (atom nil))
(cond
(= testvalue 1) (reset! result "its one")
(= testvalue 2) (reset! result "its two")
:else (reset! result "ERROR" ))
(println "result:" #result))
You probably want something like:
(defn func
[test-value]
(let [test-var (cond
(= test-value 1) "it's one"
(= test-value 2) "it's two"
:else "ERROR")]
test-var))
=> #'user/func
(func 1)
=> "it's one"
(func 2)
=> "it's two"
(func 3)
=> "ERROR"
The let form let's you assign values to vars. Sticking it in a function is a convenient way to return the result.
On most contexts you don't want to modify an existing "variable's" value, instead you use let to bind a value to a symbol. It would be easier to answer if we knew the bigger picture, but as already mentioned atom is a datatype to which you can atomically swap in a new value.
I'd say this is more idiomatic, although not quite what you asked:
(def lookup-table
{1 "its one"
2 "its two"})
(defn make-lookup [i]
(get lookup-table i "ERROR"))
(doseq [i (range 4)]
(println i "=" (make-lookup i)))
Prints:
0 = ERROR
1 = its one
2 = its two
3 = ERROR
Instead of thinking how to assign a value to a variable, you should think what do you want to use that value for.

how to Replace an Integer with string 20 percent of the time Clojure

I need to replace an integer with a string in clojure but only for 20% of the outputted integers.
(defn factor5 [x]
(if (= (mod x 3) (mod x 5) 0) "BuzzFizz"
(if (= (mod x 5) 0) "buzz"
(if (= (mod x 3) 0) "fizz" x))))
here i have a fizzbuzz program which prints out "fizz" if the number is a multiple of 3 or "buzz" if it is a multiple of 5 and "BuzzFizz" is printed if is a multiple of both. if an integer is neither of the above multiplies the integer gets printed. What i need is to print "Boom" instead of the integer but only for 20% of the integers.
some pseudo code
if(x == int){
print out Boom instead of x only for 20% }
else{
print out x}
I have very limited exprience in clojure as my pseudocode is java based
Please see the Clojure Cheatsheet for a comprehensive listing of functions.
The one you want is rand, and a test like:
(if (< (rand) 0.2) ....)
if you want the decision made randomly you could use one of the rand runctions in an if statement like so:
user> (defn x20% [x]
(if (rand-nth [true false false false false])
"Boom"
x))
#'user/x20%
user> (x20% 5)
5
user> (x20% 5)
5
user> (x20% 5)
"Boom"
user> (x20% 5)
5
there are also rand and rand-int. which you use is somewhat a matter of style and the specifics of your function:
user> (> 2 (rand-int 10))
true
user> (> 2 (rand-int 10))
true
user> (> 2 (rand-int 10))
false
user> (> 0.2 (rand))
true
user> (> 0.2 (rand))
(defn factor-5 [x]
(if (and (number? x) (zero? (rem x 1)))
(if (zero? (rand-int 5))
"Boom"
x)))
This returns the required value rather than printing it.
It tests that its argument is numeric, and - if so - that it is a
whole number value, which could be byte, short, int, ... .
(rand-int 5) chooses randomly from 0, 1, ... 4.

Clojure loop with cond

I am working on a Project Euler problem that involves factoring numbers and have written the following function to do that.
(defn get-factors [value]
(let [max-factor (->> (Math/sqrt value)
(Math/floor)
(Math/round))
ifactors #{}]
(loop [n 2 factors ifactors]
(do
(println (format ">> N: %d, Factors: %s" n factors))
(cond
(when (> n max-factor) ; exit of we have passed the max-factor
(do
(println (format "--Exiting(%d): %s" n factors))
factors)) ; return factors
(when (= 0 (mod value n)); have we found a factor?
(do
(println (format"--Factor(%d)" n))
(recur (inc n) (conj factors n (/ value n))))) ; recurse: add _n_ and reciprocal _n_ to list
:default (do ; otherwise
(println (format"--default(%d): %s" n (= 0 (mod value n))))
(recur (inc n) factors)) ; recurse: increment _n_, dont modify factors
)))))
However, the function is returning nil and my println statements are evaluated in a strange order. Here is the output from the REPL for (get-factors 12), which should return #{2,3,4,6}:
>> N: 2, Factors: #{}
--default(2): true
>> N: 3, Factors: #{}
--default(3): true
>> N: 4, Factors: #{}
--Exiting(4): #{}
--Factor(4)
>> N: 5, Factors: #{3 4}
--Exiting(5): #{3 4}
As you can see, the default state is being hit even though the (= 0 (mod value n)) of the previous case evaluates to true. Likewise, the exit condition is hit twice. The last case evaluated should be for n=3, but you can see output for up to n=5.
I'm obviously doing something fundamentally wrong but I am not seeing what. (Related, is there a better way to go about constructing a list?)
First, there is an implicit "when" (or "if") in the test part of any cond so you should not be using when yourself inside that test.
Second, you are using a single form, a when form, as the entire branch of the cond, therefore, the cond does not see the second form it expects when the test is true.
Check out this example of a proper cond:
http://clojuredocs.org/clojure_core/1.2.0/clojure.core/cond
If, as others have suggested, you strip out all the crud - the whens and dos and printlns - your program works!
A few suggestions:
Use quot instead of / to get an integer quotient.
You might as well start your threading macro thus: (->> value (Math/sqrt) ... ).
Use :else, not :default or anything else to introduce the catch-all clause in your cond.

NullPointerException after simple clojure program

I am working on learning clojure, and have run into a NullPointerException that seems to have nothing to do with my code. The program runs to completion before producing the error. The code:
; solves the collatz conjecture
; return one step in the sequence
(defn collatz-step [n]
(if (= (rem n 2) 0)
(/ n 2)
(+ 1 (* 3 n))))
; recurse over all numbers
(defn collatz [n]
(if (= n 1)
(println "All done!")
((println (format "N = %d" n))
(collatz (collatz-step n)))))
; get input and run it
(println "Enter a positive number:")
(collatz (read-string (read-line)))
Is there something I'm missing?
when this line runs:
((println (format "N = %d" n))
(collatz (collatz-step n)))
the println and colatz will finish leving the form like this:
(return-value-of-println return-value-of-collatz)
println returns nil yielding:
(nil return-value-of-collatz)
which is a function call to the function nil resulting in an NPE
take out the extra ()
Clojure does not have tail call elimination, so changing your recursive call to collatz to recur will keep it from blowing the stack on large values of n