####################
# 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