Python Developer • Future Quant • Systems Thinker
# Shopping Cart Program => A simple application that allows users to add items to a virtual shopping cart,
# view the contents of the cart, and calculate the total cost of the items in the cart.
# It can be used as a basic e-commerce application or as a learning exercise for programming concepts such as classes, lists, and user input.
# In this program, we will create a ShoppingCart class that has methods for adding items, removing items, modifying items, viewing the cart, and checking out.
# The program will also include error handling for invalid input and edge cases, such as trying to remove an item that is not in the cart or trying to checkout with an empty cart.
# This program is a fun way to practice using classes, methods, lists, and user input in Python, and it can be expanded with additional features such as saving the cart to a file, applying discounts,
# or integrating with a payment system. The possibilities are endless, so feel free to get creative with your shopping cart program!
# Note: At the time of writing this, the program currently does not include a graphical user interface (GUI), but you can certainly add one if you want to practice using libraries such as Tkinter or PyQt.
# The current implementation is designed to be run in a terminal or command-line interface, and it provides a simple text-based menu for the user to interact with the shopping cart.
# But don't worry, the core functionality of the shopping cart is all there, and you can always enhance it with a GUI later on if you wish to do so.
# The important thing is to understand the underlying programming concepts and how to implement them in Python. Happy coding!
# But one thing is sure, I will make a GUI version in the future after I have completed the entire course, so stay tuned for that if you're interested in learning how to create graphical applications with Python!
# The program will also include a simple text-based menu for the user to interact with the shopping cart, allowing them to choose from options such as adding an item,
# removing an item, viewing the cart, modifying an item, checking out, or quitting the program.
# The program will continue to run until the user chooses to quit, and it will provide feedback on the actions taken, such as confirming when an item is added or
# removed, displaying the contents of the cart, and showing the total cost at checkout.
# The program will also include cutting-edge error handling to ensure that the user cannot enter invalid input, such as trying to add an item with a negative price or
# trying to remove an item that is not in the cart.
# Overall, this shopping cart program is a great way to practice fundamental programming concepts in Python while creating a useful and interactive application.
# By implementing this program, you will gain experience with classes, methods, lists, user input, error handling, and basic program flow control, all of which are essential skills for any Python programmer.
# By completing this project, you will have a functional shopping cart application that you can further enhance and customize as you continue to learn and grow as a Python developer. Happy coding!
# By far the most complex project in this course, so don't worry if it takes some time to understand and implement. Take it step by step, and feel free to ask for help if you get stuck. You've got this!
class ShoppingCart:
def __init__(self):
# Each entry is {"name": , "price": }
self.items = []
def _validate(self, item, price=None):
if not item:
raise ValueError("Item cannot be empty.")
if not item.isalpha():
raise ValueError("Item must contain only letters.")
if price is not None and (not isinstance(price, (int, float)) or price < 0):
raise ValueError("Price must be a non-negative number.")
def add_item(self, item, price=None):
self._validate(item, price)
if not self.items:
print("Your shopping cart is empty. Adding the first item.")
stored_price = float(price) if price is not None else None
self.items.append({"name": item, "price": stored_price})
if stored_price is None:
print(f"Added {item} to the shopping cart.")
else:
print(f"Added {item} (${stored_price:.2f}) to the shopping cart.")
def add_price(self, item, price):
self._validate(item, price)
for entry in self.items:
if entry["name"] == item:
entry["price"] = float(price)
print(f"Added price ${price:.2f} for {item}.")
return
print(f"{item} not found in the shopping cart. Cannot add price.")
def remove_item(self, item):
self._validate(item)
if not self.items:
print("Your shopping cart is empty. No items to remove.")
return
for i, entry in enumerate(self.items):
if entry["name"] == item:
removed = self.items.pop(i)
if removed["price"] is None:
print(f"Removed {removed['name']} from the shopping cart.")
else:
print(
f"Removed {removed['name']} (${removed['price']:.2f}) from the shopping cart."
)
return
print(f"{item} not found in the shopping cart.")
def modify_item(self, item, new_item=None, new_price=None):
self._validate(item)
if new_item is not None:
self._validate(new_item)
if new_price is not None and (
not isinstance(new_price, (int, float)) or new_price < 0
):
raise ValueError("Price must be a non-negative number.")
if not self.items:
print("Your shopping cart is empty. No items to modify.")
return
for entry in self.items:
if entry["name"] == item:
if new_item is None and new_price is None:
print("No changes provided.")
return
original_name = entry["name"]
original_price = entry["price"]
if new_item is not None:
entry["name"] = new_item
if new_price is not None:
entry["price"] = float(new_price)
old_price_text = (
"Not specified" if original_price is None else f"${original_price:.2f}"
)
new_price_text = (
"Not specified"
if entry["price"] is None
else f"${entry['price']:.2f}"
)
print(
f"Modified item: {original_name} ({old_price_text}) -> "
f"{entry['name']} ({new_price_text})"
)
return
print(f"{item} not found in the shopping cart.")
def __str__(self):
if not self.items:
return "Your shopping cart is empty."
lines = ["Shopping Cart:"]
total = 0.0
for entry in self.items:
if entry["price"] is None:
lines.append(f"- {entry['name']} (Price: Not specified)")
else:
lines.append(f"- {entry['name']}: ${entry['price']:.2f}")
total += entry["price"]
lines.append(f"Total (priced items): ${total:.2f}")
return "\n".join(lines)
def view_cart(self):
print(self)
def checkout(self):
if not self.items:
print("Your shopping cart is empty. Nothing to checkout.")
return
total = sum(entry["price"] for entry in self.items if entry["price"] is not None)
unpriced_items = [entry["name"] for entry in self.items if entry["price"] is None]
print("\nCheckout Summary:")
print(self)
if unpriced_items:
print(
f"Note: {len(unpriced_items)} item(s) have no price and were not included in the total."
)
print(f"Amount due: ${total:.2f}")
while True:
confirm = prompt_input("Complete purchase? (yes/no): ", allow_blank=True)
if confirm is None:
return
confirm = confirm.lower()
if confirm in {"yes", "y"}:
self.items.clear()
print("Checkout complete. Thank you for your purchase!")
return
if confirm in {"no", "n", ""}:
print("Checkout cancelled.")
return
print("Please enter yes, no, or 'esc'.")
def prompt_input(message, allow_blank=False):
while True:
raw = input(message).strip()
if raw.lower() == "esc":
print("Returning to main menu.")
return None
if allow_blank or raw:
return raw
print("Error: Input cannot be empty.")
def prompt_action(action, message):
while True:
raw = prompt_input(message)
if raw is None:
return False
try:
action(raw.title())
return True
except ValueError as e:
print(f"Error: {e}")
# User interaction
cart = ShoppingCart()
while True:
print("\n1. Add item")
print("2. Remove item")
print("3. View cart")
print("4. Modify item")
print("5. Checkout")
print("6. Quit")
choice = prompt_input("Choose an option: ", allow_blank=True)
if choice is None:
print("You are already at the main menu.")
continue
if choice == "1":
item_input = prompt_input("Enter an item to add: ")
if item_input is None:
continue
price = None
cancelled = False
while True:
price_input = prompt_input(
"Enter the price for the item (press Enter to skip): ", allow_blank=True
)
if price_input is None:
cancelled = True
break
if not price_input:
break
try:
price = float(price_input)
if price < 0:
raise ValueError
break
except ValueError:
print("Invalid price. Price must be a non-negative number.")
if cancelled:
continue
try:
cart.add_item(item_input.title(), price)
except ValueError as e:
print(f"Error: {e}")
elif choice == "2":
prompt_action(cart.remove_item, "Enter an item to remove: ")
elif choice == "3":
cart.view_cart()
elif choice == "4":
target_item = prompt_input("Enter the item to modify: ")
if target_item is None:
continue
new_name_input = prompt_input(
"Enter the new item name (press Enter to keep current): ", allow_blank=True
)
if new_name_input is None:
continue
cancelled = False
new_price = None
while True:
new_price_input = prompt_input(
"Enter the new price (press Enter to keep current): ", allow_blank=True
)
if new_price_input is None:
cancelled = True
break
if not new_price_input:
break
try:
new_price = float(new_price_input)
if new_price < 0:
raise ValueError
break
except ValueError:
print("Invalid price. Price must be a non-negative number.")
if cancelled:
continue
try:
new_name = new_name_input.title() if new_name_input else None
cart.modify_item(target_item.title(), new_name, new_price)
except ValueError as e:
print(f"Error: {e}")
elif choice == "5":
cart.checkout()
elif choice == "6":
print("Goodbye!")
break
else:
print("Invalid option. Please choose 1-6. Type 'esc' to cancel a prompt.")
# By Kairos