;; Code to run a vending machine ;; Kathi Fisler ;; September 26, 2004 ;; NOTE: Run in ADVANCED language level ;; Modified by Glynis Hamel ;; We want to write functions to implement a vending machine. ;; Soda costs 50 cents, and candy costs 65 cents. We need ;; one function for depositing money and one for people to select items ;; insert-coin takes in money and remembers the amount currently in the machine ;; choose item consumes 'soda or 'candy and produces "more money" or "give item" ;;;;;;;zeroth version;;;;;;;;;;;;;;;;;;;; (define soda-cost 50) (define candy-cost 65) ;; amt : number ;; stores the current amount in the vending machine (define amt 0) ;; insert-coin : number -> void ;; consumes number of cents and adds it to amt ;; EFFECT: increases amt (define (insert-coin coin) (set! amt (+ amt coin))) ;; choose-item : symbol -> string ;; consumes item that user wants and produces status message (define (choose-item item) (cond [(symbol=? item 'soda) (cond [(>= amt soda-cost) "give item"] [else "more money"])] [(symbol=? item 'candy) (cond [(>= amt candy-cost) "give item"] [else "more money"])])) ;;--------------> Demonstrate in interactions window ;; (choose-item 'soda) ;; "more money" ;; (insert-coin 25) ;; (choose-item 'soda) ;; "more money" ;; (insert-coin 25) ;; (choose-item 'soda) ;; "give item" ;; Happy with vending machine? ;; With the same 50 cents, I can get as many sodas as I want ;; Should tell you how much money you need when you select an item ;; Two cond cases could be a helper function ;;;;;;;first version - tell how much more money is needed ;;;;;;;;;;;;;;;;;;;; #| (define soda-cost 50) (define candy-cost 65) ;; amt : number ;; stores the current amount in the vending machine (define amt 0) ;; insert-coin : number -> void ;; consumes number of cents and adds it to amt ;; EFFECT: increases amt (define (insert-coin coin) (set! amt (+ amt coin))) ;; choose-item : symbol -> string ;; consumes item that user wants and produces status message (define (choose-item item) (cond [(symbol=? item 'soda) (cond [(< amt soda-cost) (format "You are short ~a cents" (- soda-cost amt))] [(>= amt soda-cost) (format "give soda and ~a cents change" (- amt soda-cost))])] [(symbol=? item 'candy) (cond [(< amt candy-cost) (format "You are short ~a cents" (- candy-cost amt))] [(>= amt candy-cost) (format "give candy and ~a cents change" (- amt candy-cost))])])) |# ;;;; second version -- introduce helper for choose-item ;;;;;;;;;;;; #| (define soda-cost 50) (define candy-cost 65) ;; amt : number ;; stores the current amount in the vending machine (define amt 0) ;; insert-coin : number -> void ;; consumes number of cents and adds it to amt ;; EFFECT: increases amt (define (insert-coin coin) (set! amt (+ amt coin))) ;; choose-item : symbol -> string ;; consumes item that user wants and produces status message (define (choose-item item) (cond [(symbol=? item 'soda) (dispense 'soda soda-cost)] [(symbol=? item 'candy) (dispense 'candy candy-cost)])) ;; dispense : symbol number -> string ;; consumes selected item and its cost and produces a status message (define (dispense item item-cost) (cond [(< amt item-cost) (format "You are short ~a cents" (- item-cost amt))] [(>= amt item-cost) (format "give ~a and ~a cents change" item (- amt item-cost))])) |# #| ;;;; third version -- have dispense reset amt if an item has been dispensed;;;;; (define soda-cost 50) (define candy-cost 65) ;; amt : number ;; stores the current amount in the vending machine (define amt 0) ;; insert-coin : number -> void ;; consumes number of cents and adds it to amt ;; EFFECT: increases amt (define (insert-coin coin) (set! amt (+ amt coin))) ;; choose-item : symbol -> string ;; consumes item that user wants and produces status message (define (choose-item item) (cond [(symbol=? item 'soda) (dispense 'soda soda-cost)] [(symbol=? item 'candy) (dispense 'candy candy-cost)])) ;; dispense : symbol number -> string ;; consumes selected item and its cost and produces a status message ;; EFFECT : resets amt to 0 (define (dispense item item-cost) (cond [(< amt item-cost) (format "You are short ~a cents" (- item-cost amt))] [(>= amt item-cost) (local [(define change (- amt item-cost))] (begin (set! amt 0) (format "give ~a and ~a cents change" item change)))])) |# #| This example introduces some new Racket operators and constructs: - format : string data ... data -> string creates string by dropping the data into the ~a in the string - begin : wraps around any number of Scheme expressions. Runs them in order and produces result of last one. Only useful if non-last expressions are set! or print commands (which we haven't covered yet). In this example, we needed begin so that we could reset the amt and still produce the string result from dispense. - local : allows you to give names to the results of intermediate computations. Any valid define can go into the local (and you can have as many definitions as you want in a local). Cannot be used to redefine an existing defined name. In this example, we needed local to save the old value of amount (in order to compute the change owed) before we reset it to 0. |#