Working with **kwargs

Hello guys could you help me with something simple? I want to add a menu (food, drink…) to table 1 how could it be done with this code?

table = {}

def assign_table(number, name, vip_status=False):
table[number] = [name, vip_status]

assign_table(1, ‘Karolin’, vip_status=True)
print(table)

assign_table(2, ‘Boby’)
print(table)

def assign_food(**menu):

What exactly does this mean?

That is: what do you see in the table before adding the menu, and what should you see afterward? And, what problem do you hope to solve this way?

Hi,

based on the info that you submitted, I think that a class might be better suited for your
application versus a list or dictionary at least when it comes to creating customers (assigning tables).

class Customer:

    def __init__(self, table_num, name, vip_status = False):

        self.table_number = table_num
        self.name = name
        self.vip_status = vip_status

    def print_customer_info(self):

        print('\nTable No.:    ', self.table_number)
        print('Customer Name:', self.name)
        print('VIP Status:   ', self.vip_status)

# Creating objects (customers)   
client1 = Customer(1,'Sam',True) # Create one customer
client1.print_customer_info()    # Print customer info

client2 = Customer(4,'Roger')    # Create one customer
client2.print_customer_info()    # Print customer info

One small note. When entering code onto the screen, please use three ‘~’ wavy lines before the code and three of them afterwards. This way the code gets presented as code as shown above. You can find this key just below the ‘esc’ key. Press this key in tandem with the shift key.

To create a menu, you can use dictionaries:

# Menu Items (arbitrary and can create other specialized menus)
Menu_Items = {'Plate 0': 'Large Pasta', 'Plate 1': 'Large Fish Soup', 'Plate 2': 'Egg Rolls (5)', 'Plate 3': '2 Pastrami Sandwitches'}
Beverages = {'Size 0': 'Small', 'Size 1': 'Medium', 'Size 2': 'Large', 'Size 3': 'Extra Large'}
Desserts = {'Dessert 0': 'Ice Creame A La Mode', 'Dessert 1': 'Slice of Apple Pie', 'Dessert 2': '2 Scoop Sundae'}

Good luck!

1 Like

Тhanks Paul :slight_smile:

How could I add a final price? :slight_smile:

Menu_Items = {'Plate 0': 'Large Pasta', 'Plate 1': 'Large Fish Soup', 'Plate 2': 'Egg Rolls (5)', 'Plate 3': '2 Pastrami Sandwitches'}
Menu_Items_Price = {'Large Pasta': 18.00, 'Large Fish Soup': 9.00, 'Egg Rolls (5)': 12.00, '2 Pastrami Sandwitches': 14.00}
Desserts = {'Dessert 0': 'Ice Creame A La Mode', 'Dessert 1': 'Slice of Apple Pie', 'Dessert 2': '2 Scoop Sundae'}
Desserts_Price = {'Ice Creame A La Mode': 12.90, 'Slice of Apple Pie': 7.90, '2 Scoop Sundae': 8.90 }

class Customer:

    def __init__(self, table_num, name, vip_status = False, *prices, **menu):

        self.table_number = table_num
        self.name = name
        self.vip_status = vip_status
        self.prices = prices
        self.menu = menu

    def print_customer_info(self):

        print('\nTable Number: ', self.table_number)
        print('Customer Name:', self.name)
        print('VIP Status:   ', self.vip_status)
        print('Menu: ', self.menu)
        print('Total Price: ', sum(self.prices))

client5 = Customer(2,'Karl', True, food = ['Large Pasta', 'Large Fish Soup'], dessert = ['Slice of Apple Pie']) # Create one customer
client5.print_customer_info()    # Print customer info

Hi,

to do final price, it will help if you perform a simulation of sorts. From a server’s perspective, a customer will first be seated. Thus, the first information that you will obtain is: table number, customer name, and vip status. It will be some time before their order is taken. So, when creating a client, only obtain those first three items of information (in my opinion).

