Home > other >  Is it necessary to change the method each time a new object has to be accounted for?
Is it necessary to change the method each time a new object has to be accounted for?

Time:04-26

I'm new to this site and was looking for a code review as this code 'works', but it seems clunky. The output is formatted correctly but perhaps the print statements are doing most of the work, rather than the code? Is it normal to have to change the method each time a new object has to be accounted for? The "Total:" output wouldn't work correctly in this code if I simply added a new object. Example inputs given were 10 bottles of water at $1 each and 1 bag of chocolate chips for $3.

class ItemToPurchase:
    
    def __init__(self, item_name = 'none', item_price = 0, item_quantity = 0):
        self.item_name = item_name
        self.item_price = item_price
        self.item_quantity = item_quantity        

    def print_item_cost(self, item_name):
        print('{} {} @ ${} = ${}'.format(item_name, item_quantity, item_price, (item_price * item_quantity)))
        print('{} {} @ ${} = ${}'.format(item_name2, item_quantity2, item_price2, (item_price2 * item_quantity2)))
    
if __name__ == "__main__":
    
    # Type main section of code here
    item_one = ItemToPurchase()
    print('Item 1')
    item_name = input('Enter the item name:\n')
    item_price = int(input('Enter the item price:\n'))
    item_quantity = int(input('Enter the item quantity:\n'))
    
    item_two = ItemToPurchase(item_name, item_price, item_quantity)
    print()
    print('Item 2')
    item_name2 = input('Enter the item name:\n')
    item_price2 = int(input('Enter the item price:\n'))
    item_quantity2 = int(input('Enter the item quantity:\n'))
    
    print()
    print('TOTAL COST')
    item = ItemToPurchase()
    item.print_item_cost(item_name)
    print()
    print('Total: $'   str((item_price * item_quantity)   (item_price2 * item_quantity2)))

CodePudding user response:

The self parameter is a stand-in for any instance of that class. It holds all the information about a given instance of the object instantiated by the __init__ method. The self parameter is only visible to an individual instance of the class -- so item_1 and item_2 both can refer to self and only get information about themselves.

For printing your objects, I recommend implementing __str__ instead, which allows you to simply call print(instance_of_my_class):

class ItemToPurchase:
    def __init__(self, item_name = 'none', item_price = 0, item_quantity = 0):
        self.item_name = item_name
        self.item_price = item_price
        self.item_quantity = item_quantity
        self.total_cost = self.item_price * self.item_quantity   

    def __str__(self):
        return f"{self.item_name} {self.item_quantity} @ {self.item_price:.2f} = ${self.total_cost:.2f}"

Note the use of an f-string which makes it a bit easier to read and understand what your formatted string is supposed to do. Note also the use of the formatting code .2f for the price and the new property self.total_cost (this will display your prices correctly -- for example, instead of $21.0 it would return $21.00).

Usage:

item = ItemToPurchase('ping pong paddle', 5.25, 4)
print(item)

Output:

ping pong paddle 4 @ 5.25 = $21.00

CodePudding user response:

You seem to have misunderstood the purpose of a class. Each instance of your class represents a single object of that class, and its methods should only care about that object. So print_item_cost should only print the cost for itself, and it should get all the information it needs from the self parameter, which represents the object to which a method belongs.

class ItemToPurchase:
    def __init__(self, item_name = 'none', item_price = 0, item_quantity = 0):
        self.item_name = item_name
        self.item_price = item_price
        self.item_quantity = item_quantity        

    def print_item_cost(self):
        print('{} {} @ ${} = ${}'.format(self.item_name, self.item_quantity, self.item_price, (self.item_price * self.item_quantity)))

Note that print_item_cost doesn't need an item_name parameter because it gets the item name from self.

Then, you can create any number of instances of the class and print the info for each of them:

if __name__ == "__main__":
    print('Item 1')
    item_name = input('Enter the item name:\n')
    item_price = int(input('Enter the item price:\n'))
    item_quantity = int(input('Enter the item quantity:\n'))
    # Create the item using the inputs you took
    item_one = ItemToPurchase(item_name, item_price, item_quantity)

    print()
    print('Item 2')
    item_name2 = input('Enter the item name:\n')
    item_price2 = int(input('Enter the item price:\n'))
    item_quantity2 = int(input('Enter the item quantity:\n'))
    item_two = ItemToPurchase(item_name2, item_price2, item_quantity2)

    item_one.print_item_cost()
    item_two.print_item_cost()

Ideally, you'd have this in a loop and use a list to keep track of the items, but that's a different issue.

  • Related