Home > front end >  Making changes in objects permanent
Making changes in objects permanent

Time:10-25

I'm trying to create a bar program, It's based on user inputs, classes and inheritance. This is my current code for the part not having to do with user input.

class Bar:
    def __init__(self, name, stock = []) -> None:
        self.name = name
        self.stock = stock
    
    def fill_stock(self):
        pass
    
    def reduce_stock(self, name):
        if name == 'Whiskey Sour':
            whiskey.stock -= 5
            citrus_juice.stock -= 3
            sugar_syrup.stock  = 2
        
        elif name == 'Negroni':
            campari.stock -= 2
            gin.stock -= 2
            sweet_Vermouth.stock -= 2

        elif name == 'Dry Martini':
            gin.stock -= 5
            dry_vermouth.stock -= 1

    def randomize_stock(self):
        pass

#Mainclass Item
class Item:
    #All items have a name, and an amount in stock
    def __init__(self, name, stock) -> None:
        self.stock = stock
        self.name = name
    
    def __str__(self) -> str:
        return f''

#Subclass Liquor (For all alcoholic liquids)
class Liquor(Item):
    #List of the objects name found in the class
    instances = []

    #Every liquor has a name, how much stock is left, brand, cl_price, percentage of alcohol
    def __init__(self, name, stock, brand, cl_price, percentage) -> None:
        super().__init__(name, stock)
        self.cl_price = cl_price
        self.percentage = percentage
        self.brand = brand

        #Adds all instances of the class to a list
        self.__class__.instances.append(name)
#Returns the names of the instances found in the class
def liquor_list():
    return '\n'.join(Liquor.instances)


#Subclass Mixer (for all non-alcoholic liquids)
class Mixer(Item):
    #Every mixer has a name, how much stock is left, cl_price
    def __init__(self, name, stock, brand, cl_price) -> None:
        super().__init__(name, stock)
        self.brand = brand
        self.cl_price = cl_price

#Subclass Garnish (for all garnishes)
class Garnish(Item):
    #Every garnish has a name, and how much stock left
    def __init__(self, name, stock) -> None:
        super().__init__(name, stock)

#Liquor Creation
vodka = Liquor('Vodka', 79, 'Absolut', '35 kr', '37.5%')
mezcal = Liquor('Mezcal', 56, 'Corte Vetusto', '55 kr', '45%')
whiskey = Liquor('Ardbeg', 94, 'Ardbeg', '50 kr', '46%',)
rum = Liquor('Rum', 109, 'Havana Club', '25 kr', '37.5%')
baileys = Liquor('Baileys', 43, 'Baileys', '20 kr', '17%')
gin = Liquor('Gin', 89, 'Beefeater', '40 kr', '40%')
campari = Liquor('Campari', 97, 'Campari', '20 kr', '20%')
sweet_vermouth = Liquor('Sweet Vermouth', 146, 'Martini Rosso', '20kr', '15%')
dry_vermouth = Liquor('Dry Vermouth', 43, 'Noileprat', '45kr', '17%')

#Mixer Creation
tonic = Mixer('Tonic', 1889, 'SweTnc', '5 kr')
sugar_syrup = Mixer('Sugar Syrup', 2000, 'Simple', None)
citrus_juice = Mixer('Citrus_Juice', 3000, 'ICA', None)

However now when I run i.e reduce_stock it changes the value but then kind off just throws it away. Like there is no permanent change, whenever you run the programm again it goes back to being what it used to be.

class Bar:
def __init__(self, name) -> None:
    self.name = name

def fill_stock(self, name):
    pass

def reduce_stock(self):
    pass

def randomize_stock(self):
    pass

def create_stock(self, name, stock, brand, cl_price, percentage):
    name = Inventory(name, stock, brand, cl_price, percentage)

def remove_stock(self):
    pass

class Inventory:
    def __init__(self, name, stock, brand, cl_price, percentage) -> None:
        self.stock = stock
        self.name = name
        self.brand = brand
        self.cl_price = cl_price
        self.percentage = percentage

I'm also trying to restructure the code to make it a bit more readable, but having issues with create_stock as it seems to want a value for self meaning you have to input 6 values instead of the wanted 5.

CodePudding user response:

I have a bit of a re-design for you. I like what you were trying to do with your Liquor class adding all instances to a class list. But having a dictionary where the key is the name of the liquor and the value the actual instance would allow you to look up liquors by name.

But why stop there with just liquors. Have a dictionary of all items whether they be liquor, mixer, garnish or whatever.

Also, method Bar.reduce_stock has a complicated if else testing what drink is being made. This class thus needs to know every possible drink there is and how to make it. This is not good object-oriented design. What is needed is a Drink class and a subclass for each possible drink that defines the reduce_stock method. The Drink class itself provides a lookup of drinks by name. Thus the Bar.reduce_stock method becomes a simple lookup call to get the correct drink and then delegates to that instance. Until the other methods of Bar are defined, it really is not serving a very useful function; one can simply lookup a drink by name and directly call its reduce_stock method without using the Bar class at all.

I also don't know what the Inventory class is for since each item is maintaining these values as attributes. For the time being I have dropped this class and just want to show how the "inventory" gets updated.

#Mainclass Item
class Item:
    items = {}

    #All items have a name, and an amount in stock
    def __init__(self, name, stock) -> None:
        self.stock = stock
        self.name = name
        # Add item to class dictionary:
        self.items[name] = self

    def __str__(self) -> str:
        return f'Name: {self.name}, Stock: {self.stock}'

    @classmethod
    def get(cls, name):
        return cls.items[name]

    @classmethod
    def all_items(cls):
        return '\n'.join(str(v) for v in cls.items.values())

