Fork me on GitHub
#code-reviews
<
2016-12-12
>
roelofw13:12:13

someone who can give me a hint. I tried (not ( and (not(every? true? args)) (not-any? true? args))

roelofw13:12:05

that one is good when doing all the test except [true, true, true] which gives now true but it has to be false

gdeer8115:12:27

@roelofw you're on the right track but you've made a mess of your logic so lets try to think of this problem in simpler terms

roelofw15:12:20

I know im on the right track because most of the tests are a success

roelofw15:12:54

I still have difficult to find out which function I need to use

gdeer8115:12:29

I'm trying to figure out a good way of talking you through it without giving away the answer

roelofw15:12:07

I making dinner right now so It can be that i do not respond quick

gdeer8115:12:25

so what function would you use if the requirement was to return true if they were all true or all false?

roelofw15:12:19

every? Returns true if (pred x) is logical true for every x in coll, else false.

gdeer8115:12:53

so you would write (or (every? true? args) (every? false? args)) ?

gdeer8115:12:41

but there is a function that already checks for equality

roelofw15:12:50

yes, I forget that all of then could be false

roelofw15:12:36

yep , 1 = 2 gives false

roelofw15:12:50

and 2 = 2 gives true

roelofw15:12:13

so far im with you

gdeer8115:12:15

and you're getting a bunch of booleans so it's even easier because you don't really need a predicate function

roelofw15:12:05

oke, you you mean something like a map to compare the item with true or false ?

roelofw16:12:07

I was thinking about something like this (and (some true? args) (some? false args))

gdeer8116:12:18

that sounds like you would need a predicate function which I just hinted you don't need

roelofw16:12:22

hmm, I have to do some comparison otherwise I do not know if something is true or false

roelofw16:12:03

so I cannot think of a solution without any predicate

roelofw16:12:45

@gdeer81 I cannot think of a solution that you have in mind

roelofw16:12:56

can you give a hint how I can check this [ true, true, true] is all true without a predicate

roelofw16:12:20

in my opinion = is also a predicate

roelofw16:12:11

or do you mean something like this (map (= true) args)

gdeer8116:12:57

you don't need to map = since it takes a variable number of arguments

gdeer8116:12:21

okay I think I'm just making things confusing, lets go back to the thing you put earlier, (and (some true? args) (some false? args))

gdeer8116:12:42

which cases did that fail on?

roelofw16:12:56

moment, I have to try, this is new idea

roelofw16:12:57

it fails here :

FAIL in (test1) (1_half_truth_test.clj:7)
Half truth - test 1
expected: (= (half-truth true true true true) false)
  actual: (not (= nil false)) 

gdeer8116:12:54

did your function return nil?

roelofw16:12:29

yes, apperently , which is not so wierd.

Returns the first logical true value of (pred x) for any x in coll,
else nil.  One common idiom is to use a set as pred, for example
this will return :fred if :fred is in the sequence, otherwise nil:
(some #{:fred} coll)  

roelofw16:12:54

so some? i returning nill if a item is not found

gdeer8116:12:32

what did you put?

gdeer8116:12:52

it was probably because of your and statement, since one of your statements returns nil your and statement returned nil

roelofw16:12:34

the code we are talking about

(defn half-truth 
  "Solution to Problem 1: 
   Write a function which takes a variable number of booleans. 
   Your function should return true if some of the parameters
   are true, but not all of the parameters are true. 
   Otherwise your function should return false."
  [& args]
  (and (some true? args) (some false? args)))  

roelofw16:12:05

maybe a idea to check if the output is true or false ?

roelofw16:12:26

he, with this one all tests of the stanford are green :

(defn half-truth 
  "Solution to Problem 1: 
   Write a function which takes a variable number of booleans. 
   Your function should return true if some of the parameters
   are true, but not all of the parameters are true. 
   Otherwise your function should return false."
  [& args]
  ( true? (and (some true? args) (some false? args))))  

roelofw16:12:05

chips, but now working here well :

(half-truth [false true false ])
=> false 

roelofw16:12:26

if I read the desription that one schould be true

roelofw16:12:56

nope, the answer always is false

roelofw16:12:08

it seems that there cannot be a solution that works for all cases

agile_geek16:12:59

@roelofw look at what you are passing as an argument in that call to half-truth and what the defn is taking as an argument

agile_geek16:12:21

There's nothing wrong with the code in the body of the defn

roelofw16:12:26

chips, the arguments are all seperate

gdeer8116:12:58

yeah, its good to copy/paste the test cases from the problem so you don't make a typo and craft a solution for a totally different problem

roelofw16:12:05

this looks well to me :

(half-truth true true true )
=> false
(half-truth true true false )
=> true
(half-truth false true false )
=> true
(half-truth false false false )
=> false
 

roelofw16:12:37

so 2 out of the 4 challenges solved of the standford ones

agile_geek16:12:48

@roelofw do you know why false false false or true true true was returning nil until you added the true? predicate around the and

agile_geek16:12:15

Read the docs for some and see if you can work out why

roelofw16:12:43

@agile_geek yes, see here of the docs of some? Returns the first logical true value of (pred x) for any x in coll,else nil

roelofw16:12:03

so if there is nothing that is true when I do (some? true? [false, false, false]) then the answer will be nill

agile_geek16:12:38

Yes and same if nothing false in the other branch of the and

gdeer8117:12:51

@roelofw did you get a working solution yet? can I tell you the answer now?

agile_geek17:12:26

And because and stops once it's evaluated all the predicates (if they're all truthy) or on the first that is falsey and returns the value from the some clause that's falsey you get nil

roelofw17:12:54

@gdeer81 I have this as working solution :

(defn half-truth 
  "Solution to Problem 1: 
   Write a function which takes a variable number of booleans. 
   Your function should return true if some of the parameters
   are true, but not all of the parameters are true. 
   Otherwise your function should return false."
  [& args]
  ( true? (and (some true? args) (some false? args))))  

gdeer8117:12:45

okay, good now I won't feel bad if I accidentally give away the answer I had in mind

roelofw17:12:14

@gdeer81 is it a totally other answer then

roelofw17:12:52

I get this idea when you wrote : (or (every? true? args) (every? false? args))

gdeer8117:12:12

hint 1: this problem can be solved with one function that is in core

roelofw17:12:03

yes, and somebody else said it could be done in 4 characters

roelofw17:12:35

but there are not much functions with 4 characters 🙂

gdeer8117:12:53

well then that should narrow it down

gdeer8117:12:24

write a function that returns all the functions in core that have exactly 4 characters

roelofw17:12:06

that is a difficult one

roelofw17:12:35

oke, with google I succeed

roelofw17:12:01

I can display al functions of core with (dir clojure.core)

gdeer8117:12:09

there are 72

roelofw17:12:18

hmm, filter does not what I expect : (filter (fn[item] (= (count item) 4 )) (dir clojure.core))

gdeer8117:12:12

although this probably isn't helping you think about the problem in simpler terms

roelofw17:12:14

oke, and now I have to read a lot of pages

roelofw17:12:36

no, I see some candidates but no function who looks right

roelofw17:12:32

most promising looks not= but if I read the page I do not think its the one

roelofw17:12:48

some I tried and it is not the answer

gdeer8117:12:22

what does the page for not= say?

roelofw17:12:46

Same as (not (= obj1 obj2))

roelofw17:12:49

hmm, maybe the args could be obj1 and something like [ true , true] as obj2 ?

roelofw17:12:45

or maybe something like this one (not= true true true true)

gdeer8117:12:58

since it is referring to = in the doc string you'd have to read the docs for = to understand how it is supposed to work

roelofw17:12:39

I look at the examples and these look very good :

(not= false false false )
=> false
(not= true false false )
=> true
(not= true true true )
=> false  

roelofw17:12:15

(not= true false true )
=> true  

roelofw17:12:44

so it will be (not= args)

roelofw17:12:54

a very short one

gdeer8117:12:41

or you could just pass in the function itself without having to wrap it since #(not= %&) is the same as just passing in that function itself

roelofw17:12:13

nope, this case is failing :

FAIL in (test2) (1_half_truth_test.clj:11)
Half truth - test 2
expected: (= (half-truth true false true) true)
  actual: (not (= false true))
 

roelofw17:12:27

it gives false

roelofw17:12:13

and because there a two true and one false , t schould give true

snoe17:12:24

replace args with the value and you'll see why

snoe17:12:55

or, what is args?

roelofw17:12:27

args is a vector so here [false false]

snoe17:12:59

so when you do (not= args) you are doing (not= [false false])

gdeer8117:12:22

so I retract my statement above

roelofw17:12:37

chips , & args gives a vector and not the input itself 😞

gdeer8117:12:54

#(not= %&) is not the same as bare not=

snoe17:12:35

take a look at apply @roelofw

roelofw17:12:16

@gdeer81 this is also not working :

(defn half-truth 
  "Solution to Problem 1: 
   Write a function which takes a variable number of booleans. 
   Your function should return true if some of the parameters
   are true, but not all of the parameters are true. 
   Otherwise your function should return false."
  [& args]
  #(not= %&))  

roelofw17:12:42

it fails with this :

FAIL in (test1) (1_half_truth_test.clj:7)
Half truth - test 1
expected: (= (half-truth true true true true) false)
  actual: (not (= #object[pset1.1_half_truth$half_truth$fn__205 0x1133976 "[email protected]"] false))  

agile_geek17:12:56

@roelofw args is being coerced into a sequence in you argument vector in the defn of half-truth

roelofw17:12:23

yes, That is what I said earlier, @agile_geek

gdeer8117:12:36

@roelofw you've gone over your four character limit

agile_geek17:12:47

but you are calling half-truth with a variable number of arguments and not= takes a variable number of arguments so you don't need to coerce args to a sequence

gdeer8117:12:07

you don't need to define a new function, just pass in not=

gdeer8117:12:52

however, if you do want to wrap it in your own function you will have to unroll the args

roelofw17:12:55

@agile_geek so I can change [& args] to [ args]

agile_geek17:12:17

not if you want it in separate fn

agile_geek17:12:43

just use not= or use apply to unroll args

roelofw17:12:28

so somehing like (not= (apply args)) ????

agile_geek17:12:53

if you keep your fn and change argument to [arg] it will only expect one arg

gdeer8117:12:01

@roelofw what does the doc string for apply say?

roelofw17:12:20

'(apply function args) `

roelofw17:12:51

so (apply (not= ) args)

agile_geek17:12:26

it's the function you're applying not the evaluated function

agile_geek17:12:10

remember putting a fn in parens makes Clojure evaluate it

roelofw17:12:40

the function is (not= args) , Right ?

agile_geek17:12:50

thats the evaluated function

agile_geek17:12:03

i.e you are calling the fn not=

agile_geek17:12:14

with the argument args

roelofw17:12:50

oke, so it would be (apply (not=) args)

gdeer8117:12:04

that will give you an arity exception

roelofw17:12:10

yes, I does

agile_geek17:12:15

That's still evaluating not= but with no args

roelofw17:12:03

I will take a break, my head is spinning

agile_geek17:12:41

So what happens if Clojure evaluates this (not=) which gives an arity exception, and then tries to pass the result to (apply <result of calling not=> args)

roelofw17:12:47

apply wants a function and some arguments and I cannot see what the function is and what the arguments

agile_geek18:12:00

What is the name of the function

gdeer8118:12:14

consider this example (+ [1 2 3])

gdeer8118:12:32

how could you use apply to make + work with this vector?

roelofw18:12:44

there + is the function and [1 2 3 ] as a arguments I think

roelofw18:12:14

so (apply (+) [ 1 2 3 ] )

agile_geek18:12:43

What is the reuslt of (+) on its own

snoe18:12:44

what does (+) evaluate to?

roelofw18:12:59

but schould this not be in #beginner or #clojure ?

roelofw18:12:19

a function ??

snoe18:12:26

(fn? (+))

snoe18:12:35

vs (fn? +)

gdeer8118:12:07

heading to lunch now, keep at it, you're almost there

roelofw18:12:27

I do not have that feeling

agile_geek18:12:30

so if (+) evaluates to 0

roelofw18:12:42

yes, I saw it on your code

agile_geek18:12:45

then this (apply (+) [1 2 3])

agile_geek18:12:09

is same as (apply 0 [1 2 3])

roelofw18:12:39

I think this will be (+ 1 2 3) at the end

roelofw18:12:17

so something is still not right

roelofw18:12:25

the + has to stay

snoe18:12:29

no, it will be (0 1 2 3) apply only sees the substituted value

roelofw18:12:13

apply is not easy to understand

agile_geek18:12:53

It is when you get the hang of it. At the moment you are passing it the result of evaluating a function, not the function itself

snoe18:12:32

yeah but understanding apply is fundamental to lisp, understand it and other things will make sense too

agile_geek18:12:58

i.e. in the + example you were evaluating + (+) which is 0 and then passing that to apply but 0 is not a function

agile_geek18:12:30

hence the class cast exception in Clojurebot ☝️

roelofw18:12:51

what I want is something like this (fn [ acc item] ( acc + item)) Like I will do when using a map or reduce

snoe18:12:14

@roelofw do you know other languages?

agile_geek18:12:18

You could use reduce but apply is easier

roelofw18:12:23

a little bit ruby

roelofw18:12:05

@agile_geek that part I understand now

roelofw18:12:32

but I do not see how I can make it work with apply at this moment, sorry

snoe18:12:40

apply is like the splat operator not_equal(*args)

agile_geek18:12:05

So you need to pass apply the unevaluated +

agile_geek18:12:42

As you evaluate + using parens (+), how would you pass + not evaluated?

roelofw18:12:15

oke, so without the ()

roelofw18:12:53

so it would be `(apply + [1 2 3])

roelofw18:12:31

oke, so back to our code

agile_geek18:12:36

So in your half-truth example you can use apply with not=

roelofw18:12:48

(apply not= args) ?

agile_geek18:12:57

what does (apply not= [true true false]) give you

roelofw18:12:14

all test provided by the standford challenges are green

agile_geek18:12:19

So now you know a way of calling a function that takes separate multiple arguments when you have a collection of arguments

roelofw18:12:39

yes, I learned a lot today from you and some others

roelofw18:12:55

now time for the dishes 😞

roelofw18:12:39

and tomorrow try to find out how to find the nth row of a pascal triangle

roelofw18:12:25

but I noticed how more you know of clojure how shorter the code it seems

roelofw18:12:39

All thanks and have a good day/evening

gdeer8118:12:16

@roelofw I was going to ask you to now try and solve it with set theory

roelofw18:12:40

the same exercise with a set

gdeer8118:12:30

yeah your function rolls up the arguments into a collection, so what happens if you called (set args) ?

roelofw18:12:07

( count (set(args) > 1) out if my head

gdeer8118:12:16

exactly right

roelofw18:12:44

so if there are more then 1 arg then there is one or more true or false

roelofw18:12:31

if there is only 1 the seq contains only true or false

gdeer8118:12:32

okay, I updated my statement

roelofw18:12:56

@gdeer81 happy with the solution

gdeer8118:12:48

the readability could be improved. how many items does the set have every time its suppose to return true?

roelofw18:12:13

more then1

gdeer8118:12:41

but it will never have 3

roelofw18:12:05

nope,, its 1 or 2

roelofw18:12:29

1 if the items are all true or false, 2 if both

gdeer8118:12:59

so what is more readable (= 2 (count (set args))) or (> (count (set args)) 1) ?

roelofw18:12:22

I think the first

snoe19:12:21

ofc things look a bit different with 0 or 1 args

gdeer8119:12:19

well this is assuming that this is being called with (defn [& args] ...) so the args are always being rolled up

roelofw19:12:46

I have asummed the same

roelofw19:12:59

So I have earned a C today 🙂

gdeer8119:12:49

the point is that you've come away from this experience knowing more than you knew when you came in

roelofw19:12:06

yep, today I did

gdeer8119:12:15

then today you get an A

roelofw19:12:45

learned to read stack traces and where the error can be found

roelofw19:12:53

learned apply

roelofw19:12:31

learned not=

roelofw19:12:05

I hope I can use it later on when needed

gdeer8119:12:29

and you've learned when Clojure "rolls up" arguments and what that means

roelofw19:12:44

that will be the biggest challenge on the standford and 4clojure challenges

gdeer8119:12:25

You've also learned the difference between a function and a function evaluation

roelofw19:12:57

that is why my head is spinning

roelofw19:12:47

learned how to refractor functions so I can test them

gdeer8119:12:48

I think it's confusing because as a beginner you're taught to always hug your functions

roelofw19:12:01

hug my functions ??

gdeer8119:12:40

so (apply + [1 2 3]) looks weird because you want to hug that plus sign (+)

gdeer8119:12:35

this is what tripped me up when I started learning the -> macro

roelofw19:12:27

oke, I use the ->> on my first attempt for a website but there I had not make this mistake

gdeer8119:12:11

this was quite a thorough code review

roelofw19:12:57

with a lot of explanation , I wonder if some of this schould not be in beginners or the clojure channel

roelofw19:12:45

Now with 4clojure I have to reimplement zipmap and with the stanford challenges I have to find the nth row of a pascal triangle

roelofw19:12:55

both not easy

roelofw19:12:18

but now time for family

roelofw20:12:12

@gdeer81 if you want and have time , do you want to review the last version of my paintings website : https://github.com/rwobben/paintings

gdeer8120:12:33

yeah I'll take a look and see if I notice any glaring issues

roelofw21:12:46

thanks, do it only if you have time