3
\$\begingroup\$

The goal:

Create an application which manages an inventory of products. Create a product class which has a price, id, and quantity on hand. Then create an inventory class which keeps track of various products and can sum up the inventory value.

I figured out how to get a list of dictionaries, and then add up the price. My output isn't pretty, but before I continue, I would simply like general critique.

class Product:
    def __init__(self, i, p, q):
        self.identification = i
        self.price = p
        self.quantity = q
        self.item_dictionary = {'ID: ': self.identification, 'Price: ': self.price, 'Quantity: ': self.quantity}


class Inventory:
    def __init__(self):
        self.identification, self.price_list, self.quantity_list = [], [], []
        self.products = [
            product_1.item_dictionary,
            product_2.item_dictionary
        ]  # Make list of item dictionaries

    for i in self.products:
        self.identification.append(i['ID: '])
        self.price_list.append(i['Price: '])
        self.quantity_list.append(i['Quantity: '])
        # Make unique lists of ID, Price, and Quantity

    print(sum(self.price_list))


product_1 = Product(32, 23, 2)
product_2 = Product(23, 65, 3)


inventory_1 = Inventory()
\$\endgroup\$
4
  • \$\begingroup\$ Your program does not work, have you tested it? \$\endgroup\$ Commented May 20, 2018 at 4:22
  • \$\begingroup\$ It works for me in Pycharm, however it could have something to do with the indentations. Im not used to posting code on here to be honest. I can see if i can fix it. \$\endgroup\$ Commented May 20, 2018 at 5:15
  • \$\begingroup\$ is this the indentation you were going for? \$\endgroup\$ Commented May 20, 2018 at 5:26
  • \$\begingroup\$ Welcome to Code Review! I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. Code Review is not the site to ask for help in fixing or changing what your code does. It looks like the for i in self.products and print(...) sections are not indented correctly. Once the code does what you want, we would love to help you do the same thing in a cleaner way! Please see our help center for more information. \$\endgroup\$ Commented May 21, 2018 at 17:56

2 Answers 2

3
\$\begingroup\$
  • Single letter names are not readable in general. i, p and q, for example, would be easier to read as identification, price, and quantity. This is also a common pattern, where parameters to be stored as fields are named the same as the fields.
  • The last three lines should be in a main function, called if __name__ == '__main__'.
  • item_dictionary would be better expressed either by making Product a dict subtype or making an as_dict method.
  • product_1 and product_2 should be passed as either a products array argument or a *products star argument to Inventory().
  • Why unpack the products in Inventory?
  • The code directly inside Inventory (for loop and print()) should be in a method. I've never even seen Python code with something other than method definitions at the top level.
  • Product quantity is a property of an inventory, not a product.

I would probably implement this as follows (untested):

class Product:
    def __init__(self, identification, price):
        self.identification = identification
        self.price = price

class Inventory:
    def __init__(self, products):
        self.products = products

    @property
    def value():
        return sum(product.price for product in self.products)

def main():
    product_1 = Product(32, 23)
    product_2 = Product(23, 65)
    inventory = Inventory(2 * [product_1] + 3 * [product_2])
    print(inventory.value)

if __name__ == '__main__':
    main()
\$\endgroup\$
2
  • \$\begingroup\$ "I've never even seen Python code with something other than method definitions at the top level."... Of a class. This can be useful in exotic static setup, but here that's indeed not needed. \$\endgroup\$
    – Reinderien
    Commented May 20, 2018 at 10:25
  • 2
    \$\begingroup\$ Your sum () should not use an inner list. Pass the generator directly to sum. \$\endgroup\$
    – Reinderien
    Commented May 20, 2018 at 10:26
2
\$\begingroup\$

If an object has attributes x and y, you should not duplicate the data by adding an attribute z which is calculated based on them (ex: \$z = x + y\$). You rather should create a function which computes the calculation for you.

This is valid whatever the operation is. In your case, you have self.identification, self.price so you should not have an other attribute whose is a combination of the previous ones: self.item_dictionary = {'ID: ': self.identification, 'Price: ': self.price, 'Quantity: ': self.quantity}. You can remedy to that by relying on the magic function __repr__():

def __repr__(self):
    return 'ID:  {}, Price: {},  Quantity: {}'.format(self.identification, self.price, self.quantity)
\$\endgroup\$
1

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