timotheosh

tip calculator

Dec 25th, 2015
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 2.85 KB | None | 0 0
  1. ;;;; Solution 1
  2.  
  3. ;;;; Utility functions
  4. (defun parse-float (string)
  5.   "Return a float read from string, and the index to the remainder of string."
  6.   (multiple-value-bind (integer i)
  7.       (parse-integer string :junk-allowed t)
  8.     (if (= (length string) i)
  9.         (values integer i)
  10.         (multiple-value-bind (fraction j)
  11.             (parse-integer string :start (+ i 1) :junk-allowed t)
  12.           (if (null fraction)
  13.               (values integer i)
  14.               (values (float (+ integer (/ fraction (expt 10 (- j i 1))))) j))))))
  15.  
  16. (defun prompt-read (prompt)
  17.   (format *query-io* "~&~a: " prompt)
  18.   (force-output *query-io*)
  19.   (read-line *query-io*))
  20.  
  21. (defun enter-bill-amount ()
  22.   "Enter the bill amount."
  23.   (let ((bill-amount nil))
  24.     (loop
  25.        (if (or (null bill-amount) (minusp bill-amount))
  26.            (progn
  27.              (setf bill-amount (parse-float (prompt-read "Enter bill amount")))
  28.              (when (or (not bill-amount) (and bill-amount (< bill-amount 0)))
  29.                (format t "That is not a valid amount! Digits only (no negative numbers), please.~%")))
  30.            (return)))
  31.     (setf bill-amount (read-from-string (format nil "~$" bill-amount)))))
  32.  
  33. (defun enter-tip-rate-old ()
  34.   "Enter tip rate."
  35.   (let ((tip-rate nil))
  36.     (loop
  37.        (if (or (null tip-rate) (minusp tip-rate))
  38.            (let ((d (prompt-read "Enter the tip rate (without the %, default is 15)")))
  39.              (when (zerop (length (string-trim #(#\space #\tab) d)))
  40.                  (setf tip-rate 15)
  41.                  (return))
  42.              (setf d (parse-float d))
  43.              (if (not d)
  44.                  (format t "That is not a valid amount! Digits only, please.~%")
  45.                  (progn
  46.                    (setf tip-rate d)
  47.                    (return))))))
  48.     (/ tip-rate 100.0)))
  49.  
  50. (defun enter-tip-rate ()
  51.   "Enter tip rate."
  52.   (loop
  53.      :with tip-rate := nil
  54.      :while (or (null tip-rate) (minusp tip-rate))
  55.      :do (let ((line (prompt-read "Enter the tip rate (without the %, default is 15)")))
  56.            (when (zerop (length (string-trim #(#\space #\tab) line)))
  57.              (setf tip-rate 15)
  58.              (loop-finish))
  59.            (setf tip-rate (parse-float line))
  60.            (when tip-rate
  61.              (loop-finish))
  62.            (format t "That is not a valid amount! Digits only, please.~%"))
  63.      :finally (return (/ tip-rate 100.0))))
  64.  
  65. (defun tip-amount (bill tip-rate)
  66.   "Return the tip amount. The bill and tip-rate should be floats. The
  67. tip-rate is a percentage, already divided by 100."
  68.   (parse-float (format nil "~,2F" (* bill tip-rate))))
  69.  
  70. (defun tip-calculator ()
  71.   (let* ((bill (enter-bill-amount))
  72.          (tip-rate (enter-tip-rate))
  73.          (tip (tip-amount bill tip-rate)))
  74.     (format t "The tip is ~,2F~%" tip)
  75.     (format t "The total is ~,2F" (+ bill (* bill tip-rate)))))
  76.  
  77. (tip-calculator)
Add Comment
Please, Sign In to add comment