#Coffee Machine in OOP code
#Define the Moneymachine class first to process the money and currency received
class MoneyMachine:
CURRENCY = "$"
#write the coin values in a dictionary
COIN_VALUES = {
"quarters" : 0.25,
"dimes" : 0.1,
"nickles" : 0.05,
"pennies" : 0.01
}
#we write functions using init function to initialize
def __init__(self):
self.profit = 0
self.money_received = 0
def report(self):
#Prints the report of the current profit
print(f"Money: {self.CURRENCY}{self.profit}")
def process_coins(self):
#Returns the value of the total calculated coins inserted
print("Please insert coins.")
for coin in self.COIN_VALUES:
self.money_received = int(input(f"How many {coins}? ")) * self.COIN_VALUES[coin]
return self.money_received
#define the payment function
def make_payment(self,cost):
self.process_coins()
if self.money_received >= cost:
change = round(self.money_received - cost, 2)
print(f"Here is your {self.CURRENCY}{change} in change.")
self.profit = cost
self.money_received = 0
return True
#if payment is not enough, return False
else:
print("Sorry that's not enough money. Money refunded.")
self.money_received = 0
return False
#Next we define the Menu class and Menu items. We can model it using classes
class menuItem:
#put in all the ingredient variables and the cost ofcourse
def __init__(self, name, water, milk, coffee, cost):
self.name = name
self.cost = cost
self.ingredients = {
"water" : water,
"milk" : milk,
"coffee": coffee
}
#full menu with costs for different coffees
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 items
print("Sorry that item is not available")
#After this we make the CoffeeMaker class to process the coffee
class CoffeeMaker:
#models the coffee Machine
def __init__(self):
self.resources = {
"water" : 300,
"milk" : 200,
"coffee": 100,
}
def report(self):
#prints out the report of the 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.resouces[item] -= order.ingredients[item]
print(f"Here's your {order.name}. Enjoy!")
#----------------------------------------------------------------------Python Part-----------------------------------------------------------------------#
money_machine = MoneyMachine()
coffee_maker = CoffeeMaker()
is_on = True
coffee_maker.report()
money_machine.report()
while is_on:
options = menu.get_items()
choice = input(f"What would you like? ({options}): ")
if choice == "off":
is_on = False
elif choice == "report":
coffee_maker.report()
money_machine.report()
else:
drink = menu.find_drink(choice)
if coffee_maker.is_resource_sufficient(drink) and money_machine.make_payment(drink.cost):
coffee_maker.make_coffee(drink)
Now it runs all fine during the course but whenever I run it, I get this error:
Traceback (most recent call last):
File "c:\Users\Armand S\Desktop\Python Files\D16 Coffee Machine in OOP.py", line 123, in <module>
options = menu.get_items()
TypeError: get_items() missing 1 required positional argument: 'self'
I have no idea what this error is and in need of help. Any suggestions? I've looked for alot of solutions but I'm just confused as to why the functions in my while loop need more positional arguments (since I'm not using the def function? idk) so yeah I'm asking that. And if there are any more suggestions to make my code better then that would be appreciated.
CodePudding user response:
You have to create an object of the main
class first to access the get_items()
method
Try the following -
menuObj = menu()
options = menuObj.get_items()
...
...
...
# Update the object name in the else as well
else:
drink = menuObj.find_drink(choice)
N.B: There are other issues in your code as well like spelling mistakes on variable names. One of them is you wrote 'coin' in the for loop but while printing you wrote 'coins'. Then there are 'menuItem' and 'MenuItem'. Do fix them as well.
CodePudding user response:
You cannot directly call the get_items() method without creating an instance ( menu=menu()
) of the menu class, as it's not a classmethod.
CodePudding user response:
The mistake behind this error is that you haven't defined an instance menu = Menu() (class names should begin with capital letter as per best practices) so I have changed it! There are other variable mistakes in your code as well. However I have modified your code! Here is your code after modifications:
class MoneyMachine:
CURRENCY = "$"
#write the coin values in a dictionary
COIN_VALUES = {
"quarters" : 0.25,
"dimes" : 0.1,
"nickles" : 0.05,
"pennies" : 0.01
}
#we write functions using init function to initialize
def __init__(self):
self.profit = 0
self.money_received = 0
def report(self):
#Prints the report of the current profit
print(f"Money: {self.CURRENCY}{self.profit}")
def process_coins(self):
#Returns the value of the total calculated 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
#define the payment function
def make_payment(self,cost):
self.process_coins()
if self.money_received >= cost:
change = round(self.money_received - cost, 2)
print(f"Here is your {self.CURRENCY}{change} in change.")
self.profit = cost
self.money_received = 0
return True
#if payment is not enough, return False
else:
print("Sorry that's not enough money. Money refunded.")
self.money_received = 0
return False
class MenuItem:
#put in all the ingredient variables and the cost ofcourse
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")
class CoffeeMaker:
#models the coffee Machine
def __init__(self):
self.resources = {
"water" : 300,
"milk" : 200,
"coffee": 100,
}
def report(self):
#prints out the report of the 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's your {order.name}. Enjoy!")
money_machine = MoneyMachine()
coffee_maker = CoffeeMaker()
is_on = True
coffee_maker.report()
money_machine.report()
menu = Menu()
while is_on:
options = menu.get_items()
choice = input(f"What would you like? ({options}): ")
if choice == "off":
is_on = False
elif choice == "report":
coffee_maker.report()
money_machine.report()
else:
drink = menu.find_drink(choice)
if coffee_maker.is_resource_sufficient(drink) and money_machine.make_payment(drink.cost):
coffee_maker.make_coffee(drink)