Python Forum

Full Version: TypeError: string indices must be integers
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
given the code snippet:
i = 0

for key, value in quiz.items():
    i += 1
    print(f"Question {str(i)} : {key['question']}")
Line 5 fails with the error code,
Error:
TypeError: string indices must be integers
The variable named 'i' is clearly an integer. Can someone explain why it fails with this error?
Why do you assume the problem is with i?

The error message talks about an index - i isn't being used as an index. However, 'question' is, so it looks like
Output:
key
is a string.

In cases like this, if it isn't at first glance obvious where the error is coming from, break down the expression into several parts. That way, the error will come from a more specific place.
There is not need need(a bad way) to make a varibale i at start an use it at index later.
Just loop over the dictionary like this.
quiz = {
    'What is the fastest land animal?': 'Cheetah',
    'What is Pi?': 3.14
    }

for key, value in quiz.items():
    #print(key, value)
    print(f"Question {key} answer is: {value}")
Output:
Question What is the fastest land animal? answer is: Cheetah Question What is Pi? answer is: 3.14
(Aug-30-2022, 02:17 PM)ndc85430 Wrote: [ -> ]Why do you assume the problem is with i?

The error message talks about an index - i isn't being used as an index. However, 'question' is, so it looks like
Output:
key
is a string.

In cases like this, if it isn't at first glance obvious where the error is coming from, break down the expression into several parts. That way, the error will come from a more specific place.


You were absolutely right. It wasn't referring to the i but to 'question'. The fact is, there is no key in the dictionary by the name of 'question', but rather a value does. So all I needed to do was change key to value and it worked beautifully.
for i, value in enumerate(quiz.values()):
    print(f"Question {i+1} : {value}")
(Aug-30-2022, 01:02 PM)JonWayn Wrote: [ -> ]given the code snippet:
i = 0

for key, value in quiz.items():
    i += 1
    print(f"Question {str(i)} : {key['question']}")
Line 5 fails with the error code,
Error:
TypeError: string indices must be integers
The variable named 'i' is clearly an integer. Can someone explain why it fails with this error?

full code:
quiz = {
    "question1": {
        "question": "What is the capital of France?",
        "answer": "Paris"
    },
    "question2": {
        "question": "What is the capital of Germany?",
        "answer": "Berlin"
    },
    "question3": {
        "question": "What is the capital of Italy?",
        "answer": "Rome"
    },
    "question4": {
        "question": "What is the capital of England?",
        "answer": "London"
    },
    "question5": {
         "question": "What is the capital of Norway?",
        "answer": "Oslo"
    },
    "question6": {
        "question": "What is the capital of Switzerland?",
        "answer": "Bern"
    },
    "question7": {
        "question": "What is the capital of Austria?",
        "answer": "Vienna"
    },
    "question8": {
        "question": "What is the capital of Spain?",
        "answer": "Madrid"
    },
    "question9": {
        "question": "What is the capital of Portugal?",
        "answer": "Lisbon"
    },
    "question10": {
        "question": "What is the capital of Belgium?",
        "answer": "Brussels"
    },
    "question11": {
        "question": "What is the capital of Sweden?",
        "answer": "Stockholm"
    },
    "question12": {
        "question": "What is the capital of Denmark?",
        "answer": "Copenhagen"
    },
    "question6": {
        "question": "What is the capital of Holland?",
        "answer": "Amsterdam"
    },
}

score = 0
i = 0

for key, value in quiz.items():
    i += 1
    print(f"Question {str(i)} : {value['question']}")
    answer = input("Answer? ")

    if answer.lower() == value['answer'].lower():
        score += 1
        print('Correct!')
    else:
        print("Incorrect :{")
        print("The correct answer is: " + value['answer'])

    print(f"Your score is {score}")
