Robert Ţiganetea Robert Ţiganetea - 1 month ago 38
Python Question

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)

Answer

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.