Looking for clojure-csv library example that uses write-csv - clojure

I am looking for a clojure-csv library example that uses write-csv. Specifically, how are the arguments formed? I cannot figure out why I am getting the following error below.
Here is my code example with error:
(def x [1 2 3 4])
(write-csv (spit "test.tmp" x) :end-of-line "\n")
ArityException Wrong number of args (3) passed to:
core$write-csv clojure.lang.AFn.throwArity (AFn.java:437)
Thank You.

EDIT Misread your question and didn't realize you were asking about using the library clojure-csv. Going to leave this up in case it helps anyone else using clojure.data.csv.
If you are using leiningen put the following in your project.clj file.
(defproject so "example"
:dependencies [[org.clojure/clojure "1.3.0"]
[org.clojure/data.csv "0.1.2"]])
Example code of creating a function which takes a filename and the data to write to a csv.
(ns so.core
(:require [clojure.data.csv :as csv]
[clojure.java.io :as io]))
(defn csv [filename data]
(with-open [f (io/writer filename)]
(csv/write-csv f data)))
Using csv from the repl.
so.core> (csv "example.csv" [["stack" 1]
["example" 40]])
And here is what example.csv looks like.
$ cat example.csv
stack,1
example,40
Hopefully this helps out.

Related

Clojure: Could not locate System/IO/File__init.class, System/IO/File.clj or System/IO/File.cljc on classpath

I am trying to run the following code that cuts a .csv file (can be thought of as plaintext) down to 100 lines:
(ns tst.demo.core
(:require [clojure.java.io :as io] [System.IO.File])
(:import [java.io File]))
(defn lines [n filename]
(with-open [rdr (io/reader filename)]
(doall (take n (line-seq rdr)))))
(defn spit-lines [^String filename a-seq]
(->> a-seq
(System.Linq.Enumerable/Cast (type-args System.String))
(System.IO.File/WriteAllLines filename)))
(spit-lines(lines 100 "test_set_batch1.csv")))
Whenever I run this I get the following error:
Syntax error (FileNotFoundException) compiling at (RemoveAfterLine100.clj:1:1).
Could not locate System/IO/File__init.class, System/IO/File.clj or System/IO/File.cljc on classpath.
I'm confused as to what's causing this error. I added System.IO.File to the :requires, so I thought it should work.
As #mange and #Alan Thompson pointed out, my problem is that I was trying to run a script on both CLR and JVM.

How to determine the full file path in which a Clojure namespace is defined?

For example:
(defn show-full-path-of-ns [namespace-symbol]
;; how to do it?
)
(show-full-path-of-ns 'ring.middleware.session)
;; => ~/.m2/repository/ring/ring-core/1.7.1/ring-core-1.7.1.jar!ring/middleware/session.clj
(Yes I know it's possible to split a namespace into more than one files, but we may ignore that.)
This is a partial solution to the problem. It works for jar files in the classpath, but it might give you some idea.
(ns so.find-namespaces
(:require
[clojure.tools.namespace.find :as f]
[clojure.java.classpath :as cp])
(:import
[java.util.jar JarFile]))
(apply hash-map (->> (cp/classpath)
(filter (memfn isFile))
(mapcat #(interleave (f/find-namespaces-in-jarfile (JarFile. %)) (repeat (.getCanonicalPath %))))))
Anyway, if there is a solution it is probably in here

Clojure open a large txt file edit the data and write it to a new file

I'm trying to open a file that is to large to slurp. I want to then edit the file to remove all characters except numbers. Then write the data to a new file.
So far I have
(:require [clojure.java.io :as io])
(:require [clojure.string :as str])
:jvm-opts ["-Xmx2G"]
(with-open [rdr (io/reader "/Myfile.txt")
wrt (io/writer "/Myfile2.txt")]
(doseq [line (line-seq rdr)]
(.write wrt (str line "\n"))))
Which reads and writes but I'm unsure of the best way to go about editing.Any help is much appreciated. I'm very new to the language.
Looks like you just need to modify the line value before writing it. If you want to modify a string to remove all non-numeric characters, a regular expression is a pretty easy route. You could make a function to do this:
(defn numbers-only [s]
(clojure.string/replace s #"[^\d]" ""))
(numbers-only "this is 4 words")
=> "4"
Then use that function in your example:
(str (numbers-only line) "\n")
Alternatively, you could map numbers-only over the output of line-seq, and because both map and line-seq are lazy you'll get the same lazy/on-demand behavior:
(map numbers-only (line-seq rdr))
And then your doseq would stay the same. I would probably opt for this approach as it keeps your "stream" processing together, and your imperative/side-effect loop is only concerned with writing its inputs.

Concatenate two files and redirect output with Clojure using terminal

I'm trying to reach out to the terminal in Clojure to concatenate two binary files together.
So I'm trying to do something like: cat file1 file2 > target
I've started looking at conch but I can't seem to get cat to treat my inputs as file paths rather than strings, e.g.
(def files '["/tmp/file1" "/tmp/file2"])
(defn add-to-target [files target]
(cat {:in files :out (java.io.File. target)}))
(add-to-target files "/tmp/target")
The result written to the /tmp/target file is:
/tmp/file1
/tmp/file2
I'm happy to try other (perhaps more Clojure idiomatic) ways to do this.
Thanks in advance.
Here you go:
(ns user
(:require [clojure.java.io :as io]))
(defn catto [f1 f2 out]
(with-open [o (io/output-stream out)]
(io/copy (io/file f1) o)
(io/copy (io/file f2) o)))
;; in REPL
;; > (catto "station.mov" "super.pdf" "zzz.bin")
Take a look at clojure.java.io docs.

Convert to CSV value to Clojure list

What is the best way to turn this line of CSV for column 3 to a Clojure list?
357302041352401, 2012-08-27 19:59:32 -0700, 100, ["SNIA34", "M33KLC", "M34KLC", "W35REK", "SRBT", "MODE", "BFF21S", "CC12", "RCV56V", "NBA1", "RESP", "A0NTC", "PRNK", "WAYS", "HIRE", "BITE", "INGA1", "M32MOR", "TFT99W", "TBF5P", "NA3NR"]
Assuming you can already read the csv file...
You can use read-string in combination with into
user=> (def your_csv_column "[\"SNIA34\", \"M33KLC\", \"M34KLC\"]")
#'user/your_csv_column
user=> (into '() (read-string your_csv_column))
("M34KLC" "M33KLC" "SNIA34")
You can use Clojure Csv to do that.
You data is interesting, which appears to include a traditional comma-separated line, followed by data in brackets. I could not quite tell if the bracketed data was the representation you had in the .csv file or wanted after reading, but either way, this is how I read a .csv file:
My library's project.clj that uses clojure-csv:
(defproject util "1.0.4-SNAPSHOT"
:description "A general purposes Clojure library"
:dependencies [[org.clojure/clojure "1.4.0"]
[clojure-csv/clojure-csv "1.3.2"]]
:aot [util.core]
:omit-source true)
My library's core.clj header:
(ns util.core
^{:author "Charles M. Norton",
:doc "util is a Clojure utilities directory containing things
most Clojure programs need, like cli routines.
Created on April 4, 2012"}
(:require [clojure.string :as cstr])
(:import java.util.Date)
(:import java.io.File)
(:use clojure-csv.core))
My library's function that returns a .csv file parsed as a vector of vectors.
(defn ret-csv-data
"Returns a lazy sequence generated by parse-csv.
Uses open-file which will return a nil, if
there is an exception in opening fnam.
parse-csv called on non-nil file, and that
data is returned."
[fnam]
(let [ csv-file (open-file fnam)
inter-csv-data (if-not (nil? csv-file)
(parse-csv csv-file)
nil)
csv-data (vec (filter #(and pos? (count %) (not (nil? (rest %))))
inter-csv-data))]
;removes blank sequence at EOF.
(pop csv-data)))
(defn fetch-csv-data
"This function accepts a csv file name, and returns parsed csv data,
or returns nil if file is not present."
[csv-file]
(let [csv-data (ret-csv-data csv-file)]
csv-data))
What I have found to be very helpful is avoid using nth -- very useful advice from SO and other sources -- and given most of my .csv data is from database queries, I zipmap columns to each .csv seqeuence (row), and then operate on that data by map key. It simplifies things for me.