1

all I'm new to Python's Data Structure & Algorithm. I implemented Insertion & Bubble Sort into my inventory program. Both my insertion and bubble sort works when I'm sorting the current dictionary. However, after adding new items or removing items from my dictionary, my insertion and bubble sort obtained a key error. I've tried changing the dictionary to [{description..}] and also changing market[len(market) + 1] to market[len(market)] before. None of these work at all. Would really appreciate if someone helped me edit my code or explain to me what's going on. Thank you in advance :")

market = {0: {'Description': 'Chocolate', 'Stock': 65, 'Price': 3.2, 'Expiry': '27 Dec', 'Discount': 'eligible'},
          1: {'Description': 'Bread', 'Stock': 20, 'Price': 2.7, 'Expiry': '15 June', 'Discount': 'eligible'},
          2: {'Description': 'Apples', 'Stock': 97, 'Price': 10.6, 'Expiry': '12 July', 'Discount': 'not eligible'},
          3: {'Description': 'Potato', 'Stock': 81, 'Price': 20.8, 'Expiry': '13 April', 'Discount': 'not eligible'},
          4: {'Description': 'Ice', 'Stock': 91, 'Price': 9.8, 'Expiry': '16 April', 'Discount': 'not eligible'}
          }


def menu():
    print('Press 1: To Add items. ')
    print('Press 2: To View items. ')
    print('Press 3: To Remove items. ')
    print('Press 4: Use Insertion Sort. ')
    print('Press 5: Use Bubble Sort. ')
    print('Press 6: Use Binary Search. ')
    print('Press 7: View Total and Average stock level. ')
    print('Press q: To Quit program. ')
    return input('What would you like to do? ')


# print(len(market) + 1) # check counter


# Insertion Sort

def insertionSort(theSeq, key):

    for i in range(1, len(theSeq)):
        temp = theSeq[i][key]
        j = i
        while j > 0 and temp < theSeq[j - 1][key]:
               theSeq[j][key] = theSeq[j - 1][key]
               j = j - 1
        theSeq[j][key] = temp
    return theSeq


# Sorting Menu
def sort_menu(second_list, sort_type):
    print('1. Sort by Description')
    print('2. Sort by Price')

    # Get user input
    user_input = input('Please enter choice: ')

    if user_input == '1':
        second_list = sort_type(second_list, 'Description')
        print('Success! Inventory list is sorted by Description!')

    elif user_input == '2':
        second_list = sort_type(second_list, 'Price')
        print('Success! Inventory list is sorted by Price!')
    else:
        print('You have entered an invalid option!')

    # Return updated list
    return second_list


# Bubble Sort
def bubble_sort(second_list, key):

    # Create temp copy of list
    temp = second_list.copy()

    # Obtain length of list
    y = len(temp)

    for i in range(y - 1, 0, -1):
        for j in range(i):
            if temp[j][key] > temp[j + 1][key]:
                temp[j], temp[j + 1] = temp[j + 1], temp[j]
    # Return updated list
    return temp

# Binary Search
def binarysearch(dictionary,item):
    global founditem
    itemlist = []
    for item2 in dictionary:
        itemlist.append(item2)
    first = 0
    last = len(itemlist) - 1
    found = False

    while first <= last and not found:
        midpoint = (first + last)//2
        if itemlist[midpoint] == item:
            # print(midpoint) test print out
            founditem = dictionary.get(midpoint)
            found = True
        else:
            if item < itemlist[midpoint]:
                last = midpoint-1
            else:
                first = midpoint+1
    return founditem


# Print total and average stock level
def average(market):
    n = len(market)
    total = 0
    for i in range(0,n):
        total += market[i]["Stock"]
    average = total/n
    return average

def total(market):
    n = len(market)
    total = 0
    for i in range(0,n):
        total += market[i]["Stock"]
    return total


