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

View File

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

View File

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