yeobub
yeobub

Reputation: 65

How to delete an item from a list inside of a class in python?

So i am building a shopping cart in python that has several commands such as add, remove, change, output item descriptions, output shopping cart, and quit(which terminates the function).

I am having trouble with removing an item from cart as my output is not the desired output.

So for example, for the input:

John Doe
February 1, 2016
a
Nike Romaleos
Volt color, Weightlifting shoes
189
2
a
Chocolate Chips
Semi-sweet
3
5
a
Powerbeats 2 Headphones
Bluetooth headphones
128
1
r
Chocolate Chips
o
q

When it says r and then Chocolate Chips, Chocolate Chips should be removed from the Cart.

My code so far:

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

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

    def print_item_description(self):
        string = '{}: {}'.format(self.item_name, self.item_description)
        print(string, end='\n')
        return string


class ShoppingCart:
    def __init__(self, customer_name='none', current_date='January 1, 2016', cart_items=[]):
        self.customer_name = customer_name
        self.current_date = current_date
        self.cart_items = cart_items

    def add_item(self, string):
        print('\nADD ITEM TO CART', end='\n')
        item_name = str(input('Enter the item name:'))
        item_description = str(input('\nEnter the item description:'))
        item_price = int(input('\nEnter the item price:'))
        item_quantity = int(input('\nEnter the item quantity:\n'))
        self.cart_items.append(ItemToPurchase(item_name, item_price, item_quantity, item_description))

    def remove_item(self):
        print('\nREMOVE ITEM FROM CART', end='\n')
        string = str(input('Enter name of item to remove:\n'))
        i = 0
        for item in self.cart_items:
            if (item.item_name == string):
                del self.cart_items[i]
                i += 1
                flag = True
                break
            else:
                flag = False
        if (flag == False):
            print('Item not found in cart. Nothing removed.')

    def modify_item(self):
        print('\nCHANGE ITEM QUANTITY', end='\n')
        name = str(input('Enter the item name: '))
        for item in self.cart_items:
            if (item.item_name == name):
                quantity = int(input('Enter the new quantity: '))
                item.item_quantity = quantity
                flag = True
                break
            else:
                flag = False
        if (flag == False):
            print('Item not found in cart. Nothing modified.')

    def get_num_items_in_cart(self):
        num_items = 0
        for item in self.cart_items:
            num_items = num_items + item.item_quantity
        return num_items

    def get_cost_of_cart(self):
        total_cost = 0
        cost = 0
        for item in self.cart_items:

            cost = (item.item_quantity * item.item_price)

            total_cost += cost

        return total_cost

    def print_total(self):
        total_cost = self.get_cost_of_cart()
        if (total_cost == 0 and cost == 0):
            print('SHOPPING CART IS EMPTY')
        else:
            self.output_cart()

    def print_descriptions(self):
        print('\nOUTPUT ITEMS\' DESCRIPTIONS')
        print('{}\'s Shopping Cart - {}'.format(self.customer_name, self.current_date), end='\n')
        print('\nItem Descriptions', end='\n')
        for item in self.cart_items:
            print('{}: {}'.format(item.item_name, item.item_description), end='\n')

    def output_cart(self):
        new = ShoppingCart()
        print('OUTPUT SHOPPING CART', end='\n')
        print('{}\'s Shopping Cart - {}'.format(self.customer_name, self.current_date), end='\n')
        print('Number of Items:', new.get_num_items_in_cart(), end='\n\n')

        # IF NUMBER OF ITEMS IN THE OUTPUT CART IS 0...
        if new.get_num_items_in_cart() == 0:
            print('SHOPPING CART IS EMPTY')
        tc = 0
        for item in self.cart_items:
            print('{} {} @ ${} = ${}'.format(item.item_name, item.item_quantity,
                                             item.item_price, (item.item_quantity * item.item_price)), end='\n')
            tc += (item.item_quantity * item.item_price)
        print('\nTotal: ${}'.format(tc), end='\n')


def print_menu(ShoppingCart):
    customer_Cart = newCart
    string = ''
    # declare the string menu
    menu = ('\nMENU\n'
            'a - Add item to cart\n'
            'r - Remove item from cart\n'
            'c - Change item quantity\n'
            'i - Output items\' descriptions\n'
            'o - Output shopping cart\n'
            'q - Quit\n')
    command = ''
    while (command != 'q'):
        string = ''
        print(menu, end='\n')
        command = input('Choose an option:\n')
        while (command != 'a' and command != 'o' and command != 'i' and command != 'r'
               and command != 'c' and command != 'q'):
            command = input('Choose an option:\n')
        if (command == 'a'):
            customer_Cart.add_item(string)
        if (command == 'o'):
            customer_Cart.output_cart()
        if (command == 'i'):
            customer_Cart.print_descriptions()
        if (command == 'r'):
            customer_Cart.remove_item()
        if (command == 'c'):
            customer_Cart.modify_item()


customer_name = str(input('Enter customer\'s name:'))
current_date = str(input('\nEnter today\'s date:\n\n'))
print('Customer name:', customer_name, end='\n')
print('Today\'s date:', current_date)
newCart = ShoppingCart(customer_name, current_date)
print_menu(newCart)

I tried

def remove_item(self):
    print('\nREMOVE ITEM FROM CART', end='\n')
    string = str(input('Enter name of item to remove:\n'))
    i = 0
    for item in self.cart_items:
        if (item.item_name == string):
            del self.cart_items[i]
            i += 1
            flag = True
            break
        else:
            flag = False
    if (flag == False):
        print('Item not found in cart. Nothing removed.')

But my output (with the input) is:

REMOVE ITEM FROM CART
Enter name of item to remove:

MENU
a - Add item to cart
r - Remove item from cart
c - Change item quantity
i - Output items' descriptions
o - Output shopping cart
q - Quit

Choose an option:
OUTPUT SHOPPING CART
John Doe's Shopping Cart - February 1, 2016
Number of Items: 6

Chocolate Chips 5 @ $3 = $15
Powerbeats 2 Headphones 1 @ $128 = $128

Total: $143

MENU
a - Add item to cart
r - Remove item from cart
c - Change item quantity
i - Output items' descriptions
o - Output shopping cart
q - Quit

Choose an option:

When it should be:

REMOVE ITEM FROM CART
Enter name of item to remove:

MENU
a - Add item to cart
r - Remove item from cart
c - Change item quantity
i - Output items' descriptions
o - Output shopping cart
q - Quit

Choose an option:
OUTPUT SHOPPING CART
John Doe's Shopping Cart - February 1, 2016
Number of Items: 3

Nike Romaleos 2 @ $189 = $378
Powerbeats 2 Headphones 1 @ $128 = $128

Total: $506

MENU
a - Add item to cart
r - Remove item from cart
c - Change item quantity
i - Output items' descriptions
o - Output shopping cart
q - Quit

Choose an option:

As you can see, my code is deleting the Nike Romaleos, $189, at Quantity 2 When it should be deleting the Chocolate Chips, $3, at Quantity 5. I am not sure why it is deleting the wrong items, as I inputted Chocolate Chips right after 'r', which calls the

if (command == 'r'):
    customer_Cart.remove_item()

If anyone could help that would be greatly appreciated!

Upvotes: 0

Views: 1527

Answers (3)

pykam
pykam

Reputation: 1481

The reason is that in remove_item() you are deleting the ith element from cart_items instead of deleting the index of the item which you are receiving as an input.

You can use remove instead of del.

This way you will not need the counter i

    def remove_item(self):
        print('\nREMOVE ITEM FROM CART', end='\n')
        string = str(input('Enter name of item to remove:\n'))

        for item in self.cart_items:
            if (item.item_name == string):
                self.cart_items.remove(item)
                flag = True
                break
            else:
                flag = False
        if (flag == False):
            print('Item not found in cart. Nothing removed.')

Upvotes: 0

Yi Zhao
Yi Zhao

Reputation: 336

The logic of following code in remove_item is wrong:

for item in self.cart_items:
    if (item.item_name == string):
        del self.cart_items[i]
        i += 1 # you only inc i when it match the string
        # also after delete, the index may be not consistent.
        flag = True
        break
    else:
        flag = False # you didn't inc i here.

you can use:

self.cart_items = [item for item in self.cart_items if item.item_name != string]

Upvotes: 1

vighnesh153
vighnesh153

Reputation: 5388

In the remove_item method, you are using i as an index to the items. Every time you loop, you only increment the value of i if the item name matches with the input string. What you should be doing is increment i no matter if the condition evaluates to True or not because it is the index. So, just move the increment statement outside the conditional block.

def remove_item(self):
    print('\nREMOVE ITEM FROM CART', end='\n')
    string = str(input('Enter name of item to remove:\n'))
    i = 0
    for item in self.cart_items:
        if (item.item_name == string):
            del self.cart_items[i]
            flag = True
            break
        else:
            flag = False
        i += 1
    if (flag == False):
        print('Item not found in cart. Nothing removed.')

This is a common mistake that every programmer makes. So, Python has provided a more elegant way to access indices of the elements in the loop.

def remove_item(self):
    print('\nREMOVE ITEM FROM CART', end='\n')
    string = str(input('Enter name of item to remove:\n'))

    # We now don't need to handle the indices. Python will
    # do it for us. This magic happens with the help of `enumerate` function.
    for i, item in enumerate(self.cart_items):
        if (item.item_name == string):
            del self.cart_items[i]
            flag = True
            break
        else:
            flag = False
    if (flag == False):
        print('Item not found in cart. Nothing removed.')

Upvotes: 1

Related Questions