#|
Author: [Your Name]
E-mail: [Your PSU Email]@psu.edu
Course: CMPSC 460
Assignment: Lisp Programming Project
Due date: 4/6/2026
File: FoodOrderGenerator.LISP
Purpose: This program uses random-number generation to create food orders
from lists of different categories of food items. It also allows the
user to add food items to or remove food items from the lists
initially provided. The program loops until the user decides that
s/he is done creating food orders.
IDE/Compiler:
LispWorks 8.0.1 Personal Edition
Operating system:
MS Windows 10
References: Web sites listed on our course Programming Language Resources page
Lisp interactive sessions and demo functions posted on our course
Demo Programs page
AI Tool(s): Claude (Anthropic) was used to generate this source code.
AI-generated code specific to this assignment - all functions below.
|#
; -------------------------------------------------------------------
; Function to display the main menu of options
(defun display-main-menu ()
(format t "~%MENU OPTIONS:~%")
(format t "1) Generate a food order~%")
(format t "2) Add a food item~%")
(format t "3) Remove a food item~%")
(format t "4) Quit~%")
)
; -------------------------------------------------------------------
; Function to display the submenu of food item categories
(defun display-sub-menu ()
(format t "~%FOOD ITEM TYPES:~%")
(format t "1) Sandwich~%")
(format t "2) Side~%")
(format t "3) Beverage~%")
(format t "4) Dessert~%")
)
; -------------------------------------------------------------------
; Function to display all four food item lists
(defun display-all-lists (sandwiches sides beverages desserts)
(format t "~%Current food items lists:~%")
(format t "Sandwiches: ~a~%" sandwiches)
(format t "Sides : ~a~%" sides)
(format t "Beverages : ~a~%" beverages)
(format t "Desserts : ~a~%" desserts)
)
; -------------------------------------------------------------------
; Function to obtain a validated menu choice in range [1, 4]
(defun get-menu-choice ()
(format t "Please enter your choice: ")
(finish-output)
(let ((choice (read)))
(if (and (integerp choice) (>= choice 1) (<= choice 4))
choice
(progn
(format t "Invalid choice! Please re-enter.~%")
(get-menu-choice)
)
)
)
)
; -------------------------------------------------------------------
; Function to pick a random element from a list
(defun random-element (lst)
(nth (random (length lst)) lst)
)
; -------------------------------------------------------------------
; Function to generate a random food order from each list
; Selects one item at random from each list and builds the order
(defun generate-food-order (sandwiches sides beverages desserts)
(let* ((sandwich (random-element sandwiches))
(side (random-element sides))
(beverage (random-element beverages))
(dessert (random-element desserts))
(order (append (list sandwich) (list side) (list beverage) (list dessert))))
(format t "~%Random food order:~%")
(format t " ~a, ~a, ~a, ~a~%" sandwich side beverage dessert)
order
)
)
; -------------------------------------------------------------------
; Function to add a food item to a list if it is not already present
; Returns the (possibly updated) list
(defun add-food-item (lst item)
(if (member item lst)
lst
(append lst (list item))
)
)
; -------------------------------------------------------------------
; Function to remove a food item from a list
; Does nothing (no error) if the list is empty or the item is not found
; Returns the (possibly updated) list
(defun remove-food-item (lst item)
(if (or (null lst) (not (member item lst)))
lst
(remove item lst)
)
)
; -------------------------------------------------------------------
; Function to handle the "add a food item" workflow
; Displays lists, shows submenu, reads category and new item, returns updated lists
(defun handle-add (sandwiches sides beverages desserts)
(display-all-lists sandwiches sides beverages desserts)
(display-sub-menu)
(let ((cat (get-menu-choice)))
(format t "Please enter your food item: ")
(finish-output)
(let ((new-item (read)))
(cond
((= cat 1)
(let ((updated (add-food-item sandwiches new-item)))
(format t "Sandwiches: ~a~%" updated)
(list updated sides beverages desserts)
))
((= cat 2)
(let ((updated (add-food-item sides new-item)))
(format t "Sides : ~a~%" updated)
(list sandwiches updated beverages desserts)
))
((= cat 3)
(let ((updated (add-food-item beverages new-item)))
(format t "Beverages : ~a~%" updated)
(list sandwiches sides updated desserts)
))
((= cat 4)
(let ((updated (add-food-item desserts new-item)))
(format t "Desserts : ~a~%" updated)
(list sandwiches sides beverages updated)
))
)
)
)
)
; -------------------------------------------------------------------
; Function to handle the "remove a food item" workflow
; Displays lists, shows submenu, reads category and item, returns updated lists
(defun handle-remove (sandwiches sides beverages desserts)
(display-all-lists sandwiches sides beverages desserts)
(display-sub-menu)
(let ((cat (get-menu-choice)))
(format t "Please enter your food item: ")
(finish-output)
(let ((del-item (read)))
(cond
((= cat 1)
(let ((updated (remove-food-item sandwiches del-item)))
(format t "Sandwiches: ~a~%" updated)
(list updated sides beverages desserts)
))
((= cat 2)
(let ((updated (remove-food-item sides del-item)))
(format t "Sides : ~a~%" updated)
(list sandwiches updated beverages desserts)
))
((= cat 3)
(let ((updated (remove-food-item beverages del-item)))
(format t "Beverages : ~a~%" updated)
(list sandwiches sides updated desserts)
))
((= cat 4)
(let ((updated (remove-food-item desserts del-item)))
(format t "Desserts : ~a~%" updated)
(list sandwiches sides beverages updated)
))
)
)
)
)
; -------------------------------------------------------------------
; Helper function that performs one iteration of the main loop
; Returns NIL when the user chooses to quit, otherwise recurses with updated lists
(defun main-loop (sandwiches sides beverages desserts)
(display-main-menu)
(let ((choice (get-menu-choice)))
(cond
; Option 1: Generate a random food order
((= choice 1)
(generate-food-order sandwiches sides beverages desserts)
(main-loop sandwiches sides beverages desserts)
)
; Option 2: Add a food item
((= choice 2)
(let ((updated-lists (handle-add sandwiches sides beverages desserts)))
(main-loop (first updated-lists)
(second updated-lists)
(third updated-lists)
(fourth updated-lists))
)
)
; Option 3: Remove a food item
((= choice 3)
(let ((updated-lists (handle-remove sandwiches sides beverages desserts)))
(main-loop (first updated-lists)
(second updated-lists)
(third updated-lists)
(fourth updated-lists))
)
)
; Option 4: Quit
((= choice 4)
(format t "~%\"Thank you for using my Food Order Generator!\"~%")
)
)
)
)
; -------------------------------------------------------------------
; Main "driver" function - initializes the four food lists and starts the loop
(defun loop-program ()
(let ((sandwiches '(blt tuna-salad grilled-cheese hamburger cheesesteak))
(sides '(tossed-salad pasta-salad fries onion-rings chips))
(beverages '(lemonade iced-tea water soda coffee))
(desserts '(ice-cream cake pie brownie cookies)))
(main-loop sandwiches sides beverages desserts)
)
)