Session 4: objects & classes: 21.03.21 5 pm GMT+1

Hi everybody,

as requested we take a step back and I will introduce to classes and objects on the next session.

Link and exercises will follow.

If you have any questions, let me know. 

Looking forward 🙂
Tagged:

Comments

  • awesome! Looking forward to it!
  • Here is the link for the session tomorrow: https://meet.jit.si/python_classes
    You will also find exercises for creating and working with classes attached.

  • edited March 2021
    Hello Alex, hello Everyone,
    I finished Session 4's exercise and just wanted to verify a few things regarding Exercise 3 (the expansion of the Basket class - add_discount method).
    From the way the test is structured, it seems that:
    1. The evaluation whether a Basket has enough items to be eligible for a discount must be done at the same time the total_gross method is called. To make it so, I edited the  total_gross method from Exercise 2 to include that check. The actual add_discount method just a) sets a flag that there is now a possibility of getting a discount if the basket qualifies. b) the values for discount_percentage and number_of_items.
    2. The discount is applied to the price before the tax.

    This got me the right answer and passed all tests, but because I ended up editing a method from a previous answer, I just wanted to know whether there is a more straightforward way that I might have overlooked.

    For reference, these are the snippets for the two Basket methods I mentioned above + my Basket class __init__. I didn't include the rest of the code, but if it's clearer to post the entire Basket class (or also Product class) let me know:
    def __init__(self):
    self.basket_list = []
    self.discount_percentage = None
    self.number_of_items = None
    def total_gross(self):
    total_prices = []
    if self.discount_percentage:
    if len(self.basket_list) >= self.number_of_items:
    for product in self.basket_list:
    discount_price = product.price - (product.price * self.discount_percentage/100)
    tax_price = discount_price + (discount_price * product.tax/100)
    total_prices.append(tax_price)
    else:
    total_prices = [product.gross() for product in self.basket_list]
    return sum(total_price
    def add_discount(self, discount_percentage, number_of_items):
    self.discount_percentage = discount_percentage
    self.number_of_items = number_of_items
  • I used a try block to catch if the instance variable exists that I create in the add_discount method so that I wouldn't need to add anything to the init but I just did this for fun and I'm not sure if it's what you'd ever actually do. Assigning one if it doesn't exist makes total_gross work if a discount was added or not.
        def total_gross(self, total=0):
            try:
                self.discount
            except AttributeError:
                self.discount = 1
            for item in self.basket:
                total += item.gross()
            return round((total * self.discount), 2) if self.discount > 0 else round(total, 2)
    Here's my add_discount method. 
        def add_discount(self, discount_percentage, number_of_items):
            if number_of_items >= len(self.basket):
                self.discount = float((discount_percentage / 100))
                return self.discount
            else:
                return 'Not enough items'

  • @WinterGreenMints : It is absolutly fine to change existing code.
    @PowerTurzt: Pay attention, that your `add_discount` method sometimes returns a float and sometimes a string. This may be confusing and a potential source of error.
    Here are my total_gross and add_discount methods:

    def total_gross(self):
        """ 
    Returns gross as float Applies discount if discount added and num_items sufficient """ gross = sum([p.gross() for p in self.products]) apply_discount = self.discount is not None and len(self.products) >= self.num_items return gross * self.discount if apply_discount else gross

    def add_discount(self, discount, num_items):
    """ Calculates the discount which is applied if num_items reached """
    self.discount = (100 - discount)/100
    self.num_items = num_items
     
    self.discount is initialized to None in __init__.
    apply_discount works in both cases because the second part of the and statement is never executed if add_discount has never been called because it is still None.
    Also note that my solution would be cleaner if I used self._discount and self._num_items because my solution will not work correctly if a client manipulates these variables without the proper functions. Which is allowed because of missing _ before the var name ...

  • Oh, I like the try/except, @PowerTurtz, that's neat. Did the test still pass for you to put the number_of_items check into add_discount? For me, it failed because the test calls "add_discount" before it creates the second instance of product, so the condition is not met. 
  • Oh, I like the try/except, @PowerTurtz, that's neat. Did the test still pass for you to put the number_of_items check into add_discount? For me, it failed because the test calls "add_discount" before it creates the second instance of product, so the condition is not met. 
    Yeah it passes because the try block catches if the discount variable doesn't exist, then assigns 1 if discount hasn't been instantiated. So my calculation still works at the end. 
  • edited April 2021
    Ah, I see. Thank you, @PowerTurtz ; and @admin for the code and explanations. Much appreciated!
Sign In or Register to comment.