forked from awfulwaffle77/ExamTopicsQuizMaker
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathquiz.py
153 lines (129 loc) · 6.21 KB
/
quiz.py
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
import os
import random
import re
import textwrap
from datetime import datetime
from io import TextIOWrapper
from _classes import CardList
class Quiz:
def __init__(self, exam_name, resources_dir=None) -> None:
self.__cardlist = CardList(resources_dir)
self.__log_dirname = "wrong_answers"
self.__init_questions_per_quiz()
self.__init_show_answer_immediately()
self.__create_wrong_answers_directory()
self.quiz_cards = self.__generate_quiz()
self.exam_name = exam_name
def __init_questions_per_quiz(self):
try:
self.__questions_per_quiz = int(
input("How many questions do you want to have? (Max: " + str(len(self.__cardlist.cards_list)) + ") "))
while self.__questions_per_quiz > len(self.__cardlist.cards_list):
self.__questions_per_quiz = int(
input("Please pick a NUMBER. (Max: " + str(len(self.__cardlist.cards_list)) + ")"))
except ValueError:
print("Defaulted to max number of questions.")
self.__questions_per_quiz = len(self.__cardlist.cards_list)
use_specific_range = (input("Do you want the questions to be from a specific range [y/N]? ").lower() == "y")
if use_specific_range:
self.__range_selection = input(
f"Do you want the {self.__questions_per_quiz} questions to be from the \n[1] beginning\n[2] end\nPlease select 1 or 2: "
)
else:
self.__range_selection = None
def __init_show_answer_immediately(self):
self.__show_answer_immediately = input(
"Do you want to have the answer shown immediately after you respond? (If not, you will be shown a score at the end and a file will be generated with the wrong answers anyway.)[Y/n]"
)
if self.__show_answer_immediately == "":
self.__show_answer_immediately = "y"
self.__show_answer_immediately = self.__show_answer_immediately.lower()
while (self.__show_answer_immediately != "n" and self.__show_answer_immediately != "y"):
self.__show_answer_immediately = input("Please pick between 'y'(yes) or 'n'(no): ")
self.__show_answer_immediately = self.__show_answer_immediately.lower()
def __generate_quiz(self) -> list:
if self.__range_selection == "1":
selected_cards = self.__cardlist.cards_list[:self.__questions_per_quiz]
elif self.__range_selection == "2":
selected_cards = self.__cardlist.cards_list[-self.__questions_per_quiz:]
else:
selected_cards = self.__cardlist.cards_list
shuffle = input("Do you want the questions to be shuffled? [Y/n] ").lower()
if shuffle == "":
shuffle = "y"
if shuffle == "y":
random.shuffle(selected_cards)
return selected_cards[:self.__questions_per_quiz]
selected_cards = selected_cards[:self.__questions_per_quiz]
return selected_cards[:self.__questions_per_quiz]
def __clear(self):
print("")
if os.name == "nt":
_ = os.system("cls")
else:
_ = os.system("clear")
def __create_wrong_answers_directory(self):
try:
os.mkdir(self.__log_dirname)
except:
print("Wrong answers directory already exists. Continuing..")
def __init_answers_file(self) -> TextIOWrapper:
filename = re.sub(" ", "_", str(datetime.now())).split(".")[0]
filename = re.sub(":", "-", filename)
filename += ".txt"
filename = self.exam_name + "_" + filename
filename = os.path.join(self.__log_dirname, filename)
wrong_answers_file = open(filename, "w", encoding="UTF-8")
return wrong_answers_file
def __write_to_file(self, wrong_answers_file, card, your_answer):
wrapper = textwrap.TextWrapper()
wrong_answers_file.write(card.question_number + " " + wrapper.fill(text=card.question) + "\n")
wrong_answers_file.write("-" * 40 + "\n")
for ans in card.answers:
try:
wrong_answers_file.write(ans + "\n")
except:
wrong_answers_file.write(str(ans) + "\n")
wrong_answers_file.write("Your answer: " + your_answer.upper() + "\n")
wrong_answers_file.write("Correct answer: " + card.correct_answer + "\n")
wrong_answers_file.write("-" * 40 + "\n\n")
def start_quiz(self):
self.__clear()
correct_answers = 0
wrong_answers_file = self.__init_answers_file()
wrapper = textwrap.TextWrapper()
print(
"Your quiz starts now. Please enter the characters corresponding to the answers (e.g., 'AB', 'C', 'DE'). Answers are NOT case sensitive."
)
input("Press Enter to continue..")
for index, card in enumerate(self.quiz_cards):
print("")
print(str(index + 1) + "/" + str(self.__questions_per_quiz))
print(card.question_number + " " + wrapper.fill(text=card.question))
print("-" * 40)
for ans in card.answers:
print(wrapper.fill(text=ans))
print("-" * 40)
your_answer = input("Your answer: ").upper()
correct_answer_set = set(card.correct_answer.upper())
your_answer_set = set(your_answer)
if your_answer_set == correct_answer_set:
correct_answers += 1
else:
self.__write_to_file(wrong_answers_file, card, your_answer)
if self.__show_answer_immediately == "y":
print("Correct answer: ", card.correct_answer)
print("Your percentage: " + str(round(correct_answers / (index + 1) * 100, 2)) + "%")
input("Press Enter to continue..")
self.__clear()
wrong_answers_file.close()
print("=^=" * 40)
print("The quiz is DONE! Good job!")
print("Your score: " + str(correct_answers) + "/" + str(self.__questions_per_quiz))
print("Your percentage: " + str(round(correct_answers / self.__questions_per_quiz * 100, 2)) + "%")
def clear(self):
print("")
if os.name == "nt":
_ = os.system("cls")
else:
_ = os.system("clear")