Robert Ţiganetea
Robert Ţiganetea

Reputation: 47

TypeError: tuple indices must be integers or slices, not str

I need to make a function that updates tuples in a list of tuples. The tuples contain transactions, which are characterised by ammount, day, and type. I made this function that should completely replace a tuple with a new one, but when I try to print the updated list of tuples I get the error:

TypeError: tuple indices must be integers or slices, not str

The code:

def addtransaction(transactions, ammount, day, type): 
    newtransactions = {
        "Ammount": ammount,
        "Day": day,
        "Type": type
        }
   transactions.append(newtransaction)

def show_addtransaction(transactions):
     Ammount = float(input("Ammount: "))
     Day = input("Day: ")
     Type = input("Type: ")
    addtransaction(transactions, ammount, day, type)

def show_all_transaction(transactions):
    print()
    for i, transaction in enumerate(transactions):
        print("{0}. Transaction with the ammount of {1} on day {2} of type:     {3}".format(
            i + 1,
            transaction['Ammount'], ; Here is where the error occurs.
            transaction['Day'],
            transaction['Type']))

def update_transaction(transactions): ; "transactions" is the list of tuples
    x = input("Pick a transaction by index:") 
    a = float(input("Choose a new ammount:"))
    b = input("Choose a new day:")
    c = input("Choose a new type:")
    i = x
    transactions[int(i)] = (a, b, c)

addtransaction(transactions, 1, 2, service)
show_all_transaction(transactions)
update_transaction(transactions)
show_all_transaction(transactions)

Upvotes: 2

Views: 36288

Answers (2)

FiveFour
FiveFour

Reputation: 1

This is not a generic answer, I'll just mention it if someone bumps into the same problem.

As stated before, tuples are addressed by integer e.g. my_tuple[int] or slice my_tuple[int1:int2].

I ran into trouble when I ported code from Python2 to Python3. The original code used somthing like my_tuple[int1/int2], this worked in Python2 since division int/int results in int. in Python3 int/int results in a floating point number. I had to fix the code to my_tuple[int1//int2] to get the python2 behavior.

Upvotes: 0

xZise
xZise

Reputation: 2379

A tuple is basically only a list, with the difference that in a tuple you cannot overwrite a value in it without creating a new tuple.

This means you can only access each value by an index starting at 0, like transactions[0][0].

But as it appears you should actually use a dict in the first place. So you need to rewrite update_transaction to actually create a dict similar to how addtransaction works. But instead of adding the new transaction to the end you just need to overwrite the transaction at the given index.

This is what update_transaction already does, but it overwrites it with a tuple and not a dict. And when you print it out, it cannot handle that and causes this error.

Original answer (Before I knew the other functions)

If you want to use strings as indexes you need to use a dict. Alternatively you can use namedtuple which are like tuples but it also has an attribute for each value with the name you defined before. So in your case it would be something like:

from collections import namedtuple
Transaction = namedtuple("Transaction", "amount day type")

The names given by the string used to create Transaction and separated by spaces or commas (or both). You can create transactions by simply calling that new object. And accessing either by index or name.

new_transaction = Transaction(the_amount, the_day, the_type)
print(new_transaction[0])
print(new_transaction.amount)

Please note that doing new_transaction["amount"] will still not work.

Upvotes: 2

Related Questions