diff --git a/otus-06/src/otus_06/homework.clj b/otus-06/src/otus_06/homework.clj index d5d5228..53dbd9f 100644 --- a/otus-06/src/otus_06/homework.clj +++ b/otus-06/src/otus_06/homework.clj @@ -1,4 +1,6 @@ -(ns otus-06.homework) +(ns otus-06.homework + (:require [clojure.java.io :as io] + [clojure.string :as string])) ;; Загрузить данные из трех файлов на диске. ;; Эти данные сформируют вашу базу данных о продажах. @@ -94,3 +96,113 @@ ;; Файлы находятся в папке otus-06/resources/homework +(defn- split-line [line] + (string/split line #"\|")) + +(defn- fmt-line [line] + (-> line + split-line + rest + vec)) +(def ^:private tables {:customer "resources/homework/cust.txt" + :product "resources/homework/prod.txt" + :sales "resources/homework/sales.txt"}) +(defn- print-table [fmt-fn name] + (with-open [rdr (io/reader (tables name))] + (doseq [lines (line-seq rdr)] + (println (fmt-fn lines))))) + +(defn- table-value [table-key id & [value-col id-col]] + (with-open [rdr (io/reader (tables table-key))] + (loop [lines (line-seq rdr)] + (let [line-vec (split-line (first lines))] + (cond (= (line-vec (or id-col 0)) id) (line-vec value-col) + (empty? (rest lines)) nil + :else (recur (rest lines))))))) + +(defn- fmt-sales-line [line] + (let [line-vec (fmt-line line) + [customer-id product-id count] line-vec] + (vector (table-value :customer customer-id 1) + (table-value :product product-id 1) + count))) + +(defn- get-product-price [id] + (let [price-col 2] + (parse-double (table-value :product id price-col)))) + +(defn- get-total-product-price [[_ product-id product-count-str]] + (let [product-count (Integer/parseInt product-count-str)] + (* (get-product-price product-id) + product-count))) + +(defn- get-total-product-count [[_ _ product-count]] + (Integer/parseInt product-count)) + +(defn- print-total [name table-key get-total-value] + (let [fomat-str {:customer "%s: %.2f" + :product "%s: %d"} + sales-columns {:customer 0 + :product 1} + id (table-value table-key name 0 1)] + (with-open [rdr (io/reader (tables :sales))] + (loop [lines (line-seq rdr) + total 0] + (if (empty? lines) + (println (format (fomat-str table-key) name total)) + (let [line (fmt-line (first lines)) + line-id (line (sales-columns table-key)) + total-product (get-total-value line) + rest-lines (rest lines)] + (recur rest-lines (if (= id line-id) + (+ total total-product) + total)))))))) + +(defn- print-menu [] + (println " +*** Sales Menu *** +------------------ +1. Display Customer Table +2. Display Product Table +3. Display Sales Table +4. Total Sales for Customer +5. Total Count for Product +6. Exit + +Enter an option? +")) + +(defn- make-action [input] + (cond (= input "1") (do (print-table fmt-line :customer) + true) + (= input "2") (do (print-table fmt-line :product) + true) + (= input "3") (do (print-table fmt-sales-line :sales) + true) + (= input "4") (do (println "Input customer name:") + (print-total (read-line) :customer get-total-product-price) + true) + (= input "5") (do (println "Input product name:") + (print-total (read-line) :product get-total-product-count) + true) + (= input "6") nil + :else true)) + +(defn -main [] + (print-menu) + (loop [num (read-line)] + (and (make-action num) + (do (print-menu) + (recur (read-line)))))) + +(comment + (table-value :product "3" 2) + (table-value :customer "Sue Jones" 0 1) + (table-value :customer "3" 1) + (print-table fmt-line :product) + (print-table fmt-line :customer) + (print-table fmt-line :sales) + (print-total "Sue Jones" :customer get-total-product-price) + (print-total "shoess" :product get-total-product-count) + (-main) + ())