Note that a customer will be placing an order for food items and drinks, one at a time. This is how items are rung up by the server after obtaining the total order. This also applies when customers come in a group. Thus, it would help to design your script/program to simulate this process. By the way, I worked on the initial program that you provided, albeit for drink menu items only. There is food, beverages, and dessert menus (three in total), more can be added of course. I only simulated drinks and the adding and removing of customers from a table list. This way you know which tables are occupied and which are available. So, adding price is a bit more involved. You can also prompt the cashier to enter one item at a time in a loop, for example, in your simulation, until all items have been entered. It is all up to how you want to design your script.

In the following script, I have simulated two major ideas:

  1. The adding and removing of customers to the table list (arriving and departing).
  2. Ordering different types of drinks (with the associated prices).
    • Accidently entering too many drinks (or customer changing the order quantity) and prompting to remove them.

Have a look at this script and let me know if you understand it.

# Menu Items (arbitrary)
Plate_Items = {'Large Pasta': 10.95, 'Large Fish Soup': 11.88, 'Egg Rolls (5)': 9.95, '15 Buffalo Wings': 15.95}
Beverages = {'Small': 3.50, 'Medium': 4.85, 'Large': 5.95, 'Extra Large': 6.90}
Desserts = {'Ice Creame A La Mode': 6.65, 'Slice of Apple Pie': 4.50, '2 Scoop Sundae': 5.75}

TAXE_RATE = 0.0825 # Tax rate
ZERO = 0

class Beverages_Order:

    def __init__(self, ordered_quantity = ZERO, size = False):
        
        self.small_quantity = ZERO
        self.medium_quantity = ZERO
        self.large_quantity = ZERO
        self.extra_large_quantity = ZERO

        self.small_drink_total_charge = ZERO
        self.medium_drink_total_charge = ZERO
        self.large_drink_total_charge = ZERO
        self.extra_large_drink_total_charge = ZERO

    # Keep running tab of drinks ordered per size
    def adding_drinks(self, beverage_size, quantity):

        if beverage_size == Beverages['Small']:
            self.small_quantity += quantity
            
        elif beverage_size == Beverages['Medium']:
            self.medium_quantity += quantity
            
        elif beverage_size == Beverages['Large']:
            self.large_quantity += quantity

        elif beverage_size == Beverages['Extra Large']:
            self.extra_large_quantity += quantity

    # Delete in case of change of choice or entered by mistake
    def deleting_drinks(self, beverage_size, delete_quantity):

        delete_quantity = delete_quantity
        
        if beverage_size == 'Small' and self.small_quantity != ZERO:
            self.small_quantity = self.delete_drinks_from_list(delete_quantity, self.small_quantity)
                                           
        elif beverage_size == 'Medium' and self.medium_quantity != ZERO:
            self.medium_quantity = self.delete_drinks_from_list(delete_quantity, self.medium_quantity)                  
                 
        elif beverage_size == 'Large' and self.large_quantity != ZERO:
            self.large_quantity = self.delete_drinks_from_list(delete_quantity, self.large_quantity)
                  
        elif beverage_size == 'Extra Large' and self.extra_large_quantity != ZERO:
            self.extra_large_quantity = self.delete_drinks_from_list(delete_quantity, self.extra_large_quantity)

    def delete_drinks_from_list(self, delete_quantity, on_hand_drinks):        

        on_hand_drinks -= delete_quantity

        if on_hand_drinks < 0:
            
            print('\nCannot have a negative value of drinks!')
            print('The most you may delete is :', abs(delete_quantity + on_hand_drinks))
            on_hand_drinks += delete_quantity

            while True:

                while True:
                
                    try:
                        delete_quantity = int(input('Enter valid quantity of large drinks to remove: '))
                        break
                    
                    except ValueError:
                        print('You did not enter an integer. Please try again.')               
                
                on_hand_drinks -= delete_quantity

                if on_hand_drinks >= 0:
                    break
                else:
                    on_hand_drinks += delete_quantity

        return on_hand_drinks                  

    def printing_drinks(self):

        total_drink_charges, taxes = self.calc_total()

        print('\nDrinks Ordered:')
        print('--------------')        

        if self.small_quantity != ZERO:
            print('Small :       %d x $%0.2f = ($%0.2f)' % (self.small_quantity, Beverages['Small'], self.small_drink_total_charge))
            
        if self.medium_quantity != ZERO:
            print('Medium :      %d x $%0.2f = ($%0.2f)' % (self.medium_quantity, Beverages['Medium'], self.medium_drink_total_charge))
            
        if self.large_quantity != ZERO:
            print('Large :       %d x $%0.2f = ($%0.2f)' % (self.large_quantity, Beverages['Large'], self.large_drink_total_charge))
            
        if self.extra_large_quantity != ZERO:
            print('Extra Large : %d x $%0.2f = ($%0.2f)' % (self.extra_large_quantity, Beverages['Extra Large'], self.extra_large_drink_total_charge))

        print('Total Taxes (8.25%):      (${:.2f})'.format(taxes))
        print('Total Drink Charges: --->  $%0.2f' % (total_drink_charges + taxes))

    def calc_total(self):

        self.small_drink_total_charge = Beverages['Small'] * self.small_quantity
        self.medium_drink_total_charge = Beverages['Medium'] * self.medium_quantity
        self.large_drink_total_charge = Beverages['Large'] * self.large_quantity
        self.extra_large_drink_total_charge = Beverages['Extra Large'] * self.extra_large_quantity

        total_drink_charges = self.small_drink_total_charge + self.medium_drink_total_charge + self.large_drink_total_charge + self.extra_large_drink_total_charge
        
        taxes = TAXE_RATE * total_drink_charges
        return total_drink_charges, taxes

    def reset_values_for_new_order(self):
        
        self.small_quantity = ZERO
        self.medium_quantity = ZERO
        self.large_quantity = ZERO
        self.extra_large_quantity = ZERO

        self.small_drink_total_charge = ZERO
        self.medium_drink_total_charge = ZERO
        self.large_drink_total_charge = ZERO
        self.extra_large_drink_total_charge = ZERO
        

