#!/usr/bin/python3 import pathlib import argparse import os import random import time from rich.console import Console from rich.markdown import Markdown from rich.table import Table from ccpq.lib_ccpq import Question, Database, Game MSG = { True: [ "Yes!", "Good one!", "Super!", "Excellent job!" ], False: [ "Sorry, that's wrong", "No, that's not right", "Damn it! That's not the right answer", ] } DIFFICULTY = { "easy": "010-160", "medium": "101-500", "hard": "102-500", } LEVELS = [ "010-160", "101-400", "101-500", "102-400", "102-500", ] class Tui(object): def __init__(self): self._console = Console() self._stats = [] def ask_question(self, question): os.system("clear") md = Markdown("# {}".format(question.get_question())) self._console.print(md) md = Markdown("level: {}".format(question.get_level())) self._console.print(md) md = "" for possibility in question.get_possibilities(): md += "1. {}\n".format(possibility) md = Markdown(md) self._console.print(md) def prompt_for_answer(self, name): #md = Markdown("What's your answer?") #self._console.print(md) answer = self._parse_input(name) return answer def _parse_input(self, name): """ """ answers = [] results = input("\n {}, what's your answer? (only numbers, separated by a SPACE) ".format(name)) results = results.split() for result in results: if result.isdigit(): answers.append(result) else: md = Markdown("**only digits please**") self._console.print(md) return answers def signal_player(self, player): os.system("clear") md = "# {}".format(player.name) md = Markdown(md) self._console.print(md) time.sleep(2) os.system("clear") def show_response(self, question): answers = question.get_right_answers() if len(answers) == 1: answer = answers[0] md = Markdown("### The right answer is: {}".format(answer)) else: md = "### The right answers are:\n" for answer in answers: md += "* {}\n".format(answer) md = Markdown(md) self._console.print(md) def show_explanation(self, question): md = "--- \n {} \n \n ---".format(question.get_explication()) md = Markdown(md) self._console.print(md) def show_success(self, success): md = "# {}".format(random.choice(MSG[success])) md = Markdown(md) self._console.print(md) def show_stats(self, stats): md = "{}, you have {} out of {} right!\n".format(stats[0], stats[1], stats[1] + stats[2]) md = Markdown(md) self._console.print(md) md = "### press **enter** to get a new question, s for stats and **CTRL-C** to quit" md = Markdown(md) self._console.print(md) result = input() return result def show_game_stats(self, players): os.system("clear") table = Table("Player") table.add_column("Right") table.add_column("Wrong") table.add_column("Total") for player in players: name, right, wrong = player.get_stats() table.add_row(str(name), str(right), str(wrong), str(right + wrong)) self._console.print(table) md = "### press **enter** to continue" md = Markdown(md) self._console.print(md) input() def goodbye(self): md = Markdown("# Goodbye!") self._console.print(md) class Application(object): def __init__(self, filepath_csv, filepath_players, interface, number, level): self._db = Database(filepath_csv, level) self._session = Game(filepath_players) self._number = number * len(self._session.get_all_players()) self._interface = interface def start(self): pass def run(self): while self._number > 0: player = self._session.get_random_player() if len(self._session.get_all_players()) > 1: self._interface.signal_player(player) question = self._db.get_question() self._interface.ask_question(question) answer = self._interface.prompt_for_answer(player) stat = question.verify(answer) player.stats.update_stats(stat) self._interface.show_success(stat) self._interface.show_response(question) self._interface.show_explanation(question) result = self._interface.show_stats(player.get_stats()) if result.startswith("s"): players = self._session.get_all_players() self._interface.show_game_stats(players) self._number -= 1 self.quit() def quit(self): players = self._session.get_all_players() self._interface.show_game_stats(players) self._interface.goodbye() def level_logic(level, difficulty): if level is None and difficulty is None: level = "lpic1_part1" elif level is not None: level = LEVELS[0:LEVELS.index(DIFFICULTY[level]) + 1] elif difficulty is not None: level = LEVELS[0:LEVELS.index(DIFFICULTY[difficulty]) + 1] return level if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( "-f", "--file", required=False, default="data", help="path to specific CSV file or directory", action="store" ) parser.add_argument( "-p", "--players", required=False, default="", help="file with list of players", action="store" ) parser.add_argument( "-n", "--number", default=20, help="number of questions to ask", type=int, action="store" ) group_level = parser.add_mutually_exclusive_group() group_level.add_argument( "-d", "--difficulty", choices=DIFFICULTY.keys(), help="easy, medium or hard" ) group_level.add_argument( "-l", "--level", choices=LEVELS, help="LPI level to test" ) args = parser.parse_args() filepath_csv = pathlib.Path(args.file) filepath_players = pathlib.Path(args.players) if not filepath_csv.exists(): print("no such file or directory!") exit(1) level = level_logic(args.level, args.difficulty) interface = Tui() app = Application(filepath_csv, filepath_players, interface, args.number, level) try: app.run() except KeyboardInterrupt: app.quit()