import os import csv import random import time from rich.console import Console from rich.markdown import Markdown # Error codes : # exit (1) = function _open_csv def _open_csv(filename): # Return True + csv list ===> all ok # with added "done" : "False" ===> Did the user already replied to this qst? # with added "correct" : "False" ===> Was the answer of the user right or wrong # or # Return False + error message ===> problem try: with open(filename) as csv_fp: data = [] data_fp = csv.DictReader(csv_fp) for item in data_fp: data.append(item) item["done"] = False item["correct"] = False return data except Exception as error: #print(error) #log("csv opening", error) exit(1) def _user_conf(max_qst): nb_qst = "0" name = input("Enter your name please : ") while not nb_qst.isnumeric() or int(nb_qst) <= 0 or int(nb_qst) > max_qst: nb_qst = input("How many question do you want (max {}) : ".format(max_qst)) return name, nb_qst def _display_question(question): os.system("clear") console = Console() display_qst = "# {}".format(question["QUESTION"]) display_qst = Markdown(display_qst) console.print(display_qst) answer = "" for i in question.keys(): if i.isnumeric(): answer += "1. {} \n".format(question[i]) answer += "\n\n[Q]uit" answer = Markdown(answer) console.print(answer) def _wait_user_answ(answer): if len(answer["ANSWER"]) > 1: # if ===> several answers real_answer = [] user_answer = [] # Build list of right answers for i in str(answer["ANSWER"]): if i.isnumeric(): real_answer.append(i) # Wait answers of the user result = input("\nWhat are your choices : ") if result.lower() == "q" or result.lower() == "quit": return 3 # Build list of user answers for i in result: if i.isnumeric(): user_answer.append(i) # Compare real_answer.sort() user_answer.sort() if real_answer == user_answer: return True else: return False else: # ===> if only one possible answer result = input("\nWhat is your choice : ") if result.lower() == "q" or result.lower() == "quit": return 3 if result in answer["ANSWER"] and len(result) != 0: return True else: return False def _stats(stats_list, player): count_qst = 0 count_right_answ = 0 os.system("clear") console = Console() display = "# Hi {}\nYour exam test is finished !!!\n".format(player) display = Markdown(display) console.print(display) for item in stats_list: if item["done"] is True: count_qst += 1 if item["correct"] is True: count_right_answ += 1 display = "# You replied to {} questions, with {} right answers!!!".format(count_qst, count_right_answ) display = Markdown(display) console.print(display) def main(): filename = 'data/list_book1.csv' # csv_list = list of dictionaries : csv_list = _open_csv(filename) random.shuffle(csv_list) # shuffle the list. # Collects the name of the player AND the number of questions wished : player, nb_qst = _user_conf(len(csv_list)) count = int(nb_qst) # The loop : get_out_while = False while count > 0 and get_out_while is False: count -= 1 _display_question(csv_list[count]) # Check if correct answer result = _wait_user_answ(csv_list[count]) if result == 3: # quit! get_out_while = True elif result: # right answer! csv_list[count]["correct"] = True csv_list[count]["done"] = True else: # wrong answer! csv_list[count]["done"] = True # End of while _stats(csv_list, player) if __name__ == "__main__": main()