For a given custom-formatter, parse refuses certain month values.
(require '[clj-time.core :as t]
'[clj-time.format :as f])
(let [custom-formatter (f/formatter "dd MMM yyyy")]
(f/parse custom-formatter "27 mar 2010")
(f/parse custom-formatter "27 dec 2010"))
The first parsereturns the expected result, #object[org.joda.time.DateTime 0x62a9d176 "2010-03-27T00:00:00.000Z"], while the second returns Actual: java.lang.IllegalArgumentException: Invalid format: "27 dec 2010" is malformed at "dec 2010".
I can't make sense of this behavior. What can possibly causes this issue?
Thanks for help.
update
Here's my project.cljfile
:dependencies [[org.clojure/clojure "1.7.0"]
[twitter-api "0.7.8"]
[cheshire "5.6.1"]
[clojure-csv/clojure-csv "2.0.1"]
[org.postgresql/postgresql "9.4-1206-jdbc42"]
[com.jolbox/bonecp "0.8.0.RELEASE"]
[org.clojure/java.jdbc "0.6.1"]
[java-jdbc/dsl "0.1.0"]
[org.slf4j/slf4j-nop "1.7.21"]
[clj-time "0.11.0"]
]
You likely need to specify a Locale for your formatter. You can check to see your default Locale with:
user=> (java.util.Locale/getDefault)
#object[java.util.Locale 0x4713d9a5 "en_US"]
See the results for different locales (including the error you are seeing):
user=> (require '[clj-time.core :as t]
#_=> '[clj-time.format :as f])
nil
user=> (let [custom-formatter (f/with-locale
(f/formatter "dd MMM yyyy")
java.util.Locale/ENGLISH)]
(f/parse custom-formatter "27 mar 2010"))
#object[org.joda.time.DateTime 0x3cfceae6 "2010-03-27T00:00:00.000Z"]
user=> (let [custom-formatter (f/with-locale
(f/formatter "dd MMM yyyy")
java.util.Locale/ITALY)]
(f/parse custom-formatter "27 mar 2010"))
#object[org.joda.time.DateTime 0x4f5e9955 "2010-03-27T00:00:00.000Z"]
user=> (let [custom-formatter (f/with-locale
(f/formatter "dd MMM yyyy")
java.util.Locale/CHINA)]
(f/parse custom-formatter "27 mar 2010"))
IllegalArgumentException Invalid format: "27 mar 2010" is malformed at "mar 2010" org.joda.time.format.DateTimeFormatter.parseDateTime (DateTimeFormatter.java:899)
Related
I'm really new to clojure and I'm trying to select values from the database. It does select the values(I think) though it only returns nil
I tried following the tutorial in https://www.tutorialspoint.com/clojure/clojure_databases.htm
Here is my code
(ns hello.core_test)
(:require [clojure.java.jdbc :as sql]))
(def mysql-db {
:subprotocol "mysql"
:subname "//localhost:3307/blink"
:user "root"
:password ""})
(println (sql/query mysql-db
["select firstName from users"]
:row-fn :firstName))
And it returns
(nil nil nil nil nil nil nil nil nil)
(The database contains 9 variables)
Here is the picture of my column
Edited. Apparantly if I remove the
:row-fn :firstName
And replace it with
:row :firstName
It returns in a format like this
({:firstname Angel} {:firstname Austin} {:firstname enrico} {:firstname wilzen} {:firstname keith} {:firstname Joshua} {:firstname Ron Andre} {:firstname Allen Jay} {:firstname Ivan})
clojure.java.jdbc converts columns by default like that (-> column-name clojure.string/lower-case keyword), you already partially answered it by yourself showing result without :row-fn.
Right now, using [org.clojure/java.jdbc "0.7.7"] this works for me:
(sql/query mysql-db ["select firstName from users"] {:row-fn :firstname})
if you don't want auto conversion:
(sql/query mysql-db ["select firstName from users"] {:identifiers identity :keywordize? false})
;; => ({"firstName" "one"} {"firstName" "two"} {"firstName" "three"})
Now can use compojure this way:
(GET ["/uri"] [para1 para2]
)
Para1 and para2 are all of type String.
I would like to let it know the type correcttly,like this:
(GET ["/uri"] [^String para1 ^Integer para2]
)
It can convert para1 to be Sting and para2 to Integer.
Is there some library or good way to do this?
This is possible as of Compojure 1.4.0 using the syntax [x :<< as-int]
This is not currently possible with only Compojure.
You could use Prismatic schema coercion.
(require '[schema.core :as s])
(require '[schema.coerce :as c])
(require '[compojure.core :refer :all])
(require '[ring.middleware.params :as rparams])
(def data {:para1 s/Str :para2 s/Int s/Any s/Any})
(def data-coercer (c/coercer data c/string-coercion-matcher ))
(def get-uri
(GET "/uri" r
(let [{:keys [para1 para2]} (data-coercer (:params r))]
(pr-str {:k1 para1 :k2 (inc para2)}))))
(def get-uri-wrapped
(let [keywordizer (fn [h]
(fn [r]
(h (update-in r [:params] #(clojure.walk/keywordize-keys %)))))]
(-> get-uri keywordizer rparams/wrap-params)))
Here is a sample run:
(get-uri-wrapped {:uri "/uri" :query-string "para1=a¶2=3" :request-method :get})
{:status 200,
:headers {"Content-Type" "text/html; charset=utf-8"},
:body "{:k1 \"a\", :k2 4}"}
I have created a project using lein command.
This is my source file:
(ns database.core)
(defn movies[na rent qty]
(spit "e.txt" (.toString [{:na na :rent rent :qty qty}]))
(read-string (slurp "e.txt")))
This is my project file:
(ns database.core-test
(:require [clojure.test :refer :all]
[database.core :refer :all]))
(deftest movies-test
testing "movies"
(let [jun (movies "Dark-knight" 12 6)]
(is (= (get-in jun [0 :na]) "Dark-knight"))
(is (= (get-in jun [0 :rent]) 12))
(is (= (get-in jun [0 :qty]) 6))))
But when I try to run it i keep getting this error.
clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Can't take value of a macro: #'clojure.test/testing, compiling:(C:\Users\A\database\test\database\core_test.clj:5:1)
What could be the possible reasons for this error?
testing macro must be enclosed in its own pair of parentheses so that it was invoked
(deftest movies-test
(testing "movies"
(let [jun (movies "Dark-knight" 12 6)]
(is (= (get-in jun [0 :na]) "Dark-knight"))
(is (= (get-in jun [0 :rent]) 12))
(is (= (get-in jun [0 :qty]) 6)))))
This works as expected:
java -jar clojure-1.4.0.jar -e "(do (require 'clojure.repl) (.setDynamic #'clojure.repl/print-doc) (with-bindings {#'clojure.repl/print-doc str} (eval '(clojure.repl/doc println))))"
Output:
"{:ns #<Namespace clojure.core>, :name println, :arglists ([& more]), :added \"1.0\", :static true, :doc \"Same as print followed by (newline)\", :line 3325, :file \"clojure/core.clj\"}"
But the same does not work in the REPL:
java -jar clojure-1.4.0.jar -e "(do (require 'clojure.repl) (.setDynamic #'clojure.repl/print-doc) (clojure.main/repl :init (fn [] {#'clojure.repl/print-doc str}))))"
Output of (doc println):
user=> (doc println)
-------------------------
clojure.core/println
([& more])
Same as print followed by (newline)
nil
user=>
I don't know what I'm doing wrong.
Found the answer after diving into the counterclockwise and nrepl code:
java -jar clojure-1.4.0.jar -e "(do (require 'clojure.repl) (.setDynamic #'clojure.repl/print-doc) (with-bindings {#'clojure.repl/print-doc str} (clojure.main/repl)))))"
The output is the same as above:
"{:ns #<Namespace clojure.core>, :name println, :arglists ([& more]), :added \"1.0\", :static true, :doc \"Same as print followed by (newline)\", :line 3325, :file \"clojure/core.clj\"}"
The trick is to use with-bindings before calling repl:
(with-bindings {#'clojure.repl/print-doc str}
(repl))
I'd appreciate suggestions/insights on how I can leverage Clojure to efficiently parse and compare two files. There are two (log) files that contain employee attendance; from these files I need to determine all the days that two employees worked the same times, in the same department. Below are examples of the log files.
Note: each file has differing number of entries.
First File:
Employee Id Name Time In Time Out Dept.
mce0518 Jon 2011-01-01 06:00 2011-01-01 14:00 ER
mce0518 Jon 2011-01-02 06:00 2011-01-01 14:00 ER
mce0518 Jon 2011-01-04 06:00 2011-01-01 13:00 ICU
mce0518 Jon 2011-01-05 06:00 2011-01-01 13:00 ICU
mce0518 Jon 2011-01-05 17:00 2011-01-01 23:00 ER
Second File:
Employee Id Name Time In Time Out Dept.
pdm1705 Jane 2011-01-01 06:00 2011-01-01 14:00 ER
pdm1705 Jane 2011-01-02 06:00 2011-01-01 14:00 ER
pdm1705 Jane 2011-01-05 06:00 2011-01-01 13:00 ER
pdm1705 Jane 2011-01-05 17:00 2011-01-01 23:00 ER
if you are not going to do it periodically,
(defn data-seq [f]
(with-open [rdr (java.io.BufferedReader.
(java.io.FileReader. f))]
(let [s (rest (line-seq rdr))]
(doall (map seq (map #(.split % "\\s+") s))))))
(defn same-time? [a b]
(let [a (drop 2 a)
b (drop 2 b)]
(= a b)))
(let [f1 (data-seq "f1.txt")
f2 (data-seq "f2.txt")]
(reduce (fn[h v]
(let [f2 (filter #(same-time? v %) f2)]
(if (empty? f2)
h
(conj h [(first v) (map first f2)])))) [] f1)
)
will get you,
[["mce0518" ("pdm1705")] ["mce0518" ("pdm1705")] ["mce0518" ("pdm1705")]]
I came to somewhat shorter and (IMHO) more readable version
(use ; moar toolz - moar fun
'[clojure.contrib.duck-streams :only (reader)]
'[clojure.string :only (split)]
'[clojure.contrib.str-utils :only (str-join)]
'[clojure.set :only (intersection)])
(defn read-presence [filename]
(with-open [rdr (reader filename)] ; file will be securely (always) closed after use
(apply hash-set ; make employee's hash-set
(map #(str-join "--" (drop 2 (split % #" [ ]+"))) ; right-to-left: split row by spaces then forget two first columns then join using "--"
(drop 1 ; ommit first line
(line-seq rdr)))))) ; read file content line-by-line
(intersection (read-presence "a.in") (read-presence "b.in")) ; now it's simple!
;result: #{"2011-01-01 06:00--2011-01-01 14:00--ER" "2011-01-02 06:00--2011-01-01 14:00--ER" "2011-01-05 17:00--2011-01-01 23:00--ER"}
Assuming a.in and b.in are your files. I also assumed you'll have one hash-set for each employee -- (naive) generalization to N employees would need next six lines:
(def employees ["greg.txt" "allison.txt" "robert.txt" "eric.txt" "james.txt" "lisa.txt"])
(for [a employees b employees :when (and
(= a (first (sort [a b]))) ; thou shall compare greg with james ONCE
(not (= a b)))] ; thou shall not compare greg with greg
(str-join " -- " ; well, it's not pretty... nor pink at least
[a b (intersection (read-presence a) (read-presence b))]))
;result: ("a.in -- b.in -- #{\"2011-01-01 06:00--2011-01-01 14:00--ER\" \"2011-01-02 06:00--2011-01-01 14:00--ER\" \"2011-01-05 17:00--2011-01-01 23:00--ER\"}")
Actually this loop is sooo ugly and it doesn't memorize intermediate results... To be improved.
--edit--
I knew there must be something elegant in core or contrib!
(use '[clojure.contrib.combinatorics :only (combinations)])
(def employees ["greg.txt" "allison.txt" "robert.txt" "eric.txt" "james.txt" "lisa.txt"])
(def employee-map (apply conj (for [e employees] {e (read-presence e)})))
(map (fn [[a b]] [a b (intersection (employee-map a) (employee-map b))])
(combinations employees 2))
;result: (["a.in" "b.in" #{"2011-01-01 06:00--2011-01-01 14:00--ER" "2011-01-02 06:00--2011-01-01 14:00--ER" "2011-01-05 17:00--2011-01-01 23:00--ER"}])
Now it's memorized (parsed data in employee-map), general and... lazy :D