This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-12-10
Channels
- # admin-announcements (32)
- # announcements (4)
- # aws (25)
- # beginners (296)
- # boot (1)
- # cider (87)
- # clara (16)
- # cljs-dev (7)
- # cljsrn (41)
- # clojure (121)
- # clojure-art (26)
- # clojure-japan (4)
- # clojure-miami (190)
- # clojure-russia (168)
- # clojure-sg (3)
- # clojure-sweden (13)
- # clojurescript (138)
- # clojurex (7)
- # cursive (98)
- # data-science (2)
- # datomic (129)
- # devcards (10)
- # editors (5)
- # funcool (1)
- # hoplon (31)
- # jobs (1)
- # ldnclj (4)
- # lein-figwheel (3)
- # off-topic (2)
- # om (213)
- # onyx (33)
- # parinfer (7)
- # portland-or (1)
- # re-frame (19)
- # reagent (2)
- # ring-swagger (27)
- # slack-help (3)
yes. this is the code I have so far : https://www.refheap.com/112536
sorry I forget . Here a better paste : https://www.refheap.com/112537
@roelof: you wanted output like
[{:name "head1", :size 3}
{:name "head2", :size 3}
{:name "head", :size 3}
{:name "left-eye", :size 1}
{:name "eye2", :size 1}
right?so eye1 and eye2, the numbers are based on the parameter you passed here? (symmetrize-body-parts2 asym-hobbit-body-parts 2)
so only for the parts that starts with left I wanted to change it to part-number without the left
part-number is the number which comes out of the range function. it needs to stop on n + 1 because otherwise I get one part less
@roelof: not sure i'll have time to finish it but the gist of what i might do is (str (clojure.string/replace (:name part) #"^left-" replacement))
in here i would use a capture group to perform the replacement at the end of the string. i'm not sure how to do this in clojure but you'd look into capture groups. and then to get rid of the "left" thing completely from the array i would apply a filter to the output
i'll get back to you if i figure out the capture group thing, kind of important thing for me to know as wlel 😛
no problem. This problem has no rush. IM trying to learn clojure as a hobby so no dead lines
(clojure.string/replace (:name part) #"^left-(.*)" #(str (last %1) replacement))
this would give you the replacement at end of the part
from there you just need to remove the "-" in your range function then use a filter to remove the "left" parts
can someone explain to me how does supplying mixin maps via 'extend' allow implementing one function at a time? (of the protocol
as far as i understood, even if i use mixin maps, the map still needs to have all the functions of the protocol
if the map just has a partial set, and if later add more function keys to the map, it wont help right? since the map is immutable
btw @roelof would recommend http://clojurekoans.com I went through this a few days ago and was really nice to get jump started on clojure
(if (not (re-find #"left" name))
{:name (clojure.string/replace (:name part) #(str (last %1) replacement) ):size (:size part)}
part
)
@roelof: do you have some more context ? it's not clear what part
looks like, or what result you are expecting
@mccraigmccraig: here you have to code : [{:name "head" :size 3} {:name "left-eye" :size 1}
sorry. better url : https://www.refheap.com/112541
and the output must look like this :
[{:name "head" :size 3}
{:name "eye1" :size 1} {:"name "eye2" :size 1} ]
@mccraigmccraig: I hope it clear.
@roelof: i'm not clear on what you are trying to do to the list of parts...
firstly, what do you want matching-part2
to do to a part...
What I want is that the parts which begin with left are converted to part-1 without the left
what is part-1 ?
and {:name "left-eye" :size 1} must become {:name "eye1" :size 1} , {:name "eye2" :size 1} depending on the value of n
and where is n
coming from ? is that replacement
?
n is a number how many parts the user wants so if n = 2 then I want to have 2 eyes , if n = 3 then I want to have 3 eyes
but there is no n
in the function matching-part2
?
@mccraigmccraig: I try to solve exercise 6 of this page : http://www.braveclojure.com/do-things/
correct the n is already used on the other function. matching part must only do the convert from left-eye to eye1
@roelof: does this do the transform you want ? https://www.refheap.com/632c2e9054f7e9d8d2bf8b201
good luck - sorry i don't have time to dig into the whole exercise... hope that was helpful
it looks to work except I see this : {:name "left-ear", :size 1} and I want to convert that to {:name "ear1", :size 1}
@roelof: i see (matching-part2 {:name "left-ear" :size 1} 10) ;=> {:name "ear10", :size 1}
@mccraigmccraig: thanks for the help
@roelof: do some other exercises and come back to it in a week and refactor. Amazing what not thinking about the problem for a bit does. Subconscious works on the problem in the meantime.
@agile_geek: thanks, I will work on 4clojure and the next chapters of the brave book
@roelof: to read a resource I tend to use io/resource like so:
(read-string (slurp (io/resource file)))
This will look in your resources dir if you are using lein and project.clj.
according to the book (slurp filename) is enough but I see then a message that the file is not found
If you use slurp on it's own you need to specify the filename relative to project home dir.
If you do it using io/resource you dont
so I can use io/resource only on the slurp part not on the part where I define the name of the file
Also if you package the app as a standalone jar using lein uberjar
later it will copy the resources dir to the root of the jar so if you specified the filename as 'resources/suspects.csv' it would work from lein repl
but not from java -jar <name-of-project.jar>
You can do this
(def filename (io/resource "suspects.csv"))
BTW io
is defined as this (:require [
So advantage to using resource is that you can use same filepath for resources dir and the root of the jar
then I can work through the chapter core-functions-in-depth of the brave and truth book
using slurp and just string for filepath would mean changing the filepath between the repl and the jar.
Got to go back to work now. Good luck.
Me too!
I think on clojure you never stop learning. I learn as a beginner every day new things
@agile_geek: thanks again. I can now start on the challenges
Hi! What would be a cleaner way of doing this?
(:require [clj-time.core :as t])
;...
(let [t0 (t/now)] (t/date-time (t/year t0) (t/month t0) (t/day t0) (t/hour t0)))
one maybe stupid beginners question. How can I make a vector of records so the new entry will be appended at the end. here is the code :
(defn append
"append a new suspect to the database"
[name glitter-index records]
(conj records {:name name :glitter-index glitter-index})
)
@polymeris: it's not shorter but you could use a formatter to format the date an hour.
(def custom-formatter (f/formatter "yyyy-MM-dd hh"))
then coerce it back to date-time.takes a lot more lines of code though
I think what you are doing maybe most succinct and efficient.
thanks, @agile_geek
this gives a error message :
(conj vec (records {:name name :glitter-index glitter-index}))
Just what I was going to ask
@roelof: and what do you want the output to be?
I now see this output :
({:name "roelof", :glitter-index 2}
{:name "Edward Cullen", :glitter-index 10}
{:name "Bella Swan", :glitter-index 0}
{:name "Charlie Swan", :glitter-index 0}
{:name "Jacob Black", :glitter-index 3}
{:name "Carlisle Cullen", :glitter-index 6})
:thumbsup:
@polymeris: thanks the is the answer . I put the ending ) for vectors at a wrong place
now the challenge that I need to make a validation function for input name and input schould not be empty
IM thinking something like (and (not(empty? {:name :name} )) (not(empty? {:glitter-index glitter-index}))
@roelof: You are at the same point as me 😄 I think the exercise also requires a verification function to be ran for each element, which will be passed in as a map of keywords to function names to call
oke, so first a check for names and then a check for gitter-index so a nested if @rantingbob
@rantingbob: I had this :
(defn validate
"looks if name and glitter-index are not empty"
[name glitter-index]
(if (and (not(empty? {:name :name} )) (not(empty? {:glitter-index glitter-index})))
(append name glitter-index (mapify (parse (slurp filename))))
(println "input cannot be valided"))
)
and when I change it to this (if (and (not(empty? name )) (not(empty? {glitter-index})))
I see this error message: CompilerException java.lang.RuntimeException: Map literal must contain an even number of forms
Also, and this might be a style thing, but that validate function is both doing the append, and the mapify and printing out an error
Personally, I'd only have it validate the entries, then return true or false if it's valid or not
so you could go (when (valid entry) (append entry))
@rantingbob: I m trying that way
I have this now :
(defn validate
"looks if name and glitter-index are not empty"
[name glitter-index]
(if (or (:name name) (:glitter-index glitter-index))
(println "validated")
(println "not validated")
))
oke, when I do (validate "roelof" 2) it worked fine . When I do (validate "" 2) I still see the message validated
yeah, it should be and, right now it says "if either of these things are true the entry is valid"
you want "if both of these things are true"
@agile_geek: In your customer-formatter
, what does f
resolve to, what is it?
@cjmurphy: are you asking in the right channel. as far as I can see agile-geek has not posted a question for some time
Well from Java or anywhere else "" is indeed the empty String - that's always been my understanding of the term.
oke, then I wonder why (validate "" 2) is validated on this function (and (or (empty? (:name name)) (empty?(:glitter-index glitter-index)))
I was just looking at (empty? (:name name))
, maybe (nil? (:name name))
would be the way to go??
Hmm - I prolly s/not be commenting as don't understand these problems - but you did ask.
Anyone has an idea on how to express this cleaner:
(fmap #(reduce (fn [acc x] acc (:f x)) 0 %)
{:a '({:f 1 :b 10} {:f 2 :b 20} {:f 3 :b 30})
:b '({:f 4 :b 40} {:f 5 :b 50})})
pff, I begin to think FP is not for me . Also this is not working :
(defn validate
"looks if name and glitter-index are not empty"
[name glitter-index]
(if (and ( not (nil? name)) (not (nil? glitter-index)) )
(println "validated")
(println "not validated"))
)
(if (and (not (empty? name)) (not(nil? flitter-index)) valid invalid) should work I blieeve
thing to remember, an ampty string isn't nil or falsy
I don't know if its empty either, I think that refers to collections
yeah you want blank
(defn validate "looks if name and glitter-index are not empty" [name glitter-index] (if (and ( not (clojure.string/blank? name)) (not (nil? glitter-index)) ) (println "validated") (println "not validated")) )
I think that works, pardon poor formatting
Thanks, the line you post is working. I had to use empty? for the name and nil? for the index
blank for the name and nil for the index
nil? specifically checks if a value is nil, empty? checks if a sequence is empty, blank? checks if a string is blank
(:name name) didn't work because name was a string, and you can't take a keyword out of a string
check out http://conj.io for a quick cheatsheet
@polymeris: what is it you want your function to return? {:a 6 :b 9}
?
correct, @codonnell
(into {} (map (fn [[k v]] [k (reduce + 0 (map :f v))]) m))
is a decent solution, I think. I named your map m
.
hah...I was getting there too. Just had to install lein on my windows machine...you beat me to it 😛
Perhaps #(get % :f 0)
would be more robust, instead of just :f
I'm curious how you got to it...what was the thought process?
Mine was "I need to sum all of the :f in each val in the map so I'm going to 'map extract-and-sum-f m'" then for extract and sum I'm probably doing something like 'reduce + get-all-fs' where gett-all-fs is something like 'map :f v'
If that makes sense
I usually think from the inside out. First, I wanted to turn the maps into their :f
value. And do this for all of the maps for a particular key, so (map :f v)
.
then I'm going to massage that into a new map
I need to turn those numbers into their sum, so the reduce
, and I want to do that for each [k v]
pair in the hash-map, which brought me to my outer map
call.
Since map
returns a seq, we turn that back into a map with into {}
interesting that we both came at it from different directions
We had a similar thought process, I think.
we did, but you went inside out and I went outside in
interesting exercise
I think inside out because I can check my steps more easily in the repl.
If I try to do it all at once, I usually make mistakes and have a harder time checking.
So, i'm pretty new, whats the benefit of fmap?
So I thought this would work :
(defn convert-back
"convert the map back to strings"
[records]
(map (fn [it] (clojure.string/join it) records ))
)
@polymeris: what does fmap
do? I haven't encountered it before.
Don't be too hard on yourself @roelof. Getting used to functional programming solutions to problems is quite challenging; you really have to think in different ways.
@roelof: think about what map does, what you are doing there is looping over each map in your vector of maps and calling str.join. so if you have { [1 2] [a b]} you are trying to join [1 2] to [a b] when you want to be joining the contents of those vectors
You are on the right lines, you just need to join the vectors contents too
so its a wrapper around (into {} (map f...
@roelof: so yo uwant to be doing something like (map (join-with-newline) (map (join-with-comma) m))
so first you create a sequence containing [1 2] and [a b] as strings ["1,2" "a,b"} then you reduce (not map) over that, joining them toghether
I think that makes sense I'm just as new as you so this might be the blind leading the blind 😄
oke, I tried this (map (fn [{:name name :gitter-index gitter-index}] (clojure.string/join name gitter-index )) records ))
but now gitter-index in the anymous function cannot be resolved says cursive
I think thts because you have your function arguments incorrect. Don't worry about destructuring the argument for the moment. I would just take an entry and work with that
so (fn [entry] (clojure.string/join "," (vals entry))
you get the vals from the entry, and join them with ","
oke, a little bit further . if I do (map (fn [it] (clojure.string/join (:name name) )) records )
I see this : ("" "" "" "" "")
because it should be (:name it)
and you should probably give it a seperator
check the docs on http://conj.io for an idea what it needs to take
I checked the docs and I do not get it working. I have now this (map (fn [it] (clojure.string/join (:name it) (:gitter-index it) ) records ))
and this (map (fn [it] (clojure.string/join "," [(:name it) (:gitter-index it)] ) records ))
gives a object
yeah, string join expects a collection
so rather than getting the values independently, just get them as acollection
(vals it) should do the trick I believe
That way your working with the abstraction and it doesn't matter if it has :name or what have you in it
Do you have a repl?
this seems to work : (map (fn [it] (clojure.string/join "," (vals it) )) records )
only I see a set
If I ever get stuck like this I susually try to think in smaller chunks and work in the repl. I'll def some temporary to (first records) and get a function that joins them. Then I'll play with map to get a sequence of joined strings, then I'll work with reduce to get a single joined string
rather than trying to solve the whole thing at once. Then I'll usually refactor it top down if I can
I do only tend ot think about it bottom up like that if I get stuck though
I'm pretyt sure map always returns a seq?
@rantingbob: oke, this part is working (clojure.string/join "," (vals {:name "Edward Cullen", :glitter-index 10} ) )
Excellent
hah. Fair. No problem. And you're going to reduce, join, onto a blank string.
http://www.lispcast.com/annotated-clojure-core-reduce is a good xplanation of reduce
@rantingbob: then I think I know how to make it work
You should be able to yes
well...(reduce (join-with-newline) "" (map (the-above-function-that-joins-with-comma) m))
so (map (join-with-comma) m) should return you a seq containing all your "rows" with there contents joined by commas
then you need to reduce over that seq putting together your final string
Yeah I think I missunderstood your question
its a very different way of thinking if you've only programmed with imperative languages or OOP before
It's worth it though. Once you get it it's quite a bit of fun, and oh god you write so much less code
so I have to think how to join with the newline. I do not think I can use it on both functions
first worry about getting ( "joined,string" "joined1,string1" etc.)
Then worry about turning that into "joined,string/njoined1,string1"
as I say, I would first worry about getting each record joined yb commas in a single string
stupid fingers
first worry about getting each record joined by commas into a single seq
then work out how to turn that seq of strings into a new string joined by newlines
I hope that was helpful. I'm honestly not much further along than you are. The key is to think about data transformation, how do I turn A into B. Then try and think about abstractions. Try not to use :name etc.
and think in small bites.
anyway, sleep well
I promise, you'll get there and its fun
Yes, it is
Does the portland area have much of a clojure community? I know the conj/west was there
at this moment I find it no fun. Every challenge is a fight and my energy is low due to a illness
Then dude...give it a break for abit
don't force it or you'll hate it
anyone know the syntax for the compojure urls? Can they be straight regex's and if so what key do the groups end up under the request?
Is there a way to route a multifn with a wildcard / variables? That is to say, if I have something like:
(defmulti an-example (fn [x y] [x y]))
Which routes to the appropriate example based on the argument vector, can I then do
(defmethod an-example [:simple _])
which would accept everything that has :simple as a first argument, ignoring the second?
Or
(defmethod an-example [:complex :complex-option-1])
(defmethod an-example [:complex :complex-option-1])
which looks at both options?Hi, all. I’m genuinely stumped here. I’m using Korma to run SQL queries, and I’m wondering why this doesn’t work?
(def db (create-db (mysql {:db “my_db" :user "root"})))
(def users (create-entity "users"))
(with-db db (select users))
I get this error: CompilerException com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.* FROM "users"' at line 1
This does work, though, even as it’s supposed to be another way of writing the above:
(defdb db (mysql {:db “my_db” :user “root”}))
(defentity users)
(select users)
Yeah, I think this might be a korma bug
@lambdahands: I have a very vague memory of having run up against something like that & it turned out to be a Korma version issue -- docs were outdated on the subject, and only one syntax was supported in the newest version. Seriously, though, it's possible I'm imagining that entirely.
I see every line in your example is changing; might be worth going back & isolating the change to a single difference if possible.
Yeah, I think the discrepancy lies in with-db
. If I’m stuck much longer I’ll open an issue as the behavior is very odd; the error is rather esoteric as well.