Before discovering http://quizlet.com/, the following program was developed for running custom quizzes to help with studying for college courses. The program is not very advanced, but it works reasonably well for what it was designed to do. If the program were developed further, it would need greater capabilities than it currently has and would require a secondary system for actually creating the quizzes (currently, they are hand-typed). Quiz Me could be a starting point for anyone who wishes to actually write a program such as this and inspire others to write much better programs than what this recipe currently offers.
FAQ (Frequently Asked Questions) is used to generate events that power the quizzing process. The remaining classes represent the different event types. Enter and Exit instances are yielded when entering and exiting different tiers in the quiz structure. Reports are yielded after a tier has been completed and allow whoever is taking a test to review how well the questions have been answered per section, chapter, and complete quiz. Questions are randomly created and yielded and provide a way to easily answer from a list of choices. The Answer class extends the Question interface for getting more information when reviewing incorrectly answered questions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | ####################
# source/teach_me.py
####################
import random
from . import quizcore
################################################################################
class FAQ:
def __init__(self, testbank):
self.test = quizcore.UnitTest(testbank)
def __iter__(self):
unittest = self.test
yield Enter(unittest)
unittest_report = Report(unittest)
for chapter in unittest.chapters:
yield Enter(chapter)
chapter_report = Report(chapter, unittest_report)
for section in chapter.sections:
yield Enter(section)
section_report = Report(section, chapter_report)
QnA = []
for category in section.categories:
category.build()
QnA.extend(category.QnA)
random.shuffle(QnA)
for question in QnA:
yield Question(section_report, *question)
yield Exit(section)
section_report.finalize()
yield section_report
yield Exit(chapter)
chapter_report.finalize()
yield chapter_report
yield Exit(self.test)
unittest_report.finalize()
yield unittest_report
################################################################################
class _Status:
def __init__(self, division):
self.kind = division.__class__.__name__
self.name = division.name
def __str__(self):
return '{}: {}'.format(self.kind, self.name)
class Enter(_Status): pass
class Exit(_Status): pass
################################################################################
class Report:
def __init__(self, level, parent=None):
self.__level = level.__class__.__name__
self.__parent = parent
self.__right = 0
self.__wrong = 0
self.__problems = []
self.__finalized = False
def right_answer(self):
assert not self.__finalized
self.__right += 1
def wrong_answer(self):
assert not self.__finalized
self.__wrong += 1
def review(self, question, answer):
assert not self.__finalized
self.__problems.append((question, answer))
def problems(self):
assert self.__finalized
for question, answer in self.__problems:
yield Answer(answer, *question)
def finalize(self):
assert not self.__finalized
if self.__parent is not None:
self.__parent.__right += self.__right
self.__parent.__wrong += self.__wrong
self.__parent.__problems.extend(self.__problems)
self.__finalized = True
@property
def level(self):
return self.__level
@property
def right(self):
assert self.__finalized
return self.__right
@property
def wrong(self):
assert self.__finalized
return self.__wrong
@property
def total(self):
assert self.__finalized
return self.__right + self.__wrong
@property
def final(self):
return self.__parent is None
################################################################################
class Question:
def __init__(self, report, category, question, choices, right):
self.__report = report
self.__category = category
self.__question = question
self.__choices = choices
self.__right = right
self.__answered = False
self.__QnA = category, question, choices, right
@property
def category(self):
return self.__category
@property
def question(self):
return self.__question
@property
def choices(self):
return self.__choices
def answer(self, index_or_string):
assert not self.__answered
if isinstance(index_or_string, int):
index_or_string = self.__choices[index_or_string]
if index_or_string == self.__right:
self.__report.right_answer()
else:
self.__report.wrong_answer()
self.__report.review(self.__QnA, index_or_string)
self.__answered = True
################################################################################
class Answer(Question):
def __init__(self, answer, *question):
super().__init__(None, *question)
self.__answer = answer
@property
def answer(self):
return self.__answer
@property
def right(self):
return self._Question__right
|