#Subclass Liquor (For all alcoholic liquids)
class Liquor(Item):
    #Every liquor has a name, how much stock is left, brand, cl_price, percentage of alcohol
    def __init__(self, name, stock, brand, cl_price, percentage) -> None:
        super().__init__(name, stock)
        self.cl_price = cl_price
        self.percentage = percentage
        self.brand = brand

    def __str__(self):
        s = super().__str__()
        return s   f', Brand: {self.brand}, Price: {self.cl_price}, Percentage: {self.percentage}'

#Subclass Mixer (for all non-alcoholic liquids)
class Mixer(Item):
    #Every mixer has a name, how much stock is left, cl_price
    def __init__(self, name, stock, brand, cl_price) -> None:
        super().__init__(name, stock)
        self.brand = brand
        self.cl_price = cl_price

    def __str__(self):
        s = super().__str__()
        return s   f', Brand: {self.brand}, Price: {self.cl_price}'

#Subclass Garnish (for all garnishes)
class Garnish(Item):
    #Every garnish has a name, and how much stock left
    def __init__(self, name, stock) -> None:
        super().__init__(name, stock)

class Drink:
    drinks = {}

    def __init__(self, name):
        self.name = name
        self.drinks[name] = self

    def reduce_stock(self):
        raise Exception('This method must be overriden.')

    @classmethod
    def get(cls, name):
        return cls.drinks[name]


class WhiskeySour(Drink):
    def __init__(self):
        super().__init__('Whiskey Sour')

    def reduce_stock(self):
        whiskey = Item.get('Scotch') # Bourbon or Rye, please!
        whiskey.stock -= 5
        citrus_juice = Item.get('Citrus_Juice')
        citrus_juice.stock -= 3
        sugar_syrup = Item.get('Sugar Syrup')
        sugar_syrup.stock -= 2 # Should be -=

WhiskeySour()

class Negroni(Drink):
    def __init__(self):
        super().__init__('Negroni')

    def reduce_stock(self):
        campari = Item.get('Campari')
        campari.stock -= 2
        gin = Item.get('Gin')
        gin.stock -= 2
        sweet_vermouth = Item.get('Sweet Vermouth')
        sweet_vermouth.stock -= 2

Negroni()

class DryMartini(Drink):
    def __init__(self):
        super().__init__('Martini')

    def reduce_stock(self):
        gin = Item.get('Gin')
        gin.stock -= 5
        dry_vermouth = Item.get('Dry Vermouth')
        dry_vermouth.stock -= 1

DryMartini()

class Bar:
    def fill_stock(self):
        pass

    # This could be a static or class method:
    def reduce_stock(self, name):
        drink = Drink.get(name)
        drink.reduce_stock()

    def randomize_stock(self):
        pass

    def create_stock(self, name, stock, brand, cl_price, percentage):
        pass

    def remove_stock(self):
        pass

#Liquor Creation
Liquor('Vodka', 79, 'Absolut', '35 kr', '37.5%')
Liquor('Mezcal', 56, 'Corte Vetusto', '55 kr', '45%')
Liquor('Scotch', 94, 'Ardbeg', '50 kr', '46%',)
Liquor('Rum', 109, 'Havana Club', '25 kr', '37.5%')
Liquor('Baileys', 43, 'Baileys', '20 kr', '17%')
Liquor('Gin', 89, 'Beefeater', '40 kr', '40%')
Liquor('Campari', 97, 'Campari', '20 kr', '20%')
Liquor('Sweet Vermouth', 146, 'Martini Rosso', '20kr', '15%')
Liquor('Dry Vermouth', 43, 'Noileprat', '45kr', '17%')

#Mixer Creation
Mixer('Tonic', 1889, 'SweTnc', '5 kr')
Mixer('Sugar Syrup', 2000, 'Simple', None)
Mixer('Citrus_Juice', 3000, 'ICA', None)

bar = Bar()
bar.reduce_stock('Whiskey Sour')
print(Item.all_items())

Prints:

Name: Vodka, Stock: 79, Brand: Absolut, Price: 35 kr, Percentage: 37.5%
Name: Mezcal, Stock: 56, Brand: Corte Vetusto, Price: 55 kr, Percentage: 45%
Name: Scotch, Stock: 89, Brand: Ardbeg, Price: 50 kr, Percentage: 46%
Name: Rum, Stock: 109, Brand: Havana Club, Price: 25 kr, Percentage: 37.5%
Name: Baileys, Stock: 43, Brand: Baileys, Price: 20 kr, Percentage: 17%
Name: Gin, Stock: 89, Brand: Beefeater, Price: 40 kr, Percentage: 40%
Name: Campari, Stock: 97, Brand: Campari, Price: 20 kr, Percentage: 20%
Name: Sweet Vermouth, Stock: 146, Brand: Martini Rosso, Price: 20kr, Percentage: 15%
Name: Dry Vermouth, Stock: 43, Brand: Noileprat, Price: 45kr, Percentage: 17%
Name: Tonic, Stock: 1889, Brand: SweTnc, Price: 5 kr
Name: Sugar Syrup, Stock: 1998, Brand: Simple, Price: None
Name: Citrus_Juice, Stock: 2997, Brand: ICA, Price: None
  • Related