class Customer:

    def __init__(self, table_num, name, vip_status = False, size = False):

        self.table_number = table_num
        self.name = name
        self.vip_status = vip_status
        
        self.drinks_ordered = Beverages_Order() # Composition

    def print_customer(self):

        print('\nTable No.:    ', self.table_number)
        print('Customer Name:', self.name)
        print('VIP Status:   ', self.vip_status)

    def add_drinks(self, size, quantity):
        return self.drinks_ordered.adding_drinks(size, quantity)

    def delete_drinks(self, size, quantity):
        return self.drinks_ordered.deleting_drinks(size, quantity)    
    
    def print_drinks(self):
        return self.drinks_ordered.printing_drinks()

    # Create dictionary for table number and availability status
tables = {}

# All tables available at start of shift
def initialize_tables():
    for i in range(1, 11):
        tables[i] = False

initialize_tables()

if __name__ == "__main__":


    # Creating objects (customers)   
    client1 = Customer(1,'Sam',True) # Create one customer
    client1.print_customer()         # Print customer info

    # Add drink(s) -> type (size) and quantity
    client1.add_drinks(Beverages['Small'], 3)        # Order 3 small drinks
    client1.add_drinks(Beverages['Medium'], 3)       # Order 3 medium drinks
    client1.add_drinks(Beverages['Large'], 4)        # Order 4 large drinks
    client1.add_drinks(Beverages['Extra Large'], 1)  # Order 1 extra large drink

    # Delete drink(s) - values cannot be greater than quantities that were added
    client1.delete_drinks(Beverages['Large'], 5)       # Attempt to remove 5 drinks when 4 were ordered
    client1.delete_drinks(Beverages['Extra Large'], 2) # Attempt to remove 2 drinks when 1 was ordered

    # Print drinks
    client1.print_drinks()

    # Creating objects (customers)
    client2 = Customer(4,'Roger')    # Create one customer
    client2.print_customer()         # Print customer info

    client3 = Customer(8,'Angelo')   # Create one customer
    client3.print_customer()         # Print customer info

    # Assign tables to clients
    tables[client1.table_number] = client1.name
    tables[client2.table_number] = client2.name
    tables[client3.table_number] = client3.name

    # Check table availability
    def tables_available():
        print('\nTable Availability:')
        print('No.     Status   Client')
        print('-----------------------')
        for i in range(1,11):
            if tables[i] == False:
                print('{}    Available      ---'.format(i))
            else:
                print('{}     OCCUPIED   {}'.format(i, tables[i]))

    tables_available()

    # Customer left, make table available
    tables[client2.table_number] = False

    tables_available()

