This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-05
Channels
- # adventofcode (41)
- # bangalore-clj (4)
- # beginners (283)
- # boot (62)
- # clara (9)
- # cljsrn (3)
- # clojure (112)
- # clojure-brasil (1)
- # clojure-greece (1)
- # clojure-korea (6)
- # clojure-russia (99)
- # clojure-spec (29)
- # clojure-uk (12)
- # clojurescript (34)
- # clojurex (5)
- # core-logic (1)
- # cursive (31)
- # datomic (30)
- # devcards (5)
- # editors (19)
- # emacs (31)
- # events (5)
- # garden (4)
- # hoplon (137)
- # lein-figwheel (3)
- # luminus (4)
- # mount (7)
- # off-topic (7)
- # om (18)
- # om-next (3)
- # onyx (88)
- # proton (1)
- # protorepl (6)
- # re-frame (48)
- # reagent (15)
- # spacemacs (41)
- # testing (1)
- # untangled (2)
- # yada (18)
I'm trying to learn and tool up for a core.logic project. I've found good resources for learning the highlights of some parts. Am I missing some central source for learning all of it?
have you used similar logic programming systems (like prolog) before? I learned prolog in college but you can pretty much learn prolog stuff and apply it directly to core.logic, it's mainly just syntactical differences AFAIK.
@roelofw I wasn't able to require the module from the repl, but it started working automatically later on.
@akiroz I've read some prolog/logic examples and have an idea for how I hope things work. I work for a university; and I'm building something to prove whether our majors can be completed in 4 years with a given plan of course offerings. I imagine I'll be using the simple database stuff a bit. (prerequisite class-1 class-2), etc. It's going to get complicated.
Nice! course registration at my uni was horrible and I could never register for the courses I wanted to take because of timetable/prerequisite issues..... to top it off, the online system is this super slow/buggy Java + OracleDB thing. Ughh...
@roelofw I tried out your code this morning and this works fine:
(defn read-data-painting2
"Reads the title, description, date , collection, colors and url of a image"
[id]
(let [art-objects (-> (str " " id "?key=14OGzuak&format=json&type=schilderij&toppieces=True")
(client/get {:as :json})
:body
:artObject)
name (-> art-objects
:principalMakers
first
:name)
description (:description art-objects)
date (get-in art-objects [:dating :year])
collectie (first (:objectCollection art-objects))
colors (:colors art-objects)]
{:id id :name name :description description :date date :collectie collectie :colors colors}))
(read-data-painting2 "SK-A-1718")
It returns:
{:id "SK-A-1718",
:name "Hendrick Avercamp",
:description
"Winterlandschap met ijsvermaak. Dorpsgezicht met vele figuren op het ijs: schaatsers, kolfspelers, wandelaars. Rechts een arrenslede, links een kerk.",
:date 1608,
:collectie "schilderijen",
:colors ["#B0AD92" " #64614A" " #D7D3BA" " #76806F" " #373B30" " #1F1C15" " #9E824E"]}
I think in one version of the code you had an additional line in the let
: painter (get-in name [:name])
and you had {:id id :name painter :description description :date date :collectie collectie :colors colors}
being returned.
that returned nil
for :name
as name is just a string already so you can't call get-in
on it
I see this as output on my webpage :
{:id"SK-A-2963",
:name #object[clojure.core$name 0x96b47c "clojure.core$name@96b47c"],
:description "Portret van Don Ramón Satué. Lid van de Sala de Alcaldes de Corte per la Audiencia Territorial de Madrid. Heupstuk, naar links, staande met de handen in de zakken.",
:date 1823,
:collectie "schilderijen",
:colors ["#322318" " #0F0E09" " #573525" " #764736" " #796956" " #9F947C" " #BDB89D"],
}
Shame - but there's never been anything magical about :name
keyword. I am testing this just in a normal repl so I'm not serialising it for web but even so the name is just a String so it shouldn't have a problem. I suspect something else is going on. Try calling your fn in a REPL like I did above (read-data-painting "SK-A-1718")
very very wierd, @agile_geek
So something else is going on. It looks like something is evaluating name
symbol as the name
fn
(defn homepage [req] (render-file "home.html" {:paintings (api/do-both-in-parallel(api/read-numbers)) } ))
do-both in parallel does this :
(defn do-both-in-parallel [ids]
(let [paint-thread (future (pmap read-data-painting ids))
image-thread (future (pmap read-image-url ids))]
(pmap merge @paint-thread @image-thread)))
So I can't see anything obviously wrong. I have said this before but using map
for side effects like making an http call like you are doing here is bad practice as it sometimes means that the side effect never happens so we tend to force realisation using something like doall
but if this was the problem you would see no data at all in the response.
oke, I use pmap because I want to work as much as possible with the api calls. Otherwise it takes long to display things. Some 7 seconds
I understand that and it's not the problem you are seeing.
There's some odd behaviour here as what's happening is that the name
function is being returned instead of the value of the name
var bound in your let
. This may be some side effect of all the async threads you are using as as well as pmap
you are using future
but I think you may have found a bug. Either way shadowing a fn's name is bad practice in def
let
or argument vectors so I would just change your symbol used in the let
to painter
or painter-name
as you did.
If you have the entire code base somewhere you can share it, like on github, I can take a longer look sometime but it won't be for a while.
@agile_geek I can put it into github or bitbucket
and it's no problem that it takes a while. I have a working code so I can continue on
Github would be good. Make sure it's the entire codebase incuding all the resources, project.clj etc. i.e. push the root project directory
oke, I did experiment again and when I change :name
to :painter
everything works well
Stick with that for now but push the code you have so I can try it out.
That is strange. I tested your code, and that is work fine at me too. Please share with me what is the problem.. because I work on rest-api too. (like a beginner)
The code can be found here : https://github.com/rwobben/paintings
and the problem is that if I use :name
I see a object as output. When rename it to for example : painter
everything works well
@agile_geek is the link what you need ?
@roelofw that's fine
I see the x y parameter wrong (maybe that is true?) (but I really don’t understand what is the main problem.. I don’t have really big experience)
FYI the #object[clojure.core$name 0x96b47c "clojure.core$name@96b47c"]
is telling you that the thing in the map is clojure.core/name
which is a Clojure function that takes a String, Symbol or Keyword and returns the String representation of it. https://clojuredocs.org/clojure.core/name
@roelofw found it!
(defn read-image-url
"Reads the image-url"
[id]
(let [art-objects (-> (str " " id "/tiles?key=14OGzuak&format=json")
(client/get {:as :json})
:body
:levels
)
url (filter #(= (:name %) "z4") art-objects)
tiles (:tiles (first url))
]
{:id id :name name :tiles tiles}))
You merge the results of read-image-url
with the results of read-data-painting
here:
(defn do-both-in-parallel [ids]
(let [paint-thread (future (pmap read-data-painting ids))
image-thread (future (pmap read-image-url ids))]
(pmap merge @paint-thread @image-thread)))
yes , image-url takes care of the tiles part. read-data takes care of the rest of the output
As the @image-thread maps coming back from read-image-url
is last it's :name
value overwrites any :name
from read-data-painting
so you always get the :name
from the call to read-image-url
look at the way you construct name
in read-image-url
where is the value on name
set?
not that
where do you assign a value to the name
symbol in the let
?
you set art-objects
, url
and tiles
but no name
so when you reference name
when constructing the map returned from read-image-url
you are returning the name
function
But you are referencing a symbol called name
without giving it a value in read-image-url
neither
look at the map returned from read-image-url
here: {:id id :name name :tiles tiles}
you are setting a key :name
with the value from a symbol called name
but you have no value for the symbol name
but there's no name
declared in the let
in read-image-url
do you see?
(let [art-objects (-> (str " " id "/tiles?key=14OGzuak&format=json")
(client/get {:as :json})
:body
:levels
)
url (filter #(= (:name %) "z4") art-objects)
tiles (:tiles (first url))
]
{:id id :name name :tiles tiles})
@agile_geek thanks for the time
next challenge : make a own design inspired by this one : http://wedesignthemes.com/html/redart/default/
first I have to look up how to make a picture frame with css that fits all the paintings
@agile_geek any furthers remarks on the code
@roelofw no problem. This is how we learn
@agile_geek yes, and we learn from our mistakes not from the things that we can do without any problem
@agile_geek now some html and css work to do , to make a nice layout to show all the images
How can I tell selmer that the styles.css is in the resources folder ; {% style "styles.css" %}
also chancing it to {% style "css/styles.css" %}
and putting the css file into resources/css does not make that the css file is found
Selmer is easy. The style tag just makes it easy to link to css. You need to serve your css like normal using ring
#akiroz Was it Elucian Banner perchance? :-)
@dominicm : So I schould so <link rel="stylesheet" type="text/css" href="public/css/styles.css">
@nathansmutz I'm not sure what the underlaying system is called since they styled it to our uni but... might be~ I only found out about the tech stack when the server returned stacktraces in a 500 response xD
@roelofw can you go to localhost:3000/public/css/styles.css ? If not, that's why it's broke
I did not change anything in the code. Just placing things into that directory and try to point to it
maybe I can better find a good book/tutorial about web development with only ring and compojure
I think I already mentioned this one? https://pragprog.com/book/dswdcloj2/web-development-with-clojure-second-edition
@agile_geek do you have a idea why <link rel="stylesheet" type="text/css" href="/css/style.css">
cannot find a css file which resides in resources/public/css directory ?
I have edition 1 but it covers how to build a simple web app with just ring/compojure not sure about edition 2
re: your second question, depends on how your organising your resources and the routes defined in compojure. Can't tell without code and I'm at work in middle of another issue atm
This is my handler file with the routes :
(ns paintings.handler
(:require [compojure.core :refer :all]
[compojure.route :as route]
[ring.middleware.defaults :refer [wrap-defaults site-defaults]]
[paintings.views :as views]
))
(defroutes app-routes
(GET "/" [] views/homepage)
(route/not-found "Not Found"))
(def app
(wrap-defaults app-routes site-defaults))
@roelofw http://safaribooksonline.com/ free in every 14 days 🙂
@roelofw you probably need to add a (route/resources "/")
to your app-routes
that should serve static routes from your resources folder
It's been a while since I did this but it probably needs to go after the GET
but before the not-found
so something like this :
(defroutes app-routes
(GET "/" [] views/homepage)
(route/resources "/")
(route/not-found "Not Found"))
Yep although the indentation is a bit strange in that snippet but that's probably just slack
you probably need to check that the reference in the html is correct too..it's been a while since I did this from scratch and I can't remember what the path to resources is relative too.
find an example somewhere
I think so
I have this template now :
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>The HTML5 Herald</title>
<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">
<link rel="stylesheet" type="text/css" href="/css/styles.css">
<!--[if lt IE 9]>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<h1> ik wordt gek van clojure</h1>
</body>
</html>
I'd get rid of that IE9 script hack unless you really need it to test...its probably not the problem but it's another thing that can go wrong.
I haven't used Selmer for 3 years so I'm not going to be much help
@agile_geek what do you use then
Mostly Reagent and Re-frame to serve single page apps or plain hiccup but I rarely write an app from scratch so this stuff is usually already in place.
@dpsutton Correct I am usually working on something someone else started. Frequently it's a service not a UI as well so it's often just api request/responses
I've written apps from scratch just not for a little while
No I co-organise Clojure eXchange in London which was on at same time
was wondering if we had run into each other by any chance but it sounds like we haven't
Nope but maybe next year? 😀
I'm considering going to a US conference but Strange Loop is top of my list
on luminus when I do this : [paintings2.api_get :as api]))
does it find the file api_get.clj which resides in src ?
I decided to skip Strange Loop this year and go to the Conj instead (I went to Clojure/West and could only do one more conference). Having gone to Strange Loop four times, as well as several past Clojure/West and Clojure/conj events, I think that was the right decision (for me). If you’ve never been to Strange Loop, it’s definitely worth going at least once — it can be pretty inspirational and the talks are often fascinating — but I find I get more value out of /West and /conj these days.
@roelofw You mean in a (:require …)
clause inside (ns …)
?
see here :
(ns paintings2.routes.home
(:require [paintings2.layout :as layout]
[compojure.core :refer [defroutes GET]]
[ring.util.http-response :as response]
[ :as io]
[paintings2.api_get :as api]))
If the (ns …)
inside src/paintings2/api_get.clj
says paintings2.api-get
(which it should), then the :require
should match that.
The rule of thumb is: _
in filenames, -
in namespaces.
The file should be api_get.clj
, the namespace should be api-get
.
but I see this familiar error : Caused by: java.io.FileNotFoundException: Could not locate paintings2/api_get__init.class or paintings2/api_get.clj on classpath.
If your file is called api-get.clj
, that’s wrong.
Files have underscores. Namespaces have hyphens.
Still errors :
java.lang.Exception: namespace 'paintings2.api-get' not found after loading '/paintings2/api_get'
(ns paintings2.routes.home
(:require [paintings2.layout :as layout]
[compojure.core :refer [defroutes GET]]
[ring.util.http-response :as response]
[ :as io]
[paintings2.api-get :as api]))
(defn home-page []
(layout/render
"home.html" "home.html" {:paintings (api/do-both-in-parallel(api/read-numbers)) }))
(defroutes home-routes
(GET "/" [] (home-page)))
the same as this one : https://github.com/rwobben/paintings/blob/master/src/paintings/api_get.clj
now I see this error : ' java.lang.String cannot be cast to clojure.lang.Associative `
the same problem. I have a background-image on resources/public/img and a css file on resources/public/css
@roelofw you need to remove the ..
at the start of the image url
resources are served relative to the resources dir
you may need /public/img/old-wall.jpg
I can't remember
try with and without public
nope, this background: url('/img/old-wall.jpg') no-repeat center center fixed;
is not showing the background
and this is not working also background: url('/public/img/old-wall.jpg') no-repeat center center fixed;
silly question but you do have a file called old-wall.jpg
in the directory resources/public/img/
?
and you have (routes/resources "/")
in the routes def?
Directory of C:\Users\rwobb\Desktop\clojure\paintings2\resources\public\img
05-12-2016 19:45 <DIR> .
05-12-2016 19:45 <DIR> ..
05-12-2016 16:24 69.716 old-wall.jpg
1 File(s) 69.716 bytes
2 Dir(s) 771.299.135.488 bytes free
and this is the routes/home.clj file made by lumunis :
(ns paintings2.routes.home
(:require [paintings2.layout :as layout]
[compojure.core :refer [defroutes GET]]
[ring.util.http-response :as response]
[ :as io]
[paintings2.api-get :as api]))
(defn home-page []
(layout/render
"home.html" {:paintings (api/do-both-in-parallel(api/read-numbers)) }))
(defroutes home-routes
(GET "/" [] (home-page)))
Yes that may be it
I think you don't need public
in the path
even though the img
dir is below public
I see this error message : No such namespace: routes, compiling:(paintings2/routes/home.clj:14:3)
here the whole route file :
(ns paintings2.routes.home
(:require [paintings2.layout :as layout]
[compojure.core :refer [defroutes GET]]
[ring.util.http-response :as response]
[ :as io]
[paintings2.api-get :as api]))
(defn home-page []
(layout/render
"home.html" {:paintings (api/do-both-in-parallel(api/read-numbers)) }))
(defroutes home-routes
(GET "/" [] (home-page))
(routes/resources "/") )
The (routes/resources "/")
is mapping all static resources starting at a path "/" to the default public
folder in resources
my fault
add resoources
to the refer vector in the require for compojure like so: [compojure.core :refer [defroutes GET resources]]
then you can just say (resources "/")
Woops
should be this:
[compojure.route :refer [resources]]
as a new line in the :require
and the compojure.core
line stays as it was
as resources
is defined in compojure.route
not compojure.core
what happened to your not-found
route?
is there another namespace with routes in it where you've already defined not-found
and resources
?
I think I'm confusing you because I can only see a small part of your entire code base
Ah OK
I have never used liminus so I may be steering you wrong but I think that if you need to serve static files like css and images you need resources
route defined and you will need not-found
to handle URLs that don't match a route.
Stop fo ra minute while I explain
In a namespace declaration you can bring in libraries using the :require
keyword as above
there are several patterns for this
you can give a required namespace an alias like this: [compojure.route :as routes]
the :as
will mean I can call a fn in the compojure.route
namespace like this (routes/not-found)
I can prefix any fn in the compojure.route
namespace with routes
and it will find it so I can also say (routes/resources)
Another way to require fn's from a namespace is like this:
[compojure.route :refer [not-found resources]]
this will just require the names fn's
in this case just not-found
and resources
but nothing else in compojure.route
There is another way to do this which is not recommended which is to require all fn's without a namespace alias or listing them:
[compojure.route :refer :all]
So to get both not-found
and resources
which are both in compjure.route
I could do this:
when I use refer , is it right to use not-found like this (not-found)
or do I use (clojure.route/not-found)
?
(ns ....
(:require [compojure.route :as routes])
...
(defroutes app
(routes/resources "/")
(routes/not-found))
(ns ...
(:require [compojure.route :refer [not-found resources])
...
(defroutes app
(resources "/")
(not-found))
I've left out the GET
in the defroutes but you would obviously have that too
Does that make sense?
So you would need the [ ... :refer [...]]
version of require
ns paintings2.routes.home
(:require [paintings2.layout :as layout]
[compojure.core :refer [defroutes GET ]]
[ring.util.http-response :as response]
[ :as io]
[paintings2.api-get :as api]
[compojure.route :refer [resources]]))
(defn home-page []
(layout/render
"home.html" {:paintings (api/do-both-in-parallel(api/read-numbers)) }))
(defroutes home-routes
(GET "/" [] (home-page))
(resources "/") )
OK that looks OK so must be something to do with the path in the html template file
Anyway got to go...good luck
https://github.com/ring-clojure/ring/wiki/Static-Resources may be of some help.