Description:
I am building a quiz based learning system in Python. The idea is once a day you have to give this test to improve your learning, it's different from regular rote learning. The user will be shown question first and optionally series of hints, the user then can match his answer to the original answer and honestly gives score to his attempt. I didn't go for programmatically checking the answers because it would be difficult to check semantics of two strings.
Goal:
The end goal is to provide a flexible way to add new questions and hints and add new question types. I am not favour of very fancy UI but something which feels intuitive should work.
In the long run, I will be integrating it with Slack as a bot.
Code:
from enum import Enum
class Category(Enum):
CS, MATH, PUZZLE = range(3)
class Score(Enum):
BAD, OK, GOOD = range(3)
data = [{
'question': 'What does the fox say?',
'hints': ['not the sound of cat', 'not the sound of dog'],
'answer': 'Its a mystery',
'category': Category.PUZZLE,
'score': Score.BAD
}, {
'question': 'What is the worst case run time of binary search of n elements?',
'hints': [
'Think about the best case',
'Would need to search exhaustively until one element'],
'answer': 'Log(n) base 2',
'category': Category.CS,
'score': Score.BAD
}];
def runQuiz(questions, category):
total = 0
needHint = '/h'
for q in filter(lambda q: q['category'] == category, questions):
answer = input(q['question'])
if answer == needHint:
for hint in q['hints']:
moreHints = input(hint)
if moreHints != needHint:
break
print('Correct answer is: {0}'.format(q['answer']))
rating = int(input('Rate your solution(1-3): '))
q.update({'score': rating})
total += rating
print('You are done for today, your score is {0}'.format(total))
return input('Want to start again?(y/*)')
def selectCategory():
category = input("""
Select category
1. Computer Science
2. Mathematics
3. Puzzles
4. Random (Default)
""")
selectedCategory = {
1: Category.CS,
2: Category.MATH,
3: Category.PUZZLE
}.get(int(category), Category.CS)
return selectedCategory
def main():
print('Make sure you are not feeling thirsty')
input()
print('Clean your surrounding')
input()
print('Remember your goal')
input()
print('If you need any hint type /h')
input()
print('Lets go')
selectedCategory = selectCategory()
print('You have selected {0} category'.format(selectedCategory.name))
print('')
shouldStartAgain = runQuiz(data, selectedCategory)
if shouldStartAgain == 'y':
main()
else:
print('You are done for today, sleep well!')
if __name__ == '__main__':
main()
Note:
Although the current solution doesn't meet all the requirements but it is complete in itself as its fully functional code. Its in early stage of development so I would like to take proper design decisions as soon as possible.
TODO:
Find a way to persist the questions with updated score. Make the questions with lower score come first.
Questions:
- Is there any better way to deal with terminal?
- Keeping in mind that I would like to use this system as web service too, what design decisions would be helpful?
- It may be too broad, but what good programming practices should I follow, for example when and where to choose objects, enums etc?