From 9d9a1e97a9000e8b0ea4290fce5b1324d9d8456d Mon Sep 17 00:00:00 2001 From: waldek Date: Sun, 23 May 2021 16:04:09 +0200 Subject: [PATCH] hello world --- .gitignore | 5 +++ ccpq/lib_ccpq.py | 88 ++++++++++++++++++++++++++++++++++++++++ poc_standalone.py | 81 +++++++++++++++++++++++++++++++++++++ requirements.txt | 5 +++ standalone_tui.py | 100 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 279 insertions(+) create mode 100644 .gitignore create mode 100644 ccpq/lib_ccpq.py create mode 100755 poc_standalone.py create mode 100644 requirements.txt create mode 100755 standalone_tui.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56055e6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +bin/ +data/ +include/ +lib/ +__pycache__ diff --git a/ccpq/lib_ccpq.py b/ccpq/lib_ccpq.py new file mode 100644 index 0000000..9f6c527 --- /dev/null +++ b/ccpq/lib_ccpq.py @@ -0,0 +1,88 @@ +import pathlib +import time +import os +import csv +import random +from rich.console import Console +from rich.markdown import Markdown + +LEVEL = "LEVEL" +QUESTION = "QUESTION" +ANSWER = "ANSWER" + + +class Question(object): + """class to hold the question data and methods""" + def __init__(self, data): + self._data = data + self._clean_data() + + def _clean_data(self): + """ + TODO needs quite bit of actual cleanup to make the parsing more robust + """ + self._level = self._data[LEVEL].strip() + self._question = self._data[QUESTION].strip() + self._answers = self._data[ANSWER].strip().split(" ") + + def get_question(self): + return self._question + + def get_possibilities(self): + """returns a list of all the possible answers""" + possibilities = [] + for key in self._data.keys(): + if key.isnumeric(): + possibilities.append(self._data[key]) + return possibilities + + def verify(self, answer): + """needs quite some work""" + if answer in self._data[ANSWER]: + return True + else: + return False + + def get_right_answers(self): + answers = [] + for answer in self._answers: + if len(answer) == 0: + print("question not complete...") + else: + answers.append(self._data[answer]) + return answers + + +class Database(object): + """holds all the Question objects and methods to get new questions""" + def __init__(self, filepath): + self.filepath = filepath + self._db = [] + self.setup() + + def setup(self): + data = csv.DictReader(open(self.filepath, "r")) + for row in data: + self._db.append(Question(row)) + + def get_question(self): + return random.choice(self._db) + + +class Game(object): + def __init__(self): + self._stats = [] + + def update_stats(self, stat): + self._stats.append(stat) + + def get_stats(self): + right = self._stats.count(True) + wrong = self._stats.count(False) + total = len(self._stats) + return (right, wrong, total) + + +if __name__ == "__main__": + pass + diff --git a/poc_standalone.py b/poc_standalone.py new file mode 100755 index 0000000..d8deef0 --- /dev/null +++ b/poc_standalone.py @@ -0,0 +1,81 @@ +#!/usr/bin/python3 + +import pathlib +import time +import os +import csv +import random +from collections import Counter +from rich.console import Console +from rich.markdown import Markdown + + +def _load_csv(filepath): + """Loads the csv file to a dict""" + dictreader = csv.DictReader(open(filepath, "r")) + data = [] + for element in dictreader: + data.append(element) + return data + + +def _get_random_question(data): + choice = random.choice(data) + return choice + + +def print_random_question(data): + os.system("clear") + c = Console() + question = "# {}".format(data["QUESTION"]) + question = Markdown(question) + c.print(question) + answers = [] + for i in data.keys(): + if i.isnumeric(): + answers.append(data[i]) + answer = "" + for i in answers: + answer += "1. {} \n".format(i) + answer = Markdown(answer) + c.print(answer) + + +def _test_question(data): + result = input("What's your answer? ") + if result in data["ANSWER"]: + return True + else: + return False + +def _print_succes(status): + c = Console() + if status: + msg = "## Good job!" + else: + msg = "## that's not the right answer..." + md = Markdown(msg) + c.print(md) + +def print_stats(counter): + succes = counter.count(True) + fail = counter.count(False) + print("{} out of {} correct!".format(succes, succes + fail)) + input("press ENTER for a new question or CTRL-C to quit") + +if __name__ == "__main__": + filepath = pathlib.Path("./data/list_book1.csv") + data = _load_csv(filepath) + try: + counter = [] + while True: + question = _get_random_question(data) + print_random_question(question) + status = _test_question(question) + counter.append(status) + _print_succes(status) + print_stats(counter) + except KeyboardInterrupt: + print("byebye") + + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..373fc4b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +colorama==0.4.4 +commonmark==0.9.1 +Pygments==2.9.0 +rich==10.2.2 +typing-extensions==3.10.0.0 diff --git a/standalone_tui.py b/standalone_tui.py new file mode 100755 index 0000000..18593d1 --- /dev/null +++ b/standalone_tui.py @@ -0,0 +1,100 @@ +#!/usr/bin/python3 + +import pathlib +import time +import os +import csv +import random +from rich.console import Console +from rich.markdown import Markdown + +from ccpq.lib_ccpq import Question, Database, Game + +class Tui(object): + def __init__(self): + self._console = Console() + self._stats = [] + + def ask_question(self, question): + md = Markdown("# {}".format(question.get_question())) + 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): + md = Markdown("What's your answer?") + self._console.print(md) + answer = self._parse_input() + return answer + + def _parse_input(self): + """ + TODO make it adapt to questions with multiple choices and fill the + blank + """ + while True: + result = input() + if result.isdigit(): + return result + md = Markdown("**only digits please**") + self._console.print(md) + + 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_stats(self, stats): + md = "### you have {} out of {} right!".format(stats[0], stats[2]) + md = Markdown(md) + self._console.print(md) + md = "### press **enter** to get a new question or **CTRL-C** to quit" + md = Markdown(md) + self._console.print(md) + input() + os.system("clear") + + + def goodbye(self): + md = Markdown("# Goodbye!") + self._console.print(md) + + +class Application(object): + def __init__(self, filepath, interface): + self._db = Database(filepath) + self._session = Game() + self._interface = interface + + def run(self): + while True: + question = self._db.get_question() + self._interface.ask_question(question) + answer = self._interface.prompt_for_answer() + stat = question.verify(answer) + self._session.update_stats(stat) + self._interface.show_response(question) + self._interface.show_stats(self._session.get_stats()) + + def quit(self): + self._interface.goodbye() + + +if __name__ == "__main__": + filepath = pathlib.Path("./data/list_book1.csv") + interface = Tui() + app = Application(filepath, interface) + try: + app.run() + except KeyboardInterrupt: + app.quit()