Random quiz generator - python

I have been following an example program from a tutorial book, the program is to take a dictionary with all 50 US states in and their capitals and then to create a random set of multiple choice A-D questions, these questions are then to be randomized and 3 different quizzes printed out into 3 different files. The answers for all the questions for each quiz are then to be printed out into an answers file to go with each questions file.
As a test Im only doing it with a range of 3 for now. When I run the program the files are created but only the 3rd one has the questions in its quiz file and only the 3rd answer file has its answers in too. Files 1 and 2 for the questions have the header section with the blank Name: and Date: but nothing else and their answer files are blank.
I have been over this several times now and can't figure out what the problem is.
Any input would be appreciated, thanks.
import random
# The quiz data. Keys are states and values are their capitals.
capitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau', 'Arizona':'Phoenix',
'Arkansas': 'Little Rock', 'California': 'Sacramento', 'Colorado':'Denver',
'Connecticut': 'Hartford', 'Delaware': 'Dover', 'Florida': 'Tallahassee',
'Georgia': 'Atlanta', 'Hawaii': 'Honolulu', 'Idaho': 'Boise', 'Illinois':
'Springfield', 'Indiana': 'Indianapolis', 'Iowa': 'Des Moines', 'Kansas':
'Topeka', 'Kentucky': 'Frankfort', 'Louisiana': 'Baton Rouge', 'Maine':
'Augusta', 'Maryland': 'Annapolis', 'Massachusetts': 'Boston', 'Michigan':
'Lansing', 'Minnesota': 'Saint Paul', 'Mississippi': 'Jackson', 'Missouri':
'Jefferson City', 'Montana': 'Helena', 'Nebraska': 'Lincoln', 'Nevada':
'Carson City', 'New Hampshire': 'Concord', 'New Jersey': 'Trenton',
'New Mexico': 'Santa Fe', 'New York': 'Albany', 'North Carolina': 'Raleigh',
'North Dakota': 'Bismarck', 'Ohio': 'Columbus', 'Oklahoma': 'Oklahoma City',
'Oregon': 'Salem', 'Pennsylvania': 'Harrisburg', 'Rhode Island': 'Providence',
'South Carolina': 'Columbia', 'South Dakota': 'Pierre', 'Tennessee':
'Nashville', 'Texas': 'Austin', 'Utah': 'Salt Lake City', 'Vermont':
'Montpelier', 'Virginia': 'Richmond', 'Washington': 'Olympia',
'West Virginia': 'Charleston', 'Wisconsin': 'Madison', 'Wyoming': 'Cheyenne'}
# Generate quiz files
for quizNum in range(3):
# Create the quiz and answer key files.
quizFile = open('capitalsquiz%s.txt' % (quizNum + 1), 'w')
answerKeyFile = open('capitalsquiz_answers%s.txt' % (quizNum + 1), 'w')
# Write out the header for the quiz.
quizFile.write('Name:\n\nDate:\n\nPeriod:\n\n')
quizFile.write((' ' * 20) + 'State Capitals Quiz (Form %s)' % (quizNum + 1))
quizFile.write('\n\n')
# Shuffle the order of the states.
states = list(capitals.keys())
random.shuffle(states)
#Loop through all 50 states, making a question for each.
for questionNum in range(50):
# Get right and wrong answers.
correctAnswer = capitals[states[questionNum]]
wrongAnswers = list(capitals.values())
del wrongAnswers[wrongAnswers.index(correctAnswer)]
wrongAnswers = random.sample(wrongAnswers, 3)
answerOptions = wrongAnswers + [correctAnswer]
random.shuffle(answerOptions)
# Write the question and the answer options to the quiz file.
quizFile.write('%s. What is the capital of %s?\n' % (questionNum + 1, states[questionNum]))
for i in range(4):
quizFile.write(' %s. %s\n' % ('ABCD'[i], answerOptions[i]))
quizFile.write('\n')
# Write the answer key to a file.
answerKeyFile.write('%s. %s\n' % (questionNum + 1, 'ABCD'[answerOptions.index(correctAnswer)]))
quizFile.close()
answerKeyFile.close()

Think about the iteration of your loops and the setting of the variables.
Did you mean for the for questionNum in range(50): to be a separate or inner loop to the for quizNum in range(3): loop, this may be an issue of indentation within your pyton file.
When your for questionNum in range(50): loop starts the value of quizFile and answerKeyFile are set to the last in the for quizNum in range(3): hence the writing to only the last file. At the time the for questionNum in range(50): loop starts the for quizNum in range(3): has finished
To solve:
Put your question making loop in your quiz file loop (indentation is the key)
for quizNum in range(3):
...
for questionNum in range(50):

