Related
I have two lists of city and country names, and I would like to check which city belong to which country. What is the easiest way to achieve that in python?
Please note that I have used till now GeoText to extract city and country names from a test but it doesn't tell me which city belongs to which country.
The problem can't be solved manually because the lists are long.
E.G.
country_list = ['china', 'india', 'canada', 'america', ...]
city_list = ['Mocoa', 'March', 'San Miguel', 'Neiva', 'Naranjito', 'San Fernando',
'Alliance', 'Progreso', 'NewYork', 'Toronto', ...]
you can try this code
import requests
import re
city_list = ['Jerusalem', 'Tel-Aviv', 'New York', 'London', 'Madrid', 'Alliance',
'Mocoa', 'March', 'San Miguel', 'Neiva', 'Naranjito', 'San Fernando',
'Alliance', 'Progreso', 'NewYork', 'Toronto']
city_country_dict = {}
country_city_dict = {}
for city in city_list:
response = requests.request("GET", f"https://www.geonames.org/search.html?q={city}&country=")
country = re.findall("/countries.*\.html", response.text)[0].strip(".html").split("/")[-1]
if country not in country_city_dict:
country_city_dict[country] = [city]
else:
country_city_dict[country].append(city)
city_country_dict[city] = country
this code make request to geoname with city name and than search for the first link to country, you can change this and use beautifulsoup to make it more elegant.
if you run this code on large list notice that it takes time because he wait for response from geoname!
example output:
city_country_dict = {'Jerusalem': 'israe', 'Tel-Aviv': 'israe', 'New York': 'united-states', 'London': 'united-kingdo', 'Madrid': 'spain', 'Alliance': 'united-states', 'Mocoa': 'colombia', 'March': 'switzerland', 'San Miguel': 'el-salvador', 'Neiva': 'colombia', 'Naranjito': 'puerto-rico', 'San Fernando': 'trinidad-and-tobago', 'Progreso': 'honduras', 'NewYork': 'united-kingdo', 'Toronto': 'canada'}
country_city_dict = {'israe': ['Jerusalem', 'Tel-Aviv'], 'united-states': ['New York', 'Alliance', 'Alliance'], 'united-kingdo': ['London', 'NewYork'], 'spain': ['Madrid'], 'colombia': ['Mocoa', 'Neiva'], 'switzerland': ['March'], 'el-salvador': ['San Miguel'], 'puerto-rico': ['Naranjito'], 'trinidad-and-tobago': ['San Fernando'], 'honduras': ['Progreso'], 'canada': ['Toronto']}
You can prepare a python script that will fetch the city info via one of the free APIs.
One of the options that I recommend is https://tequila.kiwi.com provided by Kiwi.com for free. You can and query their Locations API with 'term' parameter, which will give you the full details of the city that has the highest rank, based on search volume. One of the parameters of the returned database entry is the country.
In Python and Selenium, I'm populating a form, submitting it, then scraping the resulting multi-page table that appears on the page underneath the form. After I scrape every page of this table, I reset the form and attempt to repopulate the form. However, a drop down menu is tripping up the code.
I've tried to make the driver wait for the drop down menu to reappear after I reset the form, but this doesn't help. I still receive the StaleReferenceElementException error on the if option.text == state line:
StaleElementReferenceException: Message: The element reference of <option> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed
How do I submit the form over and over for different options within the drop down menu?
states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
'Colorado', 'Connecticut', 'Delaware', 'District of Columbia',
'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']
# Construct browser and link
browser = webdriver.Firefox(executable_path='/usr/local/bin/geckodriver')
url = 'https://myaccount.rid.org/Public/Search/Member.aspx'
ignored_exceptions = (StaleElementReferenceException,)
# Navigate to link
browser.get(url)
try:
# For each state
for state in states:
print('Searching ' + state)
# Set category and select state menu
category = Select(browser.find_element_by_name('ctl00$FormContentPlaceHolder$Panel$categoryDropDownList'))
category.select_by_value('a027b6c0-07bb-4301-b9b5-1b38dcdc59b6')
state_menu = Select(WebDriverWait(browser, 10, ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located((By.ID, 'FormContentPlaceHolder_Panel_stateDropDownList'))))
options = state_menu.options
for option in options:
if option.text == state:
state_menu.select_by_value(option.get_attribute('value'))
browser.find_element_by_name('ctl00$FormContentPlaceHolder$Panel$searchButtonStrip$searchButton').click()
# Scrape the first page of results
results = []
curr_page = 1
onFirstPage = True
scrape_page(curr_page)
# Reset form
browser.find_element_by_name('ctl00$FormContentPlaceHolder$Panel$searchButtonStrip$resetButton').click()
break
finally:
pass
The moment you select the option, element references will update and you can't use the older references. Reason you are getting the exception is, you are trying to get the attribute from the option which no longer valid.
Rather using the iteration, I would use the xpath to select the option as shown below
state_menu = WebDriverWait(browser, 10, ignored_exceptions=ignored_exceptions).until(EC.presence_of_element_located((By.ID, 'FormContentPlaceHolder_Panel_stateDropDownList')))
#options = state_menu.options <== replace this line with below line
option = state_menu.find_element_by_xpath("//option[.='" + state + "']")
#for option in options: <== remove this line
# if option.text == state: <== remove this
option.click()
browser.find_element_by_name('ctl00$FormContentPlaceHolder$Panel$searchButtonStrip$searchButton').click()
# Scrape the first page of results
results = []
curr_page = 1
onFirstPage = True
scrape_page(curr_page)
# Reset form
browser.find_element_by_name('ctl00$FormContentPlaceHolder$Panel$searchButtonStrip$resetButton').click()
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)
Here is the code:
import requests
import bs4
response = requests.get('http://discoverygc.com/forums/serverinterface.php?action=players_online') #Loads page
soup = bs4.BeautifulSoup(response.text)
table = soup.find("div", {"id": "forum"})
rowsNo = (str(table).count('<tr>') - 2) #Number of players online. Minus 2 to remove leading title and column description rows
players = systems = [] #Define lists
for i in range(3, (rowsNo + 3)):
rows = table.findAll('tr')[i]
cols = rows.findAll('td')
player = cols[0].get_text()
system = cols[1].get_text()
players.append(player)
systems.append(system)
print(players)
print(systems)
If I remove either players.append(player) or systems.append(system) the code works fine and outputs the correct list:
['-Vasqez-', '[-=XTF=-]Neon.Bunny-[R]', "[SV]-Valley'", '<-JohnyWalker->', '~VP)Bad.Tibira', 'Alkanius', 'Apex91', 'Araroba', 'Baldor', 'Benediction', 'Black_Bird', 'Boost', 'Caelius.Moya[X]', 'Core|APM-Maverick', 'Daftwagen', 'Dee.Leers', 'Emiko:Hayashi', 'Gamma-6', 'Gauri', 'Gigi.7', 'GMG|GTS-Komahashi-Maru', 'Grawmod', 'GrazySlon', 'Hunor', 'Jakob-Schleiter', 'Joyita', 'Judge_BigJo', 'JulyJalwa', 'Kruger|KMS-Lankow', 'Luxor', 'monitor91', 'Morgulis', 'Nuggets', 'OSI-Mendes', 'Ronny.Rochester', 'Samura|-Arata', 'Samura|-Ichikawa', 'Shpritzen', 'Stardrifter', 'The_Altair', 'The.Liner.of.Dreams', 'Tony.Sosa', 'Wilde.RNC-Nestor']
or:
['Omega-11', 'Omega-49', 'Pennsylvania', 'Magellan', 'Omicron Gamma', 'Kyushu', 'Pennsylvania', 'Kyushu', 'Omega-5', 'Manchester', 'Cassini', 'Newcastle', 'Connecticut', 'Omega-47', 'Stuttgart', 'Stuttgart', 'Munich', 'New York', 'Hudson', 'Sigma-13', 'Languedoc', 'Colorado', 'Virginia', 'Stuttgart', 'New London', 'Magellan', 'New York', 'New Tokyo', 'Manchester', 'New York', 'Pennsylvania', 'Omega-3', 'Omega-49', 'New Berlin', 'California', 'Nagano', 'New Berlin', 'Okinawa', 'Magellan', 'Texas', 'Ontario', 'New Berlin', 'Stuttgart']
However if I put both lines in it mixes the two together for both lists:
['-Vasqez-', 'Omega-11', "[SV]-Valley'", 'Omega-49', '<-JohnyWalker->', 'Pennsylvania', '=Z=Exositas', 'Magellan', '~VP)Death.Incarnator', 'Omicron Gamma', 'Alkanius', 'Shikoku', 'Apex91', 'Pennsylvania', 'Baldor', 'Kyushu', 'Benediction', 'Omega-5', 'Black_Bird', 'Manchester', 'Boost', 'Cassini', 'Caelius.Moya[X]', 'Connecticut', 'Core|APM-Maverick', 'Omega-47', 'Daftwagen', 'Stuttgart', 'Darf.Acour', 'Texas', 'Dee.Leers', 'New Berlin', 'Emiko:Hayashi', 'Munich', 'Gamma-6', 'New York', 'Gauri', 'Hudson', 'Gigi.7', 'Orkney', 'GMG|GTS-Komahashi-Maru', 'Colorado', 'Grawmod', 'Virginia', 'GrazySlon', 'Stuttgart', 'Hunor', 'Manchester', 'Jakob-Schleiter', 'New Berlin', 'Joyita', 'Magellan', 'Judge_BigJo', 'New York', 'Kruger|KMS-Lankow', 'New Tokyo', 'Luxor', 'Manchester', 'monitor91', 'New York', 'Morgulis', 'Pennsylvania', 'Nuggets', 'Omega-3', 'OSI-Mendes', 'Omega-49', 'Ronny.Rochester', 'California', 'Samura|-Arata', 'Nagano', 'Samura|-Ichikawa', 'New Berlin', 'Stardrifter', 'Okinawa', 'The_Altair', 'Magellan', 'Tony.Sosa', 'Ontario', 'Wilde.RNC-Nestor', 'Omega-7']
Why is this? I cannot see any reason why this should happen.
Don't do this, they will refer to the same list:
players = systems = [] #Define lists
But split them:
players = []
systems = [] #Define lists
Then you will have two separate lists.
Your style is used for creating name aliases of a list (in some cases, it might be useful), not to create two different lists
where you have players = systems = [] change it to separate assignments.
players = []
systems = []
If you want to keep it in one line:
players, systems = [], []
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.