Home > OS >  Currently doing a python udemy course, involving making a coffee machine using objects and class, I&
Currently doing a python udemy course, involving making a coffee machine using objects and class, I&

Time:06-29

#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)
  • Related