I was studying for an exam and wanted to make a tool that functioned a little bit differently than quizlet.
This code will read in questions and multiple choice options then quiz you on them in a random order.
It will also go over the questions that you missed.
I made it last week and it is surprisingly helpful. I plan to add fill in the blank options and some more customization in the future.
Tell me what you think:
Code import random
import time
q = {}
score = [0,0,0]
def main():
print('Python Multiple Choice Quiz Generator')
file = input('Choose a file to load: ')
try:
filereader(file)
except FileNotFoundError:
print('\nERROR FILE NOT FOUND\n')
main()
except TypeError and UnboundLocalError as err:
print('\nDATA SEEMS TO NOT BE FORMATTED CORRECTLY IN TEXT FILE\n')
main()
print('\nAnswer the following questions:\n')
asker()
def filereader(file):
f = open(file,'r')
k = ''
for x in f:
l = x.rstrip()
if l == '.':
if not(k==''):
comp+=correct
q[k]=comp.split('*')
k = f.readline().rstrip()
comp=''
correct = 0
i=-1
else:
if l[-1:] == '~':
correct = str(i)
l = l.rstrip('~')
comp+=l + '*'
i+=1
def scorekeeper(a,i,c):
score[0]+=a
score[1]+=i
score[2]+=c
print('| Remaining:',score[0],'| Incorrect:',score[1],'| Correct:',score[2],'|')
def asker():
global q
iq = {}
try:
tries+=1
except:
tries=1
c = len(q.keys())
score[0] = c
score[1] = 0
scorekeeper(0,0,0)
i=0
letters = ['a','b','c','d','e','f']
while i<c:
ranq=random.sample(q.keys(), 1)
for y in ranq:
questions = q[y][0:-1]
answer = int(q[y][-1])
text=y+'\n'
lc = 0
for x in questions:
text+=letters[lc]+'.) ' + x + '\n'
lc += 1
print(text)
attemptedanswer=input('Please Enter a Letter: ')
while not(attemptedanswer.lower() in letters):
print('Invalid input')
attemptedanswer=input('Please Enter a Letter: ')
attemptedanswer = letters.index(attemptedanswer)
if attemptedanswer == answer:
print('\nCorrect!\n')
scorekeeper(-1,0,1)
else:
print('\nIncorrect!\n')
scorekeeper(-1,1,0)
iq[y]=q[y]
del q[y]
i+=1
if not(len(iq.keys()) == 0):
x = input('\nWould you like to try the questions you got incorrect again? (y/n) ')
if x == 'y':
q = iq
print()
asker()
else:
print('Congratulations! You mastered this set of questions!')
main()
You would read in a file like this:
Quote:.
What shape is a tire?
Square
Triangle
Circle~
Rectangle
.
What grows on trees?
Money
Cows
Apples~
Strawberries
.
What is not a normal household pet?
Fish
Dog
Cat
Giraffe~
.
What flies in the air?
Dove~
Penguin
Tree
Dog
.
What color is snow?
Black
White~
Blue
Red
.
What color is a firetruck?
Red~
Black
Green
Yellow
The '.' marks a new question
The '~' marks the correct answer
It is not much but I figured it may help someone out.
1) You should not be using some strange proprietary format. You should use CSV's.
Code What color is a firetruck?,Red~,Black,Green,Yellow
etc...
2) You should not be trying to re-invent the wheel.
3) You should be using pandas to actually read/sort these types of applications.
PHP Code
<?php import numpy as np import pandas as pd
try: input = raw_input except NameError: pass
quiz = pd.read_csv("test.txt") quiz = quiz.reindex(np.random.permutation(quiz.index)) # randomize the dataframe quiz.reset_index(drop=True, inplace=True) # reset the indexes so they don't fuck me up. correctAnswers = 0 totalQuestions = 0
for i in range(len(quiz.Question)): question = quiz.Question[i] answers = [quiz.Answer1[i], quiz.Answer2[i], quiz.Answer3[i], quiz.Answer4[i]] correctAnswer = "" for j, answer in enumerate(answers): if answer[-1] == "~": answers[j] = answers[j][:-1] correctAnswer = answers[j] if correctAnswer: answers = dict(zip(list(np.random.permutation(["a", "b", "c", "d"])), answers)) # randomize answers, too print("{}) {}\nA) {a}\nB) {b}\nC) {c}\nD) {d}".format(i+1, question, **answers)) choice = input("> ") if answers[choice.lower()] == correctAnswer: correctAnswers += 1 totalQuestions += 1
print("Your Score: {}/{}".format(correctAnswers, totalQuestions))
Your file should look like (note: the first line header is VERY important):
Code Question,Answer1,Answer2,Answer3,Answer4
What color is a firetruck?,Red~,Black,Green,Yellow
What color is snow?,Black,White~,Blue,Red
What flies in the air?,Dove~,Penguin,Tree,Dog
What is not a normal household pet?,Fish,Dog,Cat,Giraffe~
What grows on trees?,Money,Cows,Apples~,Strawberries
What shape is a tire?,Square,Triangle,Circle~,Rectangle
The more I post my code on here, the more I realize how much I have to learn.
Thanks for taking the time to critique/rewrite
(Mar 2, 2016 07:06 PM)DipDuo™ Wrote: The more I post my code on here, the more I realize how much I have to learn.
Thanks for taking the time to critique/rewrite
It's all good. String manipulation is a very useful thing to know, but you should also utilize readily available and well-tested/well-supported frameworks (like pandas and numpy) when possible instead of re-inventing the wheel. I'm not going to lie, I do the same thing fairly often.
I have a lot to learn xD
I like looking around in someone's code :p
I'll try this out :D
Mar 3, 2016 03:47 PM
(This post was last modified: Mar 3, 2016 03:52 PM by DipDuo™.)
(Mar 3, 2016 09:50 AM)bet4r00t Wrote: I have a lot to learn xD
I like looking around in someone's code :p
I'll try this out :D
I re-wrote it to support fill in the blank questions as well.
I also have a 'question formatter' program that will format questions to be read by the quizzer.
New Quizzer thing:
PHP Code
<?php #Question|code|Answer1|Answer2|Answer3|Answer4 #[question,code,a1,a2,a3,a4,MC or FITB,correct answer(if MC)] import random
q = {} score = [0,0,0]
def main(): print('Python Multiple Choice Quiz Generator') #print('Type "help" to learn how to import questions') file = input('Choose a file to load: ') #file='data.txt' ReadFile(file) asker() def ReadFile(file): f = open(file,'r') case = True for x in f: if x.rstrip() == '-': #switch to fill in the blank case = False x = f.readline() templist = x.rstrip().split('|') if case: DictFormatMultipleChoice(templist) else: DictFormatBlank(templist)
def DictFormatMultipleChoice(templist): i=0 for x in templist[2:]: if x[-1:] == '~': templist.append(i) templist.append('mc') templist[i+2]=templist[i+2][:-1] i+=1 if not(templist[1]==''): templist[1]=templist[1].split('&') q[templist[0]]=templist[1:]
def DictFormatBlank(templist): templist.append('f') q[templist[0]]=templist[1:]
def scorekeeper(a,i,c): score[0]+=a score[1]+=i score[2]+=c print('| Remaining:',score[0],'| Incorrect:',score[1],'| Correct:',score[2],'|')
def asker(): global q iq = {} try: tries+=1 except: tries=1 c = len(q.keys()) score[0] = c score[1] = 0 scorekeeper(0,0,0) i=0 letters = ['a','b','c','d','e','f'] while i<c: ranq=random.sample(q.keys(), 1) for y in ranq: answer = 0 text=y+'\n' if q[y][0] != '': for x in q[y][0]: text+='| | '+x+'\n' if q[y][-1] == 'mc': questions = q[y][1:-2] answer = int(q[y][-2]) lc = 0 for x in questions: text+=letters[lc]+'.) ' + x + '\n' lc += 1 print(text.rstrip()) attemptedanswer=input('> ') while not(attemptedanswer.lower() in letters): print('Invalid input') attemptedanswer=input('> ') attemptedanswer = letters.index(attemptedanswer) else: questions = q[y][1:-1] print(text.rstrip()) attemptedanswer=input('> ')
if attemptedanswer == answer or attemptedanswer in questions: #print('\nCorrect!\n') scorekeeper(-1,0,1) else: #print('\nIncorrect!\n') scorekeeper(-1,1,0) iq[y]=q[y] del q[y] i+=1 if not(len(iq.keys()) == 0): x = input('\nWould you like to try the questions you got incorrect again? (y/n) ') if x == 'y': q = iq print() asker() else: print('Congratulations! You mastered this set of questions!')
main()
Sample questions:
Quote:Assume that there is a variable named customer that references a file object. How would you write the string `Mary Smith' to the file?||customer.write(`Mary Smith')~|customer.write(`w',`Mary Smith')|customer.file.write(`Mary Smith')|customer.input(`Mary Smith')
If a file has been opened properly, which method will return the file’s entire contents as a string?||read()~|input()|get()|write()|readline()
Which method could be used to strip specific characters from just the end of a string?||strip()|remove()|lstrip()|rstrip()~|estrip()
Given that the file is valid and contains numbers, what does x contain after the following statement?|x = open("numbers.txt", "r")|a string|a boolean|a series of integers|This statement contains an error.|a file object~
Which of these is not a valid file mode when opening a file in Python?||"w"|"a"|"r"|"f"~
Before a file can be used by a program, it must be________.||opened~|encrypted|closed|formatted
This is a single piece of data within a record.||delimiter|variable|subrecord|field~
When a file is opened in this mode, data will be written at the end of the file's existing contents.||backup mode|output mode|read-only mode|addition mode|append mode~
To respond to errors, what kind of a statement must be used?||run/handle|try/handle|try/except~|attempt/except
Which of these causes an IOError?||Converting an incompatible string to an integer type.|An incorrectly formed input statement.|Opening a file that doesn't exist.~|Attempting to input a float value.|Attempting to divide by 0.|None of these
Which of these is associated with a specific file, and provides a way for the program to work with that file?||None of these|List|Extension|File constant|File object~
What do you call the process of retrieving data from a file?||Inputing|Outputing|Reading~|Handling|Writing
A(n)_________ is a function that belongs to an object, and performs some operation using that object.||class|reference|method|handler~|object
A(n)____ is a complete set of data about an item, usually a line of data in an input file.||extension|record~|method|mode|field
The______________ is one or more statements grouped together with the anticipation that they could potentially raise an exception.||try block~|record|error portion|binary section|except block
When opening a file in write mode, if a file with the specified name already exists, a warning message is generated.||True|False~
Closing a file disconnects the communication between the file and the program.||True~|False
In Python, there is no way to prevent a program from crashing if it attempts to read a file that does not exist.||True|False~
Strings can be written directly to a file with the write method, but integer data types must always be converted to strings before they can be written to a file.||True~|False
A for loop that reads in lines from a file automatically stops when it reaches the end of the file, whereas the readline() method requires you to check for an empty string to signal the end of the file.||True~|False
A file can safely be opened and closed multiple times within the same program.||True~|False
Given a valid file that contains multiple lines of data, what is the output of the following code:|f=open("names.txt","w")&print(f)|Only the first line of the file is printed|None of these~|The letter "f" is printed.|The contents of the entire file are printed
Given a valid file containing multiple lines of data, what does the print() statement print out the first time that it is called:|f=open("data.txt","r")&for line in f:& line=f.readline()& print(line)&f.close()|This program causes an error|The entire contents of the file|The first word in the file|The first line of the file|None of these|The second line of the file~
The following code could potentially raise an IOError.|f=open("names.txt", 'r')&for x in f:& print(5/int(x.rstrip()))|True~|False
The following code could potentially raise a ZeroDivisionError.|f=open("names.txt", 'r')&for x in f:& print(5/int(x.rstrip()))|True~|False
When a file is first opened successfully, where is the read position indicator?||At the beginning of the file~|At the end of the first line of the file|It needs to be assigned by the programmer first|At the end of the file
What is needed to delete a single line from a file?||The delete() method|The remove() method|The creation of a new file~|The overwrite() method
This is a small "holding section" in memory that many systems write data to before writing the data to a file.||delimiter access|encrypted zone|header|buffer~
-
Which mode specifier will open a file but will not let you change the file or write to it?||read|read mode|'r'|"r"|r
Which mode specifier will erase the contents of a file if it already exists and create it if it does not exist?||'w'|w|"w"|write mode|write
Question formatter:
PHP Code
<?php mc=[] fitb=[]
print('Python Quiz Question Compiler for use with Python Quiz Generator') def main(): file = input('\nChoose a filename: ') try: f = open(file,'r') print('This filename is already in use!\nPlease try another filename.') main() except: print('Filename Avaliable\n') i = 0 case1 = True while case1: mc_o_f = int(input('Press 1 for a multiple choice question\nPress 2 for a fill in the blank question\n')) q = input('Choose a Question: ') c = input('Is there code involved in this question? (y/n) ') code='' if c == 'y': print('Enter the code line by line (type "q" when done)') x = input('') while not(x=='q'): code+=x+'&' x = input('') if mc_o_f == 1: print('Enter Multiple choice options below. Include a "~" on the end of the correct option (type "q" when done)') options='' x = input('') while not(x=='q'): x = x.strip() options+=x+'|' x = input('') mc.append(q+'|'+code.rstrip('&')+'|'+options) if mc_o_f == 2: print('Enter all possible answers for your question one at a time. (type "q" when done)') options='' x = input('') while not(x=='q'): x = x.strip() options+=x+'|' x = input('') fitb.append(q+'|'+code.rstrip('&')+'|'+options)
i+=1 while not(x=='y' or x=='n'): print('You have',i,'total question(s).',end=' ') x = input('Would you like to make another? (y/n)') if x == 'n': case1 = False writefile(file)
def writefile(file): y='' f = open(file,'w') for x in mc: f.write(x.rstrip('|')+'\n') f.write('-\n') for x in fitb: y+=x.rstrip('|')+'\n' f.write(y.rstrip()) f.close() print('File Write Successful.')
main()
Goodies will be happy to know that I used some of his advice.
I wanted to stay away from using a non-default library though
DO NOT DEAL WITH THIS MEMBER
This is actually better than quizlet, I did not believe it would be at first.
it's basic, but very cool ^^ thank you for posting. I'll be sure to use this.
(Mar 12, 2016 03:59 PM)labroca Wrote: This is actually better than quizlet, I did not believe it would be at first.
Glad you like it. I honestly use it all the time to study for tests. it really comes in handy when I am trying to study from old multiple choice quizzes.
|