Error:
TypeError: string indices must be integers
I did get it resolved with the help of another reply but thank you for pointing me to the proper usage of the interface. It's pretty awesome
Some advice can simplify the dictionary be using enumerate() then no need to hardcode Question1,Question2....,
then also can remove i = 0.
Also if using function it look cleaner.
Example.
def questions():
   return {
       "What is the capital of France?": 'Paris',
       "What is the capital of Germany? ": 'Berlin',
     }

def quiz(questions):
    score = 0
    for quiz_numb, question in enumerate(questions.keys(), 1):
        answer = input(f'Question.{quiz_numb}\n{question} ')
        if questions[question] == answer:
            print('Correct\n')
            score += 1
        else:
            print(f'Incorrect the answer was: {questions[question]}\n')
    print(f'Total score for this round: {score}')

if __name__ == '__main__':
   quiz(questions())
Output:
Question.1 What is the capital of France? Paris Correct Question.2 What is the capital of Germany? Bern Incorrect the answer was: Berlin Total score for this round: 1
Dictionaries are not a good choice for your quiz. I can accept this as a dictionary:
{
        "question": "What is the capital of France?",
        "answer": "Paris"
    }
But this should be a list.
quiz = {
    "question1": {},
    "question2": {},
    ...
}
Using "questionN" keys just makes it more difficult to access the questions, and forced you to use items().

I would not use dictionaries for either the questions or the quiz. Since neither the question or quiz change I used tuples.
quiz = (
    ("What is the capital of France?", "PARIS")
    ("What is the capital of Germany?", "BERLIN")
)
 
score = 0
for index, question in (quiz):
    q, a = question
    print(f"Question {index+1} : {q}")
    if input("Answer? ").upper() == a:
        score += 1
        print('Correct!')
    else:
        print(f"Incorrect :(\nThe correct answer is: {a}")
 
print(f"Your score is {score}")
(Aug-30-2022, 05:48 PM)deanhystad Wrote: [ -> ]Dictionaries are not a good choice for your quiz. I can accept this as a dictionary:
{
        "question": "What is the capital of France?",
        "answer": "Paris"
    }
But this should be a list.
quiz = {
    "question1": {},
    "question2": {},
    ...
}
Using "questionN" keys just makes it more difficult to access the questions, and forced you to use items().

I would not use dictionaries for either the questions or the quiz. Since neither the question or quiz change I used tuples.
quiz = (
    ("What is the capital of France?", "PARIS")
    ("What is the capital of Germany?", "BERLIN")
)
 
score = 0
for index, question in (quiz):
    q, a = question
    print(f"Question {index+1} : {q}")
    if input("Answer? ").upper() == a:
        score += 1
        print('Correct!')
    else:
        print(f"Incorrect :(\nThe correct answer is: {a}")
 
print(f"Your score is {score}")


Thank you. I like the brevity of code that you implement but I will have to wrap my mind around the logic of its elegance and simplicity
This code:

quiz = (
    ("What is the capital of France?", "PARIS")
    ("What is the capital of Germany?", "BERLIN")
)
  
score = 0
for index, question in (quiz):
    q, a = question
    print(f"Question {index+1} : {q}")
    if input("Answer? ").upper() == a:
        score += 1
        print('Correct!')
    else:
        print(f"Incorrect :(\nThe correct answer is: {a}")
  
print(f"Your score is {score}")
...even with a correction to the syntax (a missing comma in the nested tuple), I can't see how it's going to work.

If I change the code to this:

quiz = (
    ("What is the capital of France?", "PARIS"),
    ("What is the capital of Germany?", "BERLIN")
)
  
score = 0
for index, question in enumerate(quiz):
    q, a = question
    print(f"Question {index+1} : {q}")
    if input("Answer? ").upper() == a:
        score += 1
        print('Correct!')
    else:
        print(f"Incorrect :(\nThe correct answer is: {a}")
  
print(f"Your score is {score}"))
... then yes, it works fine, and is a nice, simple way to do this.
Pages: 1 2