It's because first you iterate over [0,1,2] and create all the files, and then, with quiz 3 open you iterate over writing the actual question/answers.
Put everything under one for questionNum in range(3).
EDIT: I see that it's because of you indentation, you exit the first for loop too soon.
See https://gist.github.com/Noxeus/dcb3898f601ef76fbf8f

I think everytime you call quizfile.write () ,it overwrites the previous text that was inserted in your file because you opened the file in w mode, try opening the file in append mode("a" in open() instead of "w"),it should work out.

Related

Automate The Boring Stuff: Random Quiz Generator

I have been following an example program from a tutorial book, the program is to take a dictionary with all 50 US states in and their capitals and then to create a random set of multiple choice A-D questions, these questions are then to be randomised and 3 different quizzes printed out into 3 different files. The answers for all the questions for each quiz are then to be printed out into an answers file to go with each questions file.
As a test I'm only doing it with a range of 5 for now. When I run the program the program works as intended except only 25 question/answer combos are created for each test, rather than 50.
I have checked it a few times and can't figure out why this is. Any input would be greatly appreciated, thanks.
# randomQuizGenerator.py - Creates quizzes with questions and answers in
# random order, along with the answer key.
import random
capitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau', 'Arizona': 'Phoenix',
'Arkansas': 'Little Rock', 'California': 'Sacramento', 'Colorado': 'Denver',
'Connecticut': 'Hartford', 'Delaware': 'Dover', 'Florida': 'Tallahassee',
'Georgia': 'Atlanta', 'Hawaii': 'Honolulu', 'Idaho': 'Boise', 'Illinois':
'Springfield', 'Indiana': 'Indianapolis', 'Iowa': 'Des Moines', 'Kansas':
'Topeka', 'Kentucky': 'Frankfort', 'Louisiana': 'Baton Rouge', 'Maine':
'Augusta', 'Maryland': 'Annapolis', 'Massachusetts': 'Boston', 'Michigan':
'Lansing', 'Minnesota': 'Saint Paul', 'Mississippi': 'Jackson', 'Missouri':
'Jefferson City', 'Montana': 'Helena', 'Nebraska': 'Lincoln', 'Nevada':
'Carson City', 'New Hampshire': 'Concord', 'New Jersey': 'Trenton',
'New Mexico': 'Santa Fe', 'New York': 'Albany', 'North Carolina': 'Raleigh',
'North Dakota': 'Bismarck', 'Ohio': 'Columbus', 'Oklahoma': 'Oklahoma City',
'Oregon': 'Salem', 'Pennsylvania': 'Harrisburg', 'Rhode Island': 'Providence',
'South Carolina': 'Columbia', 'South Dakota': 'Pierre', 'Tennessee':
'Nashville', 'Texas': 'Austin', 'Utah': 'Salt Lake City', 'Vermont':
'Montpelier', 'Virginia': 'Richmond', 'Washington': 'Olympia',
'West Virginia': 'Charleston', 'Wisconsin': 'Madison', 'Wyoming': 'Cheyenne'}
# Generate 5 quiz files.
for quizNum in range(5):
# Create the quiz and answer key files.
quizFile = open('capitalsquiz%s.txt' % (quizNum+1), 'w')
answerFile = open('capitalsquiz_answers%s.txt' % (quizNum+1), 'w')
# Write out the header for the quiz.
quizFile.write('Capitals Quiz #%s' % (quizNum+1) + '\nName:\nDate:\n\n')
quizFile.write('What is the capital of:\n')
answerFile.write('Capitals Quiz %s' % (quizNum+1) + '\n\n')
# Shuffle the order of the states.
states = list(capitals.keys())
random.shuffle(states)
# Loop through all 50 states, making a question for each.
# set question number = 0
q_num = 0
for st in states:
# question number increase
q_num += 1
random.shuffle(states)
# unused needed for choosing 3 incorrect options
unusedStates = states
# write question number and state name (QUESTION)
quizFile.write('Q%s: ' % q_num + st + '?\n')
# create answer options list and fill with 1 correct answer + 3 incorrect ones
answerOptions = [None] * 3
answerOptions.append(capitals[st])
# remove correct answer to avoid duplication
unusedStates.remove(st)
for Opt in range(0, 3):
curr_ans = unusedStates[Opt]
answerOptions[Opt] = capitals[curr_ans]
# randomise answer list
random.shuffle(answerOptions)
# write answers
for i in range(0, 4):
quizFile.write(answerOptions[i]+' ')
quizFile.write('\n')
# write correct answer in answer file
answerFile.write(capitals[st]+'\n')
quizFile.close()
answerFile.close()
The reason it's happening is because you are modifying your collection while iterating over it:
states = [1,2,3,4,5,6,7,8,9,10]
for st in states:
print(st)
states.remove(st)
This snippet will print out:
1
3
5
7
9
What you have tried is:
unusedStates = states
unusedStates.remove(st)
but this will not copy the list. It will just create another name for the same list.
Here is a slightly changed version, but I am by no means a "Python pro".
import random
capitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau', 'Arizona': 'Phoenix',
'Arkansas': 'Little Rock', 'California': 'Sacramento', 'Colorado': 'Denver',
'Connecticut': 'Hartford'}
states = list(capitals.keys())
random.shuffle(states)
# Loop through all 50 states, making a question for each.
for idx, state in enumerate(states):
# use this for 1-based humans
q_num = idx + 1
# the 49 other states
other_states = states[:idx] + states[idx+1:]
# pick 3 states (guaranteed to be unique)
answer_states = random.sample(other_states, 3)
# add the correct one
answer_states.append(state)
# convert states to capitals
answer_options = [capitals[st] for st in answer_states]
# randomise answer list
random.shuffle(answer_options)
print('Question %s about %s' % (q_num, state))
print('Options', answer_options)
print('Correct Answer', capitals[state])
print() #empty line
Note the use of random.sample to pick 3 unique options, using enumerate to iterate over the list with an index variable.
Also note the creation of a 49-element list using "slicing".
#hlfrmn found the codeculprit - I would like to point out another thing - use the
with open("filename.txt","w") as f:
f.write("something")
approach that autocloses your file even if you encounter exceptions and structure it using functions that perform certain tasks.
The data definition:
capitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau', 'Arizona': 'Phoenix',
'Arkansas': 'Little Rock', 'California': 'Sacramento', 'Colorado': 'Denver',
'Connecticut': 'Hartford', 'Delaware': 'Dover', 'Florida': 'Tallahassee',
'Georgia': 'Atlanta', 'Hawaii': 'Honolulu', 'Idaho': 'Boise', 'Illinois':
'Springfield', 'Indiana': 'Indianapolis', 'Iowa': 'Des Moines', 'Kansas':
'Topeka', 'Kentucky': 'Frankfort', 'Louisiana': 'Baton Rouge', 'Maine':
'Augusta', 'Maryland': 'Annapolis', 'Massachusetts': 'Boston', 'Michigan':
'Lansing', 'Minnesota': 'Saint Paul', 'Mississippi': 'Jackson', 'Missouri':
'Jefferson City', 'Montana': 'Helena', 'Nebraska': 'Lincoln', 'Nevada':
'Carson City', 'New Hampshire': 'Concord', 'New Jersey': 'Trenton',
'New Mexico': 'Santa Fe', 'New York': 'Albany', 'North Carolina': 'Raleigh',
'North Dakota': 'Bismarck', 'Ohio': 'Columbus', 'Oklahoma': 'Oklahoma City',
'Oregon': 'Salem', 'Pennsylvania': 'Harrisburg', 'Rhode Island': 'Providence',
'South Carolina': 'Columbia', 'South Dakota': 'Pierre', 'Tennessee':
'Nashville', 'Texas': 'Austin', 'Utah': 'Salt Lake City', 'Vermont':
'Montpelier', 'Virginia': 'Richmond', 'Washington': 'Olympia',
'West Virginia': 'Charleston', 'Wisconsin': 'Madison', 'Wyoming': 'Cheyenne'}
and code:
import random
def generateAllQuestions(caps):
"""Generates all questions including 3 wrong answers. Returns a list of
[tuple(state,correct) and list of 3 wrong answers]."""
q = []
for state in capitals:
# get 4 other answers
# remove the correct one if it is inside the random sample
# use only 3 of them
others = [ val for key,val in random.sample(capitals.items(),k=4) if key != state][0:3]
# compile [tuple: (item,correct_answer),[other_answers]]
q.append([(state,capitals[state])] + [others])
return q
def partitionIntoNParts(n,data):
"""Takes the data and partiniones it into n random equally long (if possible)
sublists"""
ld = len(data)
size_part = ld // n
idx = 0
random.shuffle(data)
while idx < ld:
yield data[idx:idx + size_part]
idx += size_part
def writeHeader(f,a,n):
"""Write the header for Q and A file"""
a.write(f"Capitals Quiz #{n+1}\n\n")
f.write(f"Capitals Quiz #{n+1}\nName:\nDate:\n\nWhat is the capital of:\n")
def writeQandA(f,a,q_num,q):
"""Write a single questions into Q-file and a single answer into A-file"""
state,correct = q[0] # the tuple
others = q[1] # the others
a.write(f"{q_num+1:>3}.) {state:<14} : {correct}\n")
f.write(f"{q_num+1:>3}.) {state:<14} : ")
solutions = others + [correct]
random.shuffle(solutions) # use sort() to always get alphabetical order
for town in solutions:
f.write(f"[ ] {town:<14} ")
f.write("\n\n")
# how many files to use?
filecount = 5
qs = generateAllQuestions(capitals)
parts = partitionIntoNParts(filecount,qs)
# write files based on partioning
for idx,content in enumerate(parts):
with open(f"capitalsquiz{idx+1}.txt","w") as quiz_file,\
open(f"capitalsquiz{idx+1}_answers.txt","w") as answ_file:
writeHeader(quiz_file,answ_file,idx)
# write Q and A into file
for q_num,q in enumerate(content):
writeQandA(quiz_file,answ_file,q_num,q)
# check one files content:
print(open("capitalsquiz2.txt").read())
print(open("capitalsquiz2_answers.txt").read())
Content of capitalsquiz2.txt:
Capitals Quiz #2
Name:
Date:
What is the capital of:
1.) Oklahoma : [ ] Oklahoma City [ ] Phoenix [ ] Juneau [ ] Olympia
2.) Virginia : [ ] Austin [ ] Pierre [ ] Saint Paul [ ] Richmond
3.) North Carolina : [ ] Raleigh [ ] Tallahassee [ ] Dover [ ] Harrisburg
4.) Montana : [ ] Helena [ ] Raleigh [ ] Hartford [ ] Madison
5.) Alaska : [ ] Nashville [ ] Albany [ ] Juneau [ ] Lansing
6.) Kentucky : [ ] Charleston [ ] Cheyenne [ ] Frankfort [ ] Oklahoma City
7.) Florida : [ ] Trenton [ ] Pierre [ ] Tallahassee [ ] Honolulu
8.) Rhode Island : [ ] Providence [ ] Madison [ ] Santa Fe [ ] Trenton
9.) Arkansas : [ ] Boston [ ] Little Rock [ ] Harrisburg [ ] Denver
10.) Wisconsin : [ ] Montgomery [ ] Pierre [ ] Madison [ ] Richmond
Content of capitalsquiz2_answers.txt`:
Capitals Quiz #1
1.) Oklahoma : Oklahoma City
2.) Virginia : Richmond
3.) North Carolina : Raleigh
4.) Montana : Helena
5.) Alaska : Juneau
6.) Kentucky : Frankfort
7.) Florida : Tallahassee
8.) Rhode Island : Providence
9.) Arkansas : Little Rock
10.) Wisconsin : Madison
Hehe... I also had some fun restructuring your program. Maybe you can learn a thing or two from this.
import random
capitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau', 'Arizona': 'Phoenix',
'Arkansas': 'Little Rock', 'California': 'Sacramento', 'Colorado': 'Denver',
'Connecticut': 'Hartford', 'Delaware': 'Dover', 'Florida': 'Tallahassee',
'Georgia': 'Atlanta', 'Hawaii': 'Honolulu', 'Idaho': 'Boise', 'Illinois':
'Springfield', 'Indiana': 'Indianapolis', 'Iowa': 'Des Moines', 'Kansas':
'Topeka', 'Kentucky': 'Frankfort', 'Louisiana': 'Baton Rouge', 'Maine':
'Augusta', 'Maryland': 'Annapolis', 'Massachusetts': 'Boston', 'Michigan':
'Lansing', 'Minnesota': 'Saint Paul', 'Mississippi': 'Jackson', 'Missouri':
'Jefferson City', 'Montana': 'Helena', 'Nebraska': 'Lincoln', 'Nevada':
'Carson City', 'New Hampshire': 'Concord', 'New Jersey': 'Trenton',
'New Mexico': 'Santa Fe', 'New York': 'Albany', 'North Carolina': 'Raleigh',
'North Dakota': 'Bismarck', 'Ohio': 'Columbus', 'Oklahoma': 'Oklahoma City',
'Oregon': 'Salem', 'Pennsylvania': 'Harrisburg', 'Rhode Island': 'Providence',
'South Carolina': 'Columbia', 'South Dakota': 'Pierre', 'Tennessee':
'Nashville', 'Texas': 'Austin', 'Utah': 'Salt Lake City', 'Vermont':
'Montpelier', 'Virginia': 'Richmond', 'Washington': 'Olympia',
'West Virginia': 'Charleston', 'Wisconsin': 'Madison', 'Wyoming': 'Cheyenne'}
quiz_answer_template = '''\
Capitals Quiz #{}
{}
'''
quiz_file_template = '''\
Capitals Quiz #{}
Name:
Date:
What is the capital of?
{}
'''
question_template = '''\
Q{} {}?
{}
'''
def create_answer_file(path, question_id, answers):
with open(path, 'w') as f:
s = quiz_answer_template.format(question_id, answers)
f.write(s)
def create_quiz_file(path, question_id, question_and_options):
with open(path, 'w') as f:
s = quiz_file_template.format(question_id, question_and_options)
f.write(s)
def get_quiz(dictionary, n):
"""Based on a dictionary with key and values will return
1) Questions with 4 options tab-separated as a string
2) Correct answers as a string
"""
output = []
states = list(dictionary.keys())
random.shuffle(states)
correct_answers = [dictionary.get(i) for i in states]
for ind, st in enumerate(states[:n], 1):
d = dictionary.copy()
correct_answer = d.pop(st)
incorrect_answers = list(d.values())
random.shuffle(incorrect_answers)
options = [correct_answer] + incorrect_answers[:3]
random.shuffle(options)
output.append(question_template.format(ind, st, '\t'.join(options)))
return '\n'.join(output), '\n'.join(correct_answers)
for quizNum in range(1, 6):
questions_and_options, answers = get_quiz(capitals, n=50)
create_quiz_file(f'capitalsquiz{quizNum}.txt', quizNum, questions_and_options)
create_answer_file(f'capitalsquiz_answers{quizNum}.txt', quizNum, answers)

How would i go about randomizing the questions for this game? [duplicate]

This question already has answers here:
Shuffling a list of objects
(25 answers)
Closed 5 years ago.
for a homework assignment, i'm trying to make a game that quizzes users on the capitals of each state, kind of like a flashcards game. I've satisfied all requirements for the program with the code below except they want the questions to be in a random order. how can i shuffle the dictionary?
I know how to shuffle a list but not a dictionary, as i thought they were already supposed to be in a random order.. yet i get the questions in the same order i typed the keys/values (alphabetical by state)
flashcards = {'ALABAMA': 'MONTGOMERY',
'ALASKA': 'JENEAU',
'ARIZONA': 'PHOENIX',
'ARKANSAS': 'LITTLE ROCK',
'CALIFORNIA': 'SACRAMENTO',
'COLORADO': 'DENVER',
'CONNECTICUT': 'HARTFORD',
'DELAWARE': 'DOVER',
'FLORIDA': 'TALLAHASSEE',
'GEORGIA': 'ATLANTA',
'HAWAII': 'HONOLULU',
'IDAHO': 'BOISE',
'ILLINOIS': 'SPRINGFIELD',
'INDANA': 'INDIANAPOLIS',
'IOWA': 'DES MOINES',
'KANSAS': 'TOPEKA',
'KENTUCKY': 'FRANKFORT',
'LOUISIANA': 'BATON ROUGE',
'MAINE': 'AUGUSTA',
'MARYLAND': 'ANNAPOLIS',
'MASSACHUSETTS': 'BOSTON',
'MICHIGAN': 'LANSING',
'MINNESOTA': 'ST. PAUL',
'MISSISSIPPI': 'JACKSON',
'MISSOURI': 'JEFFERSON CITY',
'MONTANA': 'HELENA',
'NEBRASKA': 'LINCOLN',
'NAVADA': 'CARSON CITY',
'NEW HAMPSHIRE': 'CONCORD',
'NEW JERSEY': 'TRENTON',
'NEW MEXICO': 'SANTA FE',
'NEW YORK': 'ALBANY',
'NORTH CAROLINA': 'RALEIGH',
'NORTH DAKOTA': 'BISMARCK',
'OHIO': 'COLUMBUS',
'OKLAHOMA': 'OKLAHOMA CITY',
'OREGON': 'SALEM',
'PENNSYLVANIA': 'HARRISBURG',
'RHODE ISLAND': 'PROVIDENCE',
'SOUTH CAROLINA': 'COLUMBIA',
'SOUTH DAKOTA': 'PIERRE',
'TENNESSEE': 'NASHVILLE',
'TEXAS': 'AUSTIN',
'UTAH': 'SALT LAKE CITY',
'VERMONT': 'MONTPELIER',
'VIRGINIA': 'RICHMOND',
'WASHINTON': 'OLYMPIA',
'WEST VIRGINIA': 'CHARLESTON',
'WISCONSIN': 'MADISON',
'WYOMING': 'CHEYENNE'}
def main():
incorrect = 0
correct = 0
print('Let\'s play the State\'s game!!')
for b in flashcards.keys():
question = input('What is the capital of ' + b +'? : ')
if question.upper() == flashcards[b].upper():
correct += 1
print('correct!!')
print('Correct: ', correct)
print('Incorrect: ', incorrect)
else:
incorrect += 1
print('oops! that is incorrect')
print('Correct: ', correct)
print('Incorrect: ', incorrect)
main()
Use random.shuffle
from random import shuffle
states = flashcards.keys()
shuffle(states)
for state in states:
print 'State: {}, Capital: {}'.format(state, flashcards[state])

Why quizfile.write(" ") is not working from the Second for loop

I got this question Automate the boring Stuff book. The Code is also given there but When I was Practising this on my own the problem I am getting is this code is not writing in the files after the first for loop.
import random
import os
capitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau', 'Arizona': 'Phoenix',
'Arkansas': 'Little Rock', 'California': 'Sacramento', 'Colorado': 'Denver',
'Connecticut': 'Hartford', 'Delaware': 'Dover', 'Florida': 'Tallahassee',
'Georgia': 'Atlanta', 'Hawaii': 'Honolulu', 'Idaho': 'Boise', 'Illinois':
'Springfield', 'Indiana': 'Indianapolis', 'Iowa': 'Des Moines', 'Kansas':
'Topeka', 'Kentucky': 'Frankfort', 'Louisiana': 'Baton Rouge', 'Maine':
'Augusta', 'Maryland': 'Annapolis', 'Massachusetts': 'Boston', 'Michigan':
'Lansing', 'Minnesota': 'Saint Paul', 'Mississippi': 'Jackson', 'Missouri':
'Jefferson City', 'Montana': 'Helena', 'Nebraska': 'Lincoln', 'Nevada':
'Carson City', 'New Hampshire': 'Concord', 'New Jersey': 'Trenton',
'New Mexico': 'Santa Fe', 'New York': 'Albany', 'North Carolina': 'Raleigh',
'North Dakota': 'Bismarck', 'Ohio': 'Columbus', 'Oklahoma': 'Oklahoma City',
'Oregon': 'Salem', 'Pennsylvania': 'Harrisburg', 'Rhode Island': 'Providence',
'South Carolina': 'Columbia', 'South Dakota': 'Pierre', 'Tennessee':
'Nashville', 'Texas': 'Austin', 'Utah': 'Salt Lake City', 'Vermont':
'Montpelier', 'Virginia': 'Richmond', 'Washington': 'Olympia',
'West Virginia': 'Charleston', 'Wisconsin': 'Madison', 'Wyoming': 'Cheyenne'}
#print (capitals)
for q in range(35):
quizfile = open("capitalquiz%s.txt" %(q + 1), 'w')
answerfile = open("Answerfile%s.txt"%(q + 1),'w')
quizfile.write('Name:\n\nDate:\n\nPeriod:\n\n')
quizfile.write((' ' * 20) + 'State Capitals Quiz (Form %s)' % (q + 1))
quizfile.write('\n\n')
states = list(capitals.keys())
random.shuffle(states)
quizfile.write("wefkjqennqkeanfeqkjn")
for i in range(50):
correct_answer = capitals[states[i]]
wrong_answer = list(capitals.values())
del wrong_answer[correct_answer.index(correct_answer)]
wrong_answers = random.sample(wrong_answer,3)
answer_option = wrong_answers + [correct_answer]
random.shuffle(answer_option)
for item in range(50):
#quizfile.write("******************************************************")
quizfile.write("%s.what is the capital of %s" %(item+1,states[item]))
for i in range(4):
quizfile.write("%s. %s\n" %('ABCD'[i],answer_option[i]))
answerfile.write("%s. %s\n" %(q+1,'ABCD'[answer_option.index(correct_answer)]))
quizfile.close()
answerfile.close()
You've got some for loops that need to be nested within others. You're attempting to access out of scope variables as it is now.
Your code, cleaned up:
import random
import os
capitals = {'Alabama': 'Montgomery', 'Alaska': 'Juneau', 'Arizona': 'Phoenix',
'Arkansas': 'Little Rock', 'California': 'Sacramento', 'Colorado': 'Denver',
'Connecticut': 'Hartford', 'Delaware': 'Dover', 'Florida': 'Tallahassee',
'Georgia': 'Atlanta', 'Hawaii': 'Honolulu', 'Idaho': 'Boise', 'Illinois':
'Springfield', 'Indiana': 'Indianapolis', 'Iowa': 'Des Moines', 'Kansas':
'Topeka', 'Kentucky': 'Frankfort', 'Louisiana': 'Baton Rouge', 'Maine':
'Augusta', 'Maryland': 'Annapolis', 'Massachusetts': 'Boston', 'Michigan':
'Lansing', 'Minnesota': 'Saint Paul', 'Mississippi': 'Jackson', 'Missouri':
'Jefferson City', 'Montana': 'Helena', 'Nebraska': 'Lincoln', 'Nevada':
'Carson City', 'New Hampshire': 'Concord', 'New Jersey': 'Trenton',
'New Mexico': 'Santa Fe', 'New York': 'Albany', 'North Carolina': 'Raleigh',
'North Dakota': 'Bismarck', 'Ohio': 'Columbus', 'Oklahoma': 'Oklahoma City',
'Oregon': 'Salem', 'Pennsylvania': 'Harrisburg', 'Rhode Island': 'Providence',
'South Carolina': 'Columbia', 'South Dakota': 'Pierre', 'Tennessee':
'Nashville', 'Texas': 'Austin', 'Utah': 'Salt Lake City', 'Vermont':
'Montpelier', 'Virginia': 'Richmond', 'Washington': 'Olympia',
'West Virginia': 'Charleston', 'Wisconsin': 'Madison', 'Wyoming': 'Cheyenne'}
for q in range(35):
quizfile = open("capitalquiz%s.txt" %(q + 1), 'w')
answerfile = open("Answerfile%s.txt"%(q + 1),'w')
quizfile.write('Name:\n\nDate:\n\nPeriod:\n\n')
quizfile.write((' ' * 20) + 'State Capitals Quiz (Form %s)' % (q + 1))
quizfile.write('\n\n')
states = list(capitals.keys())
random.shuffle(states)
for i in range(50):
correct_answer = capitals[states[i]]
wrong_answer = list(capitals.values())
del wrong_answer[correct_answer.index(correct_answer)]
wrong_answers = random.sample(wrong_answer,3)
answer_option = wrong_answers + [correct_answer]
random.shuffle(answer_option)
quizfile.write("%s.what is the capital of %s \n" %(i+1,states[i]))
for j in range(4):
quizfile.write("%s. %s\n" %('ABCD'[j],answer_option[j]))
quizfile.write('\n')
answerfile.write("%s. %s\n" %(i+1,'ABCD'[answer_option.index(correct_answer)]))
quizfile.close()
answerfile.close()
It's not the prettiest but I think it does what you're trying to do.

Webscraping with Xpath in Python

From what I've seen the method to derive a path for Xpath to scrape a page is not totally clear to me. I'm trying to use Xpath in python to scrape the wikipedia article for states and capitals to get a list of states and a list of capitals, but so far I've had no luck when trying to figure out the correct path to use. I've tried inspecting the element and copying the Xpath there but I still have had no luck. I'm looking for someone to explain a method to figure out the correct xpath to use to grab certain elements in a page.
from lxml import html
import requests
page = requests.get('https://en.wikipedia.org/wiki/List_of_capitals_in_the_United_States')
tree = html.fromstring(page.text)
#creating list of states
state = tree.xpath('xpath')
#list of capitals
capital = tree.xpath('xpath')
print 'State: ', state
print 'Capital: ', capital
Two of the xpaths I've tried so far have been:
//*[#id="mw-content-text"]/table[1]/tbody/tr[1]/td[1]/a
//*[#id="mw-content-text"]/table[1]/tbody/tr[1]/td[2]
Start with an expression that will get you the table. Here's one that works:
>>> tree.xpath('//div[#id="mw-content-text"]/table[1]')
[<Element table at 0x7f9dd7322578>]
You want the first table in that div (hence the [1]) and there does not appear to be a tbody element there.
You could iterate over the rows in that table like this:
for row in tree.xpath('//div[#id="mw-content-text"]/table[1]/tr')[1:]:
Within that loop, the state name is:
row[0][0].text
That is the first child of the row (which is a <td> element), and then first child of that (which is an <a> element), and then the text content of that element.
And the capital is:
row[3][0].text
So:
>>> for row in tree.xpath('//div[#id="mw-content-text"]/table[1]/tr')[1:]:
... st = row[0][0].text
... cap = row[3][0].text
... print 'The capital of %s is %s' % (st, cap)
The capital of Alabama is Montgomery
The capital of Alaska is Juneau
The capital of Arizona is Phoenix
[...]
You can get all the state names like this:
>>> tree.xpath('//div[#id="mw-content-text"]/table[1]/tr/td[1]/a/text()')
['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']

variable in if statement not defined(again)

This is the code that I am having problems with, it only works when there is a state put in. I need it to work when there is a state put in and when a state and a city are put in. Really all I need is someone to help me with the variable.
import urllib2
num = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
capitals = {'Alabama': 'Montgomery',
'Alaska': 'Juneau',
'Arizona': 'Phoenix',
'Arkansas': 'Little Rock',
'California': 'Sacramento',
'Colorado': 'Denver',
'Connecticut': 'Hartford',
'Delaware': 'Dover',
'Florida': 'Tallahassee',
'Georgia': 'Atlanta',
'Hawaii': 'Honolulu',
'Idaho': 'Boise',
'Illinois': 'Springfield',
'Indiana': 'Indianapolis',
'Iowa': 'Des Moines',
'Kansas': 'Topeka',
'Kentucky': 'Frankfort',
'Louisiana': 'Baton Rouge',
'Maine': 'Augusta',
'Maryland': 'Annapolis',
'Massachusetts': 'Boston',
'Michigan': 'Lansing',
'Minnesota': 'St. Paul',
'Mississippi': 'Jackson',
'Missouri': 'Jefferson City',
'Montana': 'Helena',
'Nebraska': 'Lincoln',
'Nevada': 'Carson City',
'New Hampshire': 'Concord',
'New Jersey': 'Trenton',
'New Mexico': 'Santa Fe',
'New York': 'Albany',
'North Carolina': 'Raleigh',
'North Dakota': 'Bismark',
'Ohio': 'Columbus',
'Oklahoma': 'Oklahoma City',
'Oregon': 'Salem',
'Pennsylvania': 'Harrisburg',
'Rhode Island': 'Providence',
'South Carolina': 'Columbia',
'South Dakota': 'Pierre',
'Tennessee': 'Nashville',
'Texas': 'Austin',
'Utah': 'Salt Lake City',
'Vermont': 'Montpelier',
'Virgina': 'Richmond',
'Washington': 'Olympia',
'West Virgina': 'Charleston',
'Wisconsin': 'Madison',
'Wyoming': 'Cheyenne'}
states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida',
'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine',
'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska',
'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio',
'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas',
'Utah', 'Vermont', 'Virgina', 'Washington','West Virgina', 'Wisconsin', 'Wyoming']
def make_word(words):
result = ""
for i in words:
result += i
return result
while 1:
a = raw_input('Put in a place: ')
a = a.lower()
y = a.replace(' ', '%20')
a = list(a)
a[0] = a[0].upper()
a = ''.join(a)
num = 0
cap = 0
for key in capitals:
if key == a:
page = urllib2.urlopen('http://woeid.rosselliot.co.nz/lookup/%s' % capitals[key]).read()
cap = capitals[key]
num += 1
if a in states:
f = page.find(cap)
if f != -1:
start = page.find('data-center_long="', f) + 18
end = page.find('"', start)
start1 = page.find('data-center_lat="', end) + 17
end1 = page.find('"', start1)
print '%s Latitude: %s Longitude: %s' % (a, page[start1:end1], page[start:end])
else:
for b in states:
l = len(b) + 1
f = a.find(b)
if f != -1:
f = len(a[f:])
f = len(a) - f
f = a[:f]
page = urllib2.urlopen('http://woeid.rosselliot.co.nz/lookup/%s' % f).read()
start = page.find('data-center_long="', f) + 18
end = page.find('"', start)
start1 = page.find('data-center_lat="', end) + 17
end1 = page.find('"', start1)
print '%s Latitude: %s Longitude: %s' % (a, page[start1:end1], page[start:end])
This says the variable is not defined but I need the code to stay like this or else it most likely won't work. Can someone give me a helpful hint or an answer?
f variable is declared inside if a in states. So, if a in states condition evaluates to False, f will not be defined.

Categories

Resources