1

I have a basic shopping cart that works. I am trying to learn string formatting -- Custom Object: https://pyformat.info/#custom_1

What I want to do is this:

print("Your cart contains: {0:short}".format(cart))

Should return:

Your cart contains: cucumbers, tissues, tomatoes, toothpaste

My format method is wrong. I keep getting:

Traceback (most recent call last):
  File "C:/Users/Mark/PycharmProjects/main/main.py", line 54, in <module>
    print("Your cart contains: {0:short}".format(cart))
TypeError: __format__ must return a str, not NoneType

My code:

class Item(object):
    def __init__(self, unq_id, name, price, qty, measure):
        self.unq_id = unq_id
        self.product_name = name
        self.price = price
        self.qty = qty
        self.measure = measure


class Cart(object):
    def __init__(self):
        self.content = dict()

    def __format__(self, format_type):
        if format == 'short':
            return ', '.join(item.name for item in self.content)

    def add(self, item):
        if item.unq_id not in self.content:
            self.content.update({item.unq_id: item})
            return
        for k, v in self.content.get(item.unq_id).items():
            if k == 'unq_id':
                continue
            elif k == 'qty':
                total_qty = v.qty + item.qty
                if total_qty:
                    v.qty = total_qty
                    continue
                self.remove_item(k)
            else:
                v[k] = item[k]

    def get_total(self):
        return sum([v.price * v.qty for _, v in self.content.items()])

    def get_num_items(self):
        return sum([v.qty for _, v in self.content.items()])

    def remove_item(self, key):
        self.content.pop(key)


if __name__ == '__main__':
    cart = Cart()
    cart.add(Item(1, "Cucumbers", 1., 1, 'kg'))
    cart.add(Item(2, "Tissues", 1., 2, 'dozen'))
    cart.add(Item(3, "Tomatoes", 1., 5, 'box'))
    cart.add(Item(4, "Toothpaste", 1., 5, 'box'))
    # print("You have %i items in your cart for a total of $%.02f" % (cart.get_num_items(), cart.get_total()))
    print("Your cart contains: {0:short}".format(cart))
    # cart.remove_item(1)
    # print("You have %i items in your cart for a total of $%.02f" % (cart.get_num_items(), cart.get_total()))

1 Answer 1

1

The problem is in your __format__ realization:

def __format__(self, format_type):
    if format == 'short':
        return ', '.join(item.name for item in self.content)
  • issue 1: if format == 'short':
    -------------^--------------- - should be format_type

  • issue 2: ...(item.name - there's no attribute name on Item class.


The proper definition:

def __format__(self, format_type):
    if format_type == 'short':
        return ', '.join(i.product_name for i in self.content.values())

Then, the line print("Your cart contains: {0:short}".format(cart)) will output:

Your cart contains: Cucumbers, Tissues, Tomatoes, Toothpaste
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.