Why is Try Block of code not counting the same as when I don't use Try?

Question:

I have a function that pulls data from a Restaurant’s Clover POS System, then returns dictionaries with how many of each item was sold and then how many of each modification was made (ex: "Remove Nutella":5)

My problem occurs when one of the orders in the data didn’t actually have an item on it.

So I wrapped a try statement around my for loop in case there’s is a blank check open. However it changes the total values that my function returns.

So here is my code with the try statement in line 5(This is the one of concern):

        for index in range(len(data_elements)):
            order = data_elements[index]
            print(index)
            
            try:
                for i in range(len(order["lineItems"]["elements"])):
                    item = order["lineItems"]["elements"][i]["name"]
                    item = item.replace(" TPD","")
                    item = item.replace("*","")
                    item = item.replace("Bowl ","Bowl")

                    if item in inventory_sold:
                        inventory_sold[item] += 1
                    else:
                        inventory_sold[item] = 1
                try:
                    for ind in range(len(order["lineItems"]["elements"][i]["modifications"]["elements"])):
                        item_modification = order["lineItems"]["elements"][i]["modifications"]["elements"][ind]["name"]
                        item_modification = item_modification.replace("(or Extra) ","")
                        item_modification=item_modification.replace("or Extra ","")
                        item_modification=item_modification.replace("Strawberries","Strawberry")
                        item_modification=item_modification.replace("Substitute","Sub")
                        item_modification = item_modification.strip()

                        if item_modification in mod_dict:
                            mod_dict[item_modification] += 1
                        else:
                            mod_dict[item_modification] = 1
                except KeyError:
                    pass
            except KeyError:
                pass

        return [inventory_sold,mod_dict]

So for example yesterday there were no blank checks left open so my code runs smooth without the try statement however I need to account for days where there may be a check with no item on it.

Without the try statement in line 5 my code looks like this:

        for index in range(len(data_elements)):
            order = data_elements[index]
            print(index)

            
            for i in range(len(order["lineItems"]["elements"])):
                item = order["lineItems"]["elements"][i]["name"]
                item = item.replace(" TPD","")
                item = item.replace("*","")
                item = item.replace("Bowl ","Bowl")

                if item in inventory_sold:
                    inventory_sold[item] += 1
                else:
                    inventory_sold[item] = 1
                try:
                    for ind in range(len(order["lineItems"]["elements"][i]["modifications"]["elements"])):
                        item_modification = order["lineItems"]["elements"][i]["modifications"]["elements"][ind]["name"]
                        item_modification = item_modification.replace("(or Extra) ","")
                        item_modification=item_modification.replace("or Extra ","")
                        item_modification=item_modification.replace("Strawberries","Strawberry")
                        item_modification=item_modification.replace("Substitute","Sub")
                        item_modification = item_modification.strip()

                        if item_modification in mod_dict:
                            mod_dict[item_modification] += 1
                        else:
                            mod_dict[item_modification] = 1
                except KeyError:
                    pass
            

        return [inventory_sold,mod_dict]

This above code correctly counts the values from my data for example ("Add Nutella": 38)

Meanwhile when I add the try statement in line 5 from earlier to account for days that there may be a KeyError my values are short. Ex.("Add Nutella" :26)

Also I should add the first dictionary is correct no matter what for some reason the 3rd for loop which creates the mods dictionary is the one that gets affected.

Any help is much appreciated!

Asked By: Lamar Mccloud

||

Answers:

From our discussion it seems that your problem is that there may sometimes not be elements when looping through. Therefore you could likely do something like this instead of try except blocks. (some of your code was refactored for readability purposes)

for index,order in enumerate(data_elements): # enumerate allows you to access both the index and the element
    print(index)
    
    if 'lineItems' not in order: # check if there are lineItems in the order
        continue # continues the for loop (skipping the below)
    
    for order_item in order["lineItems"]["elements"]: # access the elements directly
        order_name = order_item["name"]
        order_name = order_name.replace(" TPD","")
        order_name = order_name.replace("*","")
        order_name = order_name.replace("Bowl ","Bowl")

        if order_name in inventory_sold:
            inventory_sold[order_name] += 1
        else:
            inventory_sold[order_name] = 1

        if 'modifications' not in order_item: # check if there are modifications in the order
            continue # continues the for loop (skipping the below)
        
        for order_modification in order_item["modifications"]["elements"]:
            order_modification_name = order_modification["name"]
            order_modification_name = order_modification_name.replace("(or Extra) ","")
            order_modification_name = order_modification_name.replace("or Extra ","")
            order_modification_name = order_modification_name.replace("Strawberries","Strawberry")
            order_modification_name = order_modification_name.replace("Substitute","Sub")
            order_modification_name = order_modification_name.strip()

            if order_modification_name in mod_dict:
                mod_dict[order_modification_name] += 1
            else:
                mod_dict[order_modification_name] = 1

return [inventory_sold,mod_dict]

Using if statements to catch any errors that may occur and handle the code appropriately as they are known elements to occur.

Answered By: Andrew Ryan