Home > other >  How do I fix this TypeError "list indices must be integers or slices, not str"?
How do I fix this TypeError "list indices must be integers or slices, not str"?

Time:07-25

This is the code that works:

candy_name = ["Assorted Small Lollipops", "Assorted Flavours Small", "Assorted Flavours Large", "Large Lollipop", "100g Assorted Flavours Small", "100g Assorted Flavours Large", "Candy Cane", "100g Candy Canes"]
candy_price = [0.1, 0.05, 0.2, 0.5, 4.5, 6, 0.2, 5.5]
candy_info = dict(zip(candy_name, candy_price))
candy_order, number_order, total = [], [], 0


while True:
    candy = input("which candy do you want?")

    while candy not in candy_info:
        candy = input("input error, try again:")
    candy_order.append(candy)
    number = input("How many %s would you like? " % candy)

    while not number.isdigit() or int(number) <= 0:
        number = input("Only integers greater than 0 are allowed, try again: ")
    number_order.append(int(number))

    keep_ordering = input("Would you like to add more to your order? y/n")
    while keep_ordering not in ["y", "n"]:
        keep_ordering = input("Simply enter y or n, try again:")

    if keep_ordering != "y":
        for _candy, _number in zip(candy_order, number_order):
            total  = candy_info[_candy] * _number
        print("Your total spend is $%f" % total)
        break

This works fine however, when I try to implement this in my own code it doesn't work, anybody know what I'm doing wrong? I had it working a few times I'm not sure if I have changed anything to make it not work

candy_name = ["Assorted Small Lollipops", "Assorted Flavours Small", "Assorted Flavours Large", "Large Lollipop", "100g Assorted Flavours Small", "100g Assorted Flavours Large", "Candy Cane", "100g Candy Canes"] #list with all candy types
candy_price = [0.1, 0.05, 0.2, 0.5, 4.5, 6, 0.2, 5.5] #all candy prices
total = 0
price_and_name = dict(zip(candy_name, candy_price))
candy_order = []
price_order = []
number_order = []

while True:
  for candies, price in zip(candy_name, candy_price):
    print(candies, "is $", price) #zips the two lists together so they line up

  price_and_name = [price_and_name.lower() for price_and_name in ["Assorted Small Lollipops", "Assorted Flavours Small", "Assorted Flavours Large", "Large Lollipop", "100g Assorted Flavours Small", "100g Assorted Flavours Large","Candy Cane", "100g Candy Canes"]] #makes the dictionary lowercase so the user input case doesn't matter
  
  candy = input("What candy would you like to order? ").lower()

  while candy not in price_and_name:
    candy = input("That was not one of the options, check your spelling and try again. ").lower()
  candy_order.append(candy)
  number = input("How many %s would you like? " % candy)

  while not number.isdigit() or int(number) <= 0:
    number = input("Only integers greater than 0 are allowed, please try again.")
  number_order.append(int(number))

  keep_ordering = input("Would you like to add more to your order? ").lower()
  while keep_ordering not in ["yes", "no"]:
    keep_ordering = input("Please enter just yes or no, try again. ").lower()

  if keep_ordering != "yes":
    for _candy, _number in zip(candy_order, number_order):
      total  = price_and_name[_candy]   _number
    print("Your total is $%f" % total)
    break

This is the full error message below: Full Error Message

Thanks for your help.

CodePudding user response:

candy_order is a List that contains string values.


    if keep_ordering != "yes":
        for _candy, _number in zip(candy_order, number_order):
          # _candy: string
          # _number: int
          total  = price_and_name[_candy]   _number
          # you are trying to index price_and_name using _candy which is a string
        print("Your total is $%f" % total)
    break

CodePudding user response:

The reason you get that error is that the price_and_name variable is a list and you probably think it's a dictionary. The dictionary you originally created replaced with a list here:

price_and_name = [price_and_name.lower() for price_and_name in ["Assorted Small Lollipops", "Assorted Flavours Small", "Assorted Flavours Large", "Large Lollipop", "100g Assorted Flavours Small", "100g Assorted Flavours Large","Candy Cane", "100g Candy Canes"]] #makes the dictionary lowercase so the user input case doesn't matter

This line doesn't make the dictionary lowercase but replaces it with a list of lowercase candy_names. If you want the candy_names to be lowercase then just call

candy_names.lower()

after declaring it and then the dictionary created after will hold lowercase candy_names as it's keys.

CodePudding user response:

In attempting to update price_and_name to contain lowercase versions of the candy names, you changed it from a dict to a list (as pointed out in a comment by @mozway), so that when you later tried to access a dict value by str key, it gave you the error in your question.

Also, on an unrelated note, your calculation for total should use multiplication, not addition.

Suggested changes:

If you change this line:

price_and_name = dict(zip(candy_name, candy_price))

... to be this:

price_and_name = dict(zip([x.lower() for x in candy_name], candy_price))

... and delete this line:

  price_and_name = [price_and_name.lower() for price_and_name in ["Assorted Small Lollipops", "Assorted Flavours Small", "Assorted Flavours Large", "Large Lollipop", "100g Assorted Flavours Small", "100g Assorted Flavours Large","Candy Cane", "100g Candy Canes"]] #makes the dictionary lowercase so the user input case doesn't matter

... and change this line:

      total  = price_and_name[_candy]   _number

... to this:

      total  = price_and_name[_candy] * _number

... it will work.

  • Related