Holy moly, what a struggle learning is. I have spent a good seven days on this tweak on the last python challenge, a coffee machine. I have spent countless broken hours trying to work out how to do Object Oriented Programming. Now I would explain to you what this all means but I think this is a far better explanation than me saying it is about imagining you have an item with attributes and methods in order to tell the computer how to control that item.
If Mosh can't get you to understand then I am sure you will know what the blind leading the blind means for you if I guide you what OOP. boop!
Covfefe
Lots of this to help me get my head in order. Although I am not so sure it is a healthy way to zoom into action. Instant coffee though as I am too lazy to make espresso. Maybe if I can be fucked with setting up my 3D printer I would have made a machine to get it all automate. Then I would be a fat fuck sitting in front of my computer, no cellar though so I think I will pass on that thought.
from menu import Menu, MenuItem
from coffee_maker import CoffeeMaker
from money_machine import MoneyMachine
turn_off = False
money = MoneyMachine()
drinks = Menu()
coffee = CoffeeMaker()
while not turn_off:
selection = input("What would you like? (espresso/latte/cappuccino): ")
# choice = drinks.find_drink(selection)
if selection == 'report':
coffee.report()
money.report()
elif selection == 'off':
turn_off = True
else:
make = coffee.is_resource_sufficient(drinks.find_drink(selection))
if make:
if money.make_payment(drinks.find_drink(selection).cost):
coffee.make_coffee(drinks.find_drink(selection))
Now this is the main.py to control the class's being called to run the machine!
The Menu
"""Models each Menu Item."""
def __init__(self, name, water, milk, coffee, cost):
self.name = name
self.cost = cost
self.ingredients = {
"water": water,
"milk": milk,
"coffee": coffee
}
class Menu:
"""Models the Menu with drinks."""
def __init__(self):
self.menu = [
MenuItem(name="latte", water=200, milk=150, coffee=24, cost=2.5),
MenuItem(name="espresso", water=50, milk=0, coffee=18, cost=1.5),
MenuItem(name="cappuccino", water=250, milk=50, coffee=24, cost=3),
]
def get_items(self):
"""Returns all the names of the available menu items"""
options = ""
for item in self.menu:
options += f"{item.name}/"
return options
def find_drink(self, order_name):
"""Searches the menu for a particular drink by name. Returns that item if it exists, otherwise returns None"""
for item in self.menu:
if item.name == order_name:
return item
print("Sorry that item is not available.")
This file holds the attributes with some methods within the menu class. See Mosh's vid link above if you are not sure. Failing that then lets all just be detecting bugs together with your code.
The money handler
class MoneyMachine:
CURRENCY = "$"
COIN_VALUES = {
"quarters": 0.25,
"dimes": 0.10,
"nickles": 0.05,
"pennies": 0.01
}
def __init__(self):
self.profit = 0
self.money_received = 0
def report(self):
"""Prints the current profit"""
print(f"Money: {self.CURRENCY}{self.profit}")
def process_coins(self):
"""Returns the total calculated from coins inserted."""
print("Please insert coins.")
for coin in self.COIN_VALUES:
self.money_received += int(input(f"How many {coin}?: ")) * self.COIN_VALUES[coin]
return self.money_received
def make_payment(self, cost):
"""Returns True when payment is accepted, or False if insufficient."""
self.process_coins()
if self.money_received >= cost:
change = round(self.money_received - cost, 2)
print(f"Here is {self.CURRENCY}{change} in change.")
self.profit += cost
self.money_received = 0
return True
else:
print("Sorry that's not enough money. Money refunded.")
self.money_received = 0
return False
This is the file that handles coin transactions. It's in US format for the coins as per my last code post. You will notice I had the functions in that one contained in a file as opposed to making them into functions/methods in a class. Again see Mosh's vid above if unsure.
Lets make covfefe
class CoffeeMaker:
"""Models the machine that makes the coffee"""
def __init__(self):
self.resources = {
"water": 300,
"milk": 200,
"coffee": 100,
}
def report(self):
"""Prints a report of all resources."""
print(f"Water: {self.resources['water']}ml")
print(f"Milk: {self.resources['milk']}ml")
print(f"Coffee: {self.resources['coffee']}g")
def is_resource_sufficient(self, drink):
"""Returns True when order can be made, False if ingredients are insufficient."""
can_make = True
for item in drink.ingredients:
if drink.ingredients[item] > self.resources[item]:
print(f"Sorry there is not enough {item}.")
can_make = False
return can_make
def make_coffee(self, order):
"""Deducts the required ingredients from the resources."""
for item in order.ingredients:
self.resources[item] -= order.ingredients[item]
print(f"Here is your {order.name} ☕️. Enjoy!")
The final stage of the OOP challenge. The making of the coffee in the machine. I had problems when I was running the code because I had the object called inside the while loop, which made my changes in the attributes go back to their original format each iteration of the orders. I fixed it. With lots of hair pulling. I better sweep around my computer cos I am going to go bald if I don't stop or failed to debug the issue.
Man this coding exercise is starting to jell, with a lot of trial and errors. I think I re watched the instructions from the course about 8 times. I would highly recommend this course if you do want to learn python: https://www.udemy.com/course/100-days-of-code/.
No sponsorship to plug the challenge, just have found this one very good. It's probably Angela Yu. She does have a nice voice and is not bad to look at each time the day ends. LOL
COVFEFE
Thanks for getting this far.