Feat: replace references to PyInquier with prompt_toolkit

This commit is contained in:
Bertrand Benjamin 2021-01-01 17:47:13 +01:00
parent 04a2506d86
commit 4ea7f8db14
3 changed files with 136 additions and 110 deletions

View File

@ -2,15 +2,19 @@
# encoding: utf-8 # encoding: utf-8
from prompt_toolkit import prompt from prompt_toolkit import prompt, HTML, ANSI
from prompt_toolkit import print_formatted_text as print
from prompt_toolkit.styles import Style
from prompt_toolkit.validation import Validator from prompt_toolkit.validation import Validator
from prompt_toolkit.completion import WordCompleter from prompt_toolkit.completion import WordCompleter
from unidecode import unidecode from unidecode import unidecode
from datetime import datetime from datetime import datetime
from functools import wraps from functools import wraps
import sys
from .getconfig import config from .getconfig import config
VALIDATE = [ VALIDATE = [
"o", "o",
"ok", "ok",
@ -23,74 +27,95 @@ VALIDATE = [
REFUSE = ["n", "non", "NON", "no", "NO"] REFUSE = ["n", "non", "NON", "no", "NO"]
CANCEL = ["a", "annuler"] CANCEL = ["a", "annuler"]
STYLE = Style.from_dict(
{
"": "#93A1A1",
"validation": "#884444",
"appending": "#448844",
}
)
class CancelError(Exception): class CancelError(Exception):
pass pass
def prompt_until_validate_or_cancel(func): def prompt_validate(question, cancelable=False, empty_means=1, style="validation"):
@wraps(func) """Prompt for validation
def wrapper(*args, **kwrd):
ans = func(*args, **kwrd)
confirm = prompt( :param question: Text to print to ask the question.
"C'est ok? (a ou annuler pour sortir) ", :param cancelable: enable cancel answer
completer=WordCompleter(VALIDATE + REFUSE + CANCEL), :param empty_means: result for no answer
).lower() :return:
0 -> Refuse
1 -> Validate
-1 -> cancel
"""
question_ = question
choices = VALIDATE + REFUSE
if confirm in CANCEL: if cancelable:
raise CancelError question_ += "(a ou annuler pour sortir)"
choices += CANCEL
while confirm not in VALIDATE: ans = prompt(
ans = func(*args, **ans, **kwrd) [
confirm = prompt( (f"class:{style}", question_),
"C'est ok? (a ou annuler pour sortir) ", ],
completer=WordCompleter(VALIDATE + REFUSE + CANCEL), completer=WordCompleter(choices),
).lower() style=STYLE,
if confirm in ["a", "annuler"]: ).lower()
if ans == "":
return empty_means
if ans in VALIDATE:
return 1
if cancelable and ans in CANCEL:
return -1
return 0
def prompt_until_validate(question="C'est ok? ", cancelable=False):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwrd):
ans = func(*args, **kwrd)
confirm = prompt_validate(question, cancelable)
if confirm == -1:
raise CancelError raise CancelError
return ans
return wrapper while not confirm:
sys.stdout.flush()
ans = func(*args, **ans, **kwrd)
confirm = prompt_validate(question, cancelable)
if confirm == -1:
raise CancelError
return ans
return wrapper
return decorator
def prompt_until_validate(func): @prompt_until_validate()
@wraps(func)
def wrapper(*args, **kwrd):
ans = func(*args, **kwrd)
confirm = prompt(
"C'est ok? ",
completer=WordCompleter(VALIDATE + REFUSE),
).lower()
while confirm not in VALIDATE:
ans = func(*args, **ans, **kwrd)
confirm = prompt(
"C'est ok? ",
completer=WordCompleter(VALIDATE + REFUSE),
).lower()
return ans
return wrapper
@prompt_until_validate
def prompt_exam(**kwrd): def prompt_exam(**kwrd):
""" Prompt questions to edit an exam """ """ Prompt questions to edit an exam """
print(HTML("<b>Nouvelle évaluation</b>"))
print("Nouvelle évaluation")
exam = {} exam = {}
exam["name"] = prompt("Nom de l'évaluation: ", default=kwrd.get("name", "DS")) exam["name"] = prompt("Nom de l'évaluation: ", default=kwrd.get("name", "DS"))
tribes_name = [t["name"] for t in config["tribes"]] tribes_name = [t["name"] for t in config["tribes"]]
exam["tribe"] = prompt( exam["tribename"] = prompt(
"Nom de la classe: ", "Nom de la classe: ",
default=kwrd.get("tribe", ""), default=kwrd.get("tribename", ""),
completer=WordCompleter(tribes_name), completer=WordCompleter(tribes_name),
validator=Validator.from_callable(lambda x: x in tribes_name), validator=Validator.from_callable(lambda x: x in tribes_name),
) )
exam["tribe"] = [t for t in config["tribes"] if t["name"] == exam["tribename"]][0]
exam["date"] = prompt( exam["date"] = prompt(
"Date de l'évaluation (%y%m%d): ", "Date de l'évaluation (%y%m%d): ",
default=kwrd.get("date", datetime.today()).strftime("%y%m%d"), default=kwrd.get("date", datetime.today()).strftime("%y%m%d"),
@ -112,98 +137,100 @@ def prompt_exam(**kwrd):
return exam return exam
@prompt_until_validate @prompt_until_validate()
def prompt_exercise(number=1, **kwrd): def prompt_exercise(number=1, **kwrd):
try: try:
kwrd["name"] kwrd["name"]
except KeyError: except KeyError:
print("Nouvel exercice") print(HTML("<b>Nouvel exercice</b>"))
else: else:
print(f"Modification de la questions {kwrd['name']}") print(HTML(f"<b>Modification de l'exercice: {kwrd['name']}</b>"))
exercise = {} exercise = {}
exercise["name"] = prompt( exercise["name"] = prompt(
"Nom de l'exercice", default=kwrd.get("name", f"Exercice {number}") "Nom de l'exercice: ", default=kwrd.get("name", f"Exercice {number}")
) )
exercise["questions"] = [] exercise["questions"] = []
try: try:
kwrd["questions"] kwrd["questions"][0]
except KeyError: except KeyError:
last_question_id = "1a" last_question_id = "1a"
except IndexError:
last_question_id = "1a"
else: else:
for ques in kwrd["questions"]: for ques in kwrd["questions"]:
try: try:
exercise["questions"].append(prompt_question()) exercise["questions"].append(prompt_question(**ques))
except CancelError: except CancelError:
print("Cette question a été supprimée") print("Cette question a été supprimée")
last_question_id = exercise["questions"][-1]["id"] last_question_id = exercise["questions"][-1]["id"]
# append = prompt("Ajouter une élément de notation", appending = prompt_validate(
# { question="Ajouter un élément de notation? ", style="appending"
# "message": "Ajouter un élément de notation", )
# "type": "confirm", while appending:
# "name": "append",
#
# ]
while prompt(append)["append"]:
try: try:
exercise["questions"].append(prompt_question(last_question_id)) exercise["questions"].append(prompt_question(last_question_id))
except CancelError: except CancelError:
print("Cette question a été supprimée") print("Cette question a été supprimée")
else: else:
last_question_id = exercise["questions"][-1]["id"] last_question_id = exercise["questions"][-1]["id"]
appending = prompt_validate(
question="Ajouter un élément de notation? ", style="appending"
)
return exercise return exercise
@prompt_until_validate_or_cancel @prompt_until_validate(cancelable=True)
def prompt_question(last_question_id="1a", **kwrd): def prompt_question(last_question_id="1a", **kwrd):
try: try:
kwrd["id"] kwrd["id"]
except KeyError: except KeyError:
print("Nouvelle question") print(HTML("<b>Nouvel élément de notation</b>"))
else: else:
print(f"Modification de la questions {kwrd['id']}") print(
HTML(
f"<b>Modification de l'élément {kwrd['id']} ({kwrd['commentaire']})</b>"
)
)
questions = [ question = {}
{ question["id"] = prompt(
"message": "Identifiant de la question", "Identifiant de la question: ",
"type": "input", default=kwrd.get("id", "1a"),
"name": "id", )
"default": kwrd.get("id", "1a"),
}, question["competence"] = prompt(
{ "Competence: ",
"message": "Competence", default=kwrd.get("competence", "Cal"),
"type": "input", # validate
"name": "competence", # completer
"default": kwrd.get("competence", "Cal"), )
},
{ question["theme"] = prompt(
"message": "Domaine", "Domaine: ",
"type": "input", default=kwrd.get("theme", ""),
"name": "theme", # completer
"default": kwrd.get("domain", ""), )
},
{ question["comment"] = prompt(
"message": "Commentaire", "Commentaire: ",
"type": "input", default=kwrd.get("comment", ""),
"name": "comment", )
"default": kwrd.get("comment", ""),
}, question["is_leveled"] = prompt(
{ "Évaluation par niveau: ",
"message": "Évaluation par niveau", default=kwrd.get("is_leveled", "1"),
"type": "confirm", # validate
"name": "is_leveled", )
"default": kwrd.get("is_leveled", True),
}, question["score_rate"] = prompt(
{ "Barème: ",
"message": "Bareme", default=kwrd.get("score_rate", "1"),
"type": "input", # validate
"name": "score_rate", )
"default": kwrd.get("score_rate", "1"),
"validate": lambda x: x.isdigit(), return question
},
]
return prompt(questions)

View File

@ -8,7 +8,7 @@ import papermill as pm
import pandas as pd import pandas as pd
from datetime import datetime from datetime import datetime
from .getconfig import config from .getconfig import config, CONFIGPATH
from .prompts import prompt_exam, prompt_exercise from .prompts import prompt_exam, prompt_exercise
from ..config import NO_ST_COLUMNS from ..config import NO_ST_COLUMNS
@ -69,11 +69,10 @@ def new_exam():
for student in students: for student in students:
base_df[student] = "" base_df[student] = ""
dest = ( path = Path(config["source"]) / exam["tribe"]["name"]
Path(config["source"]) path.mkdir(exist_ok=True)
/ exam["tribe"]["name"]
/ f"{exam['date'].strftime('%y%m%d')}_{exam['name']}.csv" dest = path / f"{exam['date'].strftime('%y%m%d')}_{exam['name']}.csv"
)
base_df.to_csv(dest, index=False) base_df.to_csv(dest, index=False)
print(f"Le fichier note a été enregistré à {dest}") print(f"Le fichier note a été enregistré à {dest}")

View File

@ -1,4 +1,4 @@
pandas pandas
click click
papermill papermill
PyInquirer prompt_toolkit