5
\$\begingroup\$

This is my first project using Python OOP. I don't know whether the code I have written is correctly or not. How can I make this code feasible?

Machine.py

Class containing some default values

class Machine:
dict_coffee = {
                'Cappuccino' : 100,
                'Cafe Latte' : 200,
                'Espresso' : 300
            }
quantity = [2,2,2]
power_status = False

Coffee_Operator.py

Operator class

Here operator can

  1. add coffee
  2. modify price
  3. modify quantity (add/remove)
  4. turn the power on, so that the user can buy coffee
  5. power off

from Machine import Machine
class CoffeeOperator(Machine):

def __init__(self):
    Machine.dict_coffee
    Machine.quantity
    if Machine.power_status == False:
        self.power_on()
    while Machine.power_status == True:
        print('=====================================')
        print('Welcome Operator')
        choice = int(input('1. Add new coffee\n2. Modify Price\n3. Modify Quantity\n4. Power On for the user\n5. Power Off\n'))
        if choice == 1:
            self.add_coffee()
        elif choice == 2:
            self.modify_price()
        elif choice == 3:
            self.modify_quantity()
        elif choice == 4:
            self.power_on()
            from Coffee_Buyer import Coffee
            Machine.power_status = False
        elif choice == 5:
            self.power_off()
        else:
            print('Invalid Input') 

def power_on(self):
    Machine.power_status = True

def power_off(self):
    Machine.power_status = False
    return Machine.power_status

def print_values(self):
    print('=====================================')
    print('List of Coffee: ')
    print('Coffee | Cost | Quantity')

    key_lst = list(Machine.dict_coffee)

    value = Machine.dict_coffee.values()
    value_lst = list(value)

    for i in range(len(key_lst)):
        print('{} | {} | {} '.format(key_lst[i],value_lst[i],Machine.quantity[i]))


def add_coffee(self):
    name= input('New coffee name: ')
    price = int(input('New coffee price: '))
    quantity = int(input('New coffee Quality: '))
    Machine.dict_coffee.update({name:price})
    Machine.quantity.append(quantity)
    self.print_values()

def modify_price(self):
    name = input('Enter name of coffee: ')
    if name in Machine.dict_coffee:
        update_price = int(input('Updated price: '))
        Machine.dict_coffee[name] = update_price
        print('Cost of {} is Rs{}'.format(name,update_price))
    else:
        print('Invalid coffee name')

def modify_quantity(self):
    print('Available quantity:')
    key_lst = list(Machine.dict_coffee)
    for i in range(len(key_lst)):
        print('Quantity of {} is {}'.format(key_lst[i],Machine.quantity[i]))
    name = input('Enter name of coffee: ')
    if name in Machine.dict_coffee:
        add_remove = int(input('1.Add more\n2.Remove existing\n'))
        change_quantity = int(input('Update quantity: '))
        name_lst = list(Machine.dict_coffee)
        index_name = name_lst.index(name)
        if add_remove == 1:
            Machine.quantity[index_name] += change_quantity
            self.print_values()
        elif add_remove == 2:
            if Machine.quantity[index_name] >= change_quantity:
                Machine.quantity[index_name] -= change_quantity
                self.print_values()
            else:
                print('You have exceed the quantity')



def get_dict(self):
    return Machine.dict_coffee
def get_quantity(self):
    return Machine.quantity
def get_power(self):
    return Machine.power_status

if __name__ == "__main__":
     opr = CoffeeOperator()

Coffee_Buyer.py

Buyer class

User can buy the coffee. If the quantity of coffee is zero then that coffee is removed from the list.

import os
import time
from Coffee_Operator import CoffeeOperator

class Coffee(CoffeeOperator):
def __init__(self):
    dict_coffee = CoffeeOperator.get_dict(CoffeeOperator)
    quantity = CoffeeOperator.get_quantity(CoffeeOperator)
    power_status = CoffeeOperator.get_power(CoffeeOperator)

    self.power_status = True       
    print('Welcome User')
    while self.power_status == True:
        self.display(len(self.quantity))
        if self.quantity == [0] or len(self.quantity) == 0:
            print("No Coffee. Turning off")
            self.power_status = False
            break
        else:
            user_input = int(input('Your choice: ')) - 1
            if 0 <= user_input < len(self.quantity):
                if self.available(user_input) == True:
                    print('Coffee is getting ready, Please pay the cost')
                self.coffee_cost(user_input)
            else:
                os.system('cls' if os.name == 'nt' else 'clear')
                print('Invalid input. There is no coffee at option {}'.format(user_input+1))

def available(self,user_input):
    if self.quantity[user_input] > 0:
        self.quantity[user_input] -= 1
        return True


def display(self,length):
    for i in [0]:
        try:
            x = self.quantity.index(i)
            self.quantity.pop(x)
            keys_list = list(self.dict_coffee)
            del_x = keys_list[x]
            self.dict_coffee.pop(del_x)
        except ValueError: 
            pass
    for key,value in self.dict_coffee.items():
        print('{} at Rs {}'.format(key,value))

def coffee_cost(self,user_input):
    value = self.dict_coffee.values()
    cost_lst = list(value)
    cost = cost_lst[user_input]       
    jack=True
    while jack:
        cost_input = int(input('Coffee cost: '))
        if cost_input != cost:
            print('Please enter perfect amount of Rs{}'.format(cost))
            jack = True
        else:
            print('Please collect your coffee')
            time.sleep(2)
            os.system('cls' if os.name == 'nt' else 'clear')
            jack = False


os.system('cls' if os.name == 'nt' else 'clear')
c = Coffee()
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Could you please elaborate on the statement:

[...] code I have written is correctly [...]

It is pretty undifferentiated; I'm just going to assume that you want your code simply reviewed and know how to make it "better".

Styling

First of all, according to PEP8 (Python Style Guide), you need to leave two blank lines after your module imports to seperate imports from any other code.

Your indentation also looks off: I assume you just didn't paste the code correctly because I'm pretty sure that Python would give you an error for it in return. The PEP8 recommended indentation space count is 4.

The class styling of CoffeeOperator and Coffee also differs. CoffeeOperator has 1 blank line after its header definition and Coffee has no blank line. Make sure your preferred code styling is always the same in your project to prevent spaghetti code from happening.

The if statements in the __init__ of CoffeeOperator also seem a bit distracting. They could maybe be put into a separate method in the class. I personally use the __init__ dunder method for attribute initialization and the general basic class setup.

Another thing to mention is that you mention the bool name (True / False) in several if statements, it is good practice to rather just write:

if true_condition: do_something()
if not true_condition: do_something()

The == True is redundant, as well as the == False. Consider using not condition for checking for a False boolean value and just the boolean variable without the == True for checking for a True boolean value.

Also, in CoffeeOperator.power_off() you return Machine.power_status but in the contrary function CoffeeOperator.power_on() you don't return anything. Maybe I'm just understanding it wrong but it looks a bit weird.

Despite that in the CoffeeOperator.__init__() you import something when choosing option 4, this is bad practice. It'll re-import the module every time you choose the option 4. It should only be imported once; consider importing it nonetheless, always.

The parameter styling should always be (parameterA, parameterB, parameterC), remember putting a space in-between for readability purposes.

The method styling should have at least 1 blank space below a method definition.

Last but not least remember to put more separating blank lines in-between your code, but make it a reasonable separation, contextualized.

PS: You should probably make a if __name__ == "__main__:" in file Coffee_Buyer.py.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.