c06f5908c1aac61e6773b531f4c5d4e3053349c2
commit c06f5908c1aac61e6773b531f4c5d4e3053349c2
Author: Simon Watson <spw01@protonmail.com>
Date: Fri Jul 16 20:58:09 2021 -0400

Initial Commit

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..690529d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+records.txt
diff --git a/fin-lisp.lisp b/fin-lisp.lisp
new file mode 100644
index 0000000..87fad93
--- /dev/null
+++ b/fin-lisp.lisp
@@ -0,0 +1,76 @@
+(ql:quickload "cl-store")
+
+;;;; Reimplementation of my bills tracker in Lisp
+(defun reload ()
+ (load "/Users/swatson/Repos/lisp-files/fin-lisp/fin-lisp.lisp"))
+
+;;; All records exist in this data structure
+;;; nil on start and loaded in from file
+;;; *records* represents as hash of months,
+;;; where the key is the month stamp, eg 20210701
+;;; and the value is the monthly expenses hash
+(defvar *records* (make-hash-table :test 'equalp))
+
+;; Called like: (add-month '202107)
+(defun add-month (month-key)
+ (setf (gethash month-key *records*) (make-hash-table :test 'equalp))
+ month-key)
+
+;;; Taken from practical common lisp
+(defun prompt-read (prompt)
+ (format *query-io* "~a: " prompt)
+ (force-output *query-io*)
+ (read-line *query-io*))
+
+(defun prompt-for-expense ()
+ (list
+ (prompt-read "Enter expense name")
+ (parse-integer
+ (prompt-read "Enter expense value"))))
+
+(defun add-expense-to-month (month)
+ (if (gethash month *records*)
+ (let ((innerhash (gethash month *records*))
+ (exp-l (prompt-for-expense)))
+ (format t "Expense name is: ~a" (first exp-l))
+ (terpri)
+ (format t "Expense value is: ~a"(second exp-l))
+ (terpri)
+ (setf (gethash (first exp-l) innerhash) (second exp-l)))
+ ;;NIL))
+ (add-expense-to-month (add-month month))))
+
+;;; Given key for *records* hash,
+;;; print expenses/values for month
+(defun dump-month (month-key)
+ (format t "~a~C" month-key #\linefeed)
+ (let ((month-hash)
+ (exp-keys))
+ (setf month-hash (gethash month-key *records*))
+ (setf exp-keys (loop for key being the hash-keys of month-hash collect key))
+ (dolist (exp-key exp-keys)
+ (format t "~a : ~a~C" exp-key (gethash exp-key month-hash) #\linefeed))))
+
+;;; Dump all records.
+;;; This will also be used for data serialization at some point
+(defun dump-records ()
+ (let ((record-key-list (loop for key being the hash-keys of *records* collect key)))
+ (dolist (month-key record-key-list) (dump-month month-key))))
+
+(defun serialize-records (filename)
+ (cl-store:store *records* filename))
+
+(defun deserialize-records (filename)
+ ;(setf *records* (cl-store:restore (pathname filename))))
+ (setf *records* (cl-store:restore filename)))
+
+;; Entry point
+(defun main ()
+ (format t "Available options:")(terpri)
+ (format t "1. Enter expense")(terpri)
+ (format t "2. Display month")(terpri)
+ (format t "3. Write records")(terpri)
+ (let
+ ((answer (prompt-read "Select an option")))
+ answer))
+