while True:
    run = menu()
    if run == '1':
        # market[len(market) + 1] = {}
        # addMarket = input('Item to be added to Market? ')
        # market[len(market) + 1]['Description'] = addMarket
        name = input('Item to be added to Market? ')
        price = float(input('Price of food?'))
        amount = int(input('Qty of food to be added to stock? '))
        expiry = input('Enter expiry date: ')
        discount = input('Enter eligibility of discount: ')
        market[len(market) + 1] = {'Description': name, 'Stock': amount, 'Price': price, 'Expiry': expiry,
                                   'Discount': discount}

    elif run == '2':
        for i in market:
            item = market[i]
            print("Item No - %d Description - %s Stock - %d Price - %.2f Expiry - %s Discount - %s" % (
            i, item['Description'], item['Stock'], item['Price'], item['Expiry'], item['Discount']))


    elif run == '3':
        remove = int(input('Key in item number to remove: '))
        del market[remove]

    elif run == '4':
        market = sort_menu(market, insertionSort)

    elif run == '5':
        market = sort_menu(market, bubble_sort)
    #
    elif run == '6':
        key = int(input('Enter key you want to search: '))
        print(binarysearch(market, key))

    elif run == '7':
        print('')
        print('Total stock level is',total(market), 'and Average stock level is', average(market))
        print('')

    else:
        quit = str()
        while quit.upper() != "Q":
            quit = input("Enter Q or q to return to Main Menu. ")
            if quit.upper() == "Q":
                print('Thank you for using MamaStore!')
                menu()
Blckknght
  • 100,903
  • 11
  • 120
  • 169
Jazli Wan
  • 23
  • 4
  • Hi Jazli. Please don't remove the contents of your question just because it's solved. That makes the answers below not make any sense, since we can't tell what problem they're trying to solve. If you *really* need to, you may be able to close and delete the whole question, but in general we want to have solved problems stay on the site in the hopes they'll help other users with similar issues. – Blckknght Jun 10 '20 at 07:57

2 Answers2

0

The problem with your insertion code is that you are inserting new elements by skipping one index per insertion. Initially size of market is 5 so when you insert new element that element should go at index 5 (starting index is 0) but market[len(market)+1] is inserting at index 6. So when you run a sequential loop in sorting it throws a keyerror because you dont have 5 as a key.
Similarly in deletion when you delete any item, sequence breaks which leads to the keyerror as it did in the case of insertion. You should probably consider running the loops over the keys of the dictionary which in your case are those item ids.
However for your code specifically it would be convinient to convert dict to a list and then perform the sorting later before returning it convert it back to dictionary. I am attaching a working code below:


market = {0: {'Description': 'Chocolate', 'Stock': 65, 'Price': 3.2, 'Expiry': '27 Dec', 'Discount': 'eligible'},
          1: {'Description': 'Bread', 'Stock': 20, 'Price': 2.7, 'Expiry': '15 June', 'Discount': 'eligible'},
          2: {'Description': 'Apples', 'Stock': 97, 'Price': 10.6, 'Expiry': '12 July', 'Discount': 'not eligible'},
          3: {'Description': 'Potato', 'Stock': 81, 'Price': 20.8, 'Expiry': '13 April', 'Discount': 'not eligible'},
          4: {'Description': 'Ice', 'Stock': 91, 'Price': 9.8, 'Expiry': '16 April', 'Discount': 'not eligible'}
          }


def menu():
    print('Press 1: To Add items. ')
    print('Press 2: To View items. ')
    print('Press 3: To Remove items. ')
    print('Press 4: Use Insertion Sort. ')
    print('Press 5: Use Bubble Sort. ')
    print('Press 6: Use Binary Search. ')
    print('Press 7: View Total and Average stock level. ')
    print('Press q: To Quit program. ')
    return input('What would you like to do? ')


# Insertion Sort

def insertionSort(theSeq, key):
    temp1 = [i for i in theSeq.values()]
    for i in range(0, len(temp1)):
        temp = temp1[i][key]
        j = i
        while j > 0 and temp < temp1[j - 1][key]:
            temp1[j][key] = temp1[j - 1][key]
            j = j - 1
        temp1[j][key] = temp
    s = {}
    for i in range(len(temp1)):
        s[i] = temp1[i]
    return s