As you’ll notice, I have tabulated the costs for the various drinks that were ordered. In the script, I created a base class for the clients and a derived class for menu items, namely drinks. I used composition for this via the following line of code:

self.drinks_ordered = Beverages_Order() # Composition

You can duplicate the same for food items and desserts. This would require you to create two more classes, one for each and repeating the same process as was done for the beverages. Of course,
you can modify it to your liking or preferences to suit your needs. The total price would then include adding up the three totals: total beverage costs, total plate food items costs, and dessert total costs if any.

1 Like

Great job Paul, I’m impressed. I don’t understand the whole script because I’m learning now and I’m a beginner. I only wanted the order placed to be calculated in the total price.
Your script is a bit complicated for me so far, I appreciate your help.
I continue to learn :slight_smile:

Hi,

ok, I was under the impression that you wanted to create a more general application.

In any case, give this a shot. You have enough here to add dessert on your own.

# Menu Items (arbitrary)
Plate_Items = {'Large Pasta': 10.95, 'Large Fish Soup': 11.88, 'Egg Rolls (5)': 9.95, '15 Buffalo Wings': 15.95}
Beverages = {'Small': 3.50, 'Medium': 4.85, 'Large': 5.95, 'Extra Large': 6.95}
Desserts = {'Ice Creame A La Mode': 6.65, 'Slice of Apple Pie': 4.50, '2 Scoop Sundae': 5.75}
ZERO = 0

class Customer:

    def __init__(self, table_num, name, vip_status = False):

        self.table_number = table_num
        self.name = name
        self.vip_status = vip_status
        self.main_plate_total_cost = ZERO
        self.drink_total_cost = ZERO

    def print_customer_info(self):

        print('\nTable Number: ', self.table_number)
        print('Customer Name:', self.name)
        print('VIP Status:   ', self.vip_status)

    def main_plate_order(self, *plates):

        self.main_plate_total_cost = 0

        print('\nMain plate(s) ordered')
        print('--------------------')        

        for items_ordered in plates:

            print('{}: ${}'.format(list(Plate_Items.keys())[list(Plate_Items.values()).index(items_ordered)], items_ordered))
            
            self.main_plate_total_cost += items_ordered
        
        print('\nMain plate(s) total cost: $%0.2f' %(self.main_plate_total_cost ))

    def drinks_ordered(self, *drinks):
        
        self.drink_total_cost = 0
        
        print('\nTotal drinks ordered')
        print('--------------------')
        
        for items_ordered in drinks:
            print('{}: ${}'.format(list(Beverages.keys())[list(Beverages.values()).index(items_ordered)], items_ordered))
            
            self.drink_total_cost += items_ordered
        
        print('\nDrinks total cost: $%0.2f' % (self.drink_total_cost))
        
    def total_order(self):
        print('\nThe customer order total cost: $%0.2f' % (self.drink_total_cost + self.main_plate_total_cost))

if __name__ == "__main__":        

    client5 = Customer(2,'Karl', True) # Create customer
    client5.print_customer_info()

    # Customer Order
    client5.main_plate_order(Plate_Items['Large Pasta'], Plate_Items['15 Buffalo Wings'])
    client5.drinks_ordered(Beverages['Extra Large'])
    client5.total_order()

p.s.
Remember to include taxes!

1 Like

You are great :slight_smile: thank you very much!