Reputation: 47
I'm doing this assignment but keep getting the error IndexError: list index out of range. It involves splitting up a CSV file by "," and moving it into a dictionary.
for line in f:
parts=line.split(",")
quiz[parts[0]]=[parts[1],parts[2].strip("\n")]
FULL CODE:
quiz={}
f=open("questions.txt","r")
quiz=f.readline()
for line in f:
parts=line.split(",")
quiz[parts[0]]=[parts[1],parts[2].strip("\n")]
for i in range(10):
print(quiz)
ans=input("Input your answer")
if ans==quiz[parts[4]]:
print("Correct!")
else:
print("Nope, the answer is")
f.close()
I expected the CSV file to be split up and in the dictionary, but instead it came up with the error message
quiz[parts[0]]=[parts[1],parts[2].strip("\n")]
IndexError: list index out of range
Here is questions.txt:
Which birthstone is associated with the month of May?,Diamond,Ruby,Emerald,Sapphire,
C
Which two colours as on the flag of Poland?,Red and Green, Blue and White, Green and White, Red and White,
D
Also, if possible I'm looking to solve this problem without the csv library but if it's easier with then that's fine
Upvotes: 0
Views: 504
Reputation: 51653
IndexError occure if you access a list beyond its content:
a = [1,2,3]
print(a[99]) # IndexError, has only indexes 0,1,2
You can catch the error:
try:
print(a[99])
except IndexError:
print("Item doesnot exist") # this is printed
or check your list first:
if len(a)>=100:
print(a[99]) # would avoid the error
Reading CSV often gets this kind of error if data is not of equal lenght or if you read the line after the last \n and it is empty - and you split/access it non the less.
You might want to restructure your code a bit and use namedtuples for more clarity:
Create the data:
q = "questions.txt"
with open(q,"w") as f:
f.write("""Which birthstone is associated with the month of May?,Diamond,Ruby,Emerald,Sapphire,
C
Which two colours as on the flag of Poland?,Red and Green, Blue and White, Green and White, Red and White,
D
""") # your problem is probably here, line is read and split and accessed on [0] etc.
# it has no data in it -> IndexError
The quiz-code:
from collections import namedtuple
QuizRecord = namedtuple('Quiz', 'question,a1,a2,a3,a4,solution')
# this creates a namedtuple with fields for
# question
# a(nswer)1 a(nswer)2 a(nswer)3 a(nswer)4
# solution
Q = []
pos = {"A":1, "B":2, "C":3, "D":4} # map solution letter to position in parts,
# 0 would be the question
with open(q) as f:
for line in f:
parts=line.strip("\n,").split(",")
if not parts:
print("Done reading lines")
break # done reading
# get the next line and get the correct solution from parsed parts
sol = pos.get(next(f).strip("\n,"),-1)
if sol == -1:
print("Done reading lines")
break # done reading
# add a new namedtuple to our quizzes
parts.append(parts[sol]) # add solution as text to ease comparisons
Q.append(QuizRecord._make(parts)) # add a new namedtuple to Q using parts
for question, a1, a2, a3, a4, sol in Q:
print(question)
print("Solutions: ", ' '.join( (a1,a2,a3,a4) ))
ans = input("Input your answer: ").lower()
if ans == sol.lower():
print("Correct!\n")
else:
print(f"Nope, the answer is {sol}\n")
Output:
Which birthstone is associated with the month of May?
Solutions: Diamond Ruby Emerald Sapphire
Input your answerEmerald
Correct!
Which two colours as on the flag of Poland?
Solutions: Red and Green Blue and White Green and White Red and White
Input your answerRed and Green
Nope, the answer is Red and White
Documentation:
Upvotes: 0
Reputation: 45
How many columns are in your input csv? Is it formatted correctly? Can you include it here?
Instead of readline, I would suggest using the csv library, specifically the DictReader function. This will read in the csv directly into a dictionary:
import csv
with open('names.csv') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(row['first_name'], row['last_name'])
f.close()
replacing first_name
and last_name
with your respective column headings.
Edit:
Just saw your notice about not using the csv library. Looks like there are no line breaks or headers in your csv, so you can try:
with open('questions.txt') as f:
for line in f:
csvvalues = line.split(',')
print(csvvalues)
This should print out the value you're reading in and then you can assign them to a key in a dictionary:
csvdict = {
'csv_info_one': csvvalue[0]
}
I am making a guess that the last value in the csv row refers to the question index, so this should work for a good dictionary structure:
with open('questions.txt') as f:
questions = {}
for line in f:
csvvalues = line.split(',')
csvvalues = [x.rstrip() for x in csvvalues]
questions[csvvalues[-1]] = {
'Q' : csvvalues[0],
'A' : csvvalues[1:len(csvvalues)-1]
}
print(questions)
This makes the assumptions that the question index is the last value in the csv row, and the question is the first, and the possible answers are the remainder of the values between first and last.
Upvotes: 1