# Sorting Menu
def sort_menu(second_list, sort_type):
    print('1. Sort by Description')
    print('2. Sort by Price')

    # Get user input
    user_input = input('Please enter choice: ')
    if user_input == '1':
        second_list = sort_type(second_list, 'Description')
        print('Success! Inventory list is sorted by Description!')

    elif user_input == '2':
        second_list = sort_type(second_list, 'Price')
        print('Success! Inventory list is sorted by Price!')
    else:
        print('You have entered an invalid option!')

    # Return updated list
    return second_list


# Bubble Sort
def bubble_sort(second_list, key):
    # Create temp copy of list
    temp = [i for  i in second_list.values()]

    # Obtain length of list
    y = len(temp)

    for i in range(y - 1, 0, -1):
        for j in range(i):
            if temp[j][key] > temp[j + 1][key]:
                temp[j], temp[j + 1] = temp[j + 1], temp[j]
    # Return updated list
    s = {}
    for i in range(len(temp)):
        s[i] = temp[i]
    return s

# Binary Search
def binarysearch(dictionary,item):
    global founditem
    itemlist = []
    for item2 in dictionary:
        itemlist.append(item2)
    first = 0
    last = len(itemlist) - 1
    found = False

    while first <= last and not found:
        midpoint = (first + last)//2
        if itemlist[midpoint] == item:
            # print(midpoint) test print out
            founditem = dictionary.get(midpoint)
            found = True
        else:
            if item < itemlist[midpoint]:
                last = midpoint-1
            else:
                first = midpoint+1
    return founditem


# Print total and average stock level
def average(market):
    n = len(market)
    total = 0
    for i in range(0,n):
        total += market[i]["Stock"]
    average = total/n
    return average

def total(market):
    n = len(market)
    total = 0
    for i in range(0,n):
        total += market[i]["Stock"]
    return total


while True:
    run = menu()
    if run == '1':
        name = input('Item to be added to Market? ')
        price = float(input('Price of food?'))
        amount = int(input('Qty of food to be added to stock? '))
        expiry = input('Enter expiry date: ')
        discount = input('Enter eligibility of discount: ')
        market[len(market)] = {'Description': name, 'Stock': amount, 'Price': price, 'Expiry': expiry,
                                   'Discount': discount}

    elif run == '2':
        for i in market:
            item = market[i]
            print("Item No - %d Description - %s Stock - %d Price - %.2f Expiry - %s Discount - %s" % (
            i, item['Description'], item['Stock'], item['Price'], item['Expiry'], item['Discount']))

    elif run == '3':
        remove = int(input('Key in item number to remove: '))
        del market[remove]

    elif run == '4':
        market = sort_menu(market, insertionSort)

    elif run == '5':
        market = sort_menu(market, bubble_sort)

    elif run == '6':
        key = int(input('Enter key you want to search: '))
        print(binarysearch(market, key))

    elif run == '7':
        print('')
        print('Total stock level is',total(market), 'and Average stock level is', average(market))
        print('')

    else:
        quit = str()
        while quit.upper() != "Q":
            quit = input("Enter Q or q to return to Main Menu. ")
            if quit.upper() == "Q":
                print('Thank you for using MamaStore!')
                menu()

Hope it helps!

0

You are mixing the concepts of keys and indices. When you add an item, you give it the key len(market) + 1 which is 5 + 1. Key '5' is therefor left unused and you get a dictionary with the keys 1, 2, 3, 4, 6

The next time, when you start sorting, you try to use those keys as indices. With range(y - 1, 0, -1), you iterate over a continuous set of integers, and thus a key error on key='5'. You should iterate over the keys. To get indices of your dictionary, use for example something like

for i, d in enumerate(market):...

The same problem occurs when you remove an item. The key is removed leaving a dictionary with for example the keys: 0, 1, 2, 4. You now get a key error on key='3'

Hope this gives enough clues to correct your script.

Ronald
  • 2,930
  • 2
  • 7
  • 18