Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions clojure/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.DS_Store
.idea
*.log
tmp/

/target
/classes
/checkouts
profiles.clj
pom.xml
pom.xml.asc
*.jar
*.class
/.lein-*
/.nrepl-port
/.prepl-port
/.cpcache

/.log
/.clj-kondo/.cache
8 changes: 8 additions & 0 deletions clojure/deps.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.11.1"}}

:aliases
{:run {:main-opts ["-m" "task-list.core"]}
:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.82.1306"}}
:extra-paths ["test"]
:main-opts ["-m" "kaocha.runner"]}}}
21 changes: 21 additions & 0 deletions clojure/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Clojure

## Usage

Clojure is best used through the REPL, but there are some CLI entry points.

Dependencies will be installed when you start the application or repl. You can
download Clojure [here](https://clojure.org/guides/install_clojure).

To run the application

``` sh
clj -M:run
```

To run the tests

``` sh
clj -M:test
```

95 changes: 95 additions & 0 deletions clojure/src/task_list/core.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
(ns task-list.core
(:require
[clojure.string :as str]))

(defn create-task-list []
{})

(def ^:dynamic *id-seq* (atom (range)))

(defn next-id []
(swap! *id-seq* rest)
(first @*id-seq*))

(defn create-task [description]
{:id (next-id)
:description description})


(defn add-task [task-list project description]
(let [task (create-task description)]
(if (get task-list project)
(assoc task-list project (conj (get task-list project) task))
(println (str "Could not find a project with the name " project ".")))))

(defn add-project [task-list project-name]
(assoc task-list project-name []))

(defn add [task-list command-line]
(let [[subcommand args] (str/split command-line #" " 2)]
(if (= subcommand "project")
(add-project task-list args)
(when (= subcommand "task")
(let [[project description] (str/split args #" " 2)]
(add-task task-list project description))))))

(defn show [task-list]
(doseq [[project tasks] task-list]
(println project)
(doseq [task tasks]
(println (str " [" (if (:done task) "x" " ") "] " (:id task) ": " (:description task))))
(println "")))

(defn set-done [task-list id value]
(let [proj-name (atom nil)
idx (atom nil)]
(loop [tasks (into [] task-list)]
(let [[project project-tasks] (first tasks)]
(doall (map-indexed (fn [i task]
(when (= id (:id task))
(reset! proj-name project)
(reset! idx i)))
project-tasks))

(if @proj-name
(update-in task-list [@proj-name @idx :done] (fn [_] value))
(if (not (empty? (rest tasks)))
(recur (rest tasks))
(do
(println (str "Could not find a task with an ID of " id))
task-list)))))))

(defn check [task-list id]
(set-done task-list id true))

(defn uncheck [task-list id]
(set-done task-list id false))

(defn error [command-line]
(println (str "I don't know what the command " command-line "is.")))

(defn execute [task-list command-line]
(let [[command args] (str/split command-line #" " 2)]
(case command
"show" (do (show task-list)
task-list)
"add" (add task-list args)
"check" (check task-list (Integer/parseInt args))
"uncheck" (uncheck task-list (Integer/parseInt args))
"help" (println "Commands:
show
add project <project name>
add task <project name> <task description>
check <task ID>
uncheck <task ID>")
"quit" (System/exit 0)
(do (error command-line)
task-list))))

(defn -main []
(binding [*id-seq* (atom (range))]
(loop [task-list (create-task-list)]
(print "> ")
(flush)
(let [input (read-line)]
(recur (execute task-list input))))))
Empty file.
48 changes: 48 additions & 0 deletions clojure/test/task_list/core_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
(ns task-list.core-test
(:require
[clojure.test :refer [deftest is]]
[task-list.core :as sut]))

(deftest application-test
(binding [sut/*id-seq* (atom (range))]
(let [output (with-out-str
(-> (sut/create-task-list)
(sut/execute "show")
(sut/execute "add project secrets")
(sut/execute "add task secrets Eat more donuts.")
(sut/execute "add task secrets Destroy all humans.")
(sut/execute "show")



(sut/execute "add project training")
(sut/execute "add task training Four Elements of Simple Design")
(sut/execute "add task training SOLID")
(sut/execute "add task training Coupling and Cohesion")
(sut/execute "add task training Primitive Obsession")
(sut/execute "add task training Outside-In TDD")
(sut/execute "add task training Interaction-Driven Design")

(sut/execute "check 1")
(sut/execute "check 3")
(sut/execute "check 5")
(sut/execute "check 6")
(sut/execute "show")))]
(is (= "secrets
[ ] 1: Eat more donuts.
[ ] 2: Destroy all humans.

secrets
[x] 1: Eat more donuts.
[ ] 2: Destroy all humans.

training
[x] 3: Four Elements of Simple Design
[ ] 4: SOLID
[x] 5: Coupling and Cohesion
[x] 6: Primitive Obsession
[ ] 7: Outside-In TDD
[ ] 8: Interaction-Driven Design

"
output)))))