111 lines
3.5 KiB
Python
111 lines
3.5 KiB
Python
import argparse
|
||
import typing as t
|
||
import random
|
||
from pathlib import Path
|
||
import jinja2 as j2
|
||
|
||
from .config import Task, Category, Config
|
||
from . import util
|
||
|
||
|
||
def constituer_groupes(choristes: list[str]) -> list[list[str]]:
|
||
"""Répartir aléatoirement les gens en groupes"""
|
||
TAILLE_GROUPE: int = 4
|
||
nb_choristes = len(choristes)
|
||
|
||
groupes: list[list[str]] = []
|
||
|
||
random.shuffle(choristes)
|
||
pos = 0
|
||
for _ in range(nb_choristes // TAILLE_GROUPE):
|
||
groupes.append(choristes[pos : pos + TAILLE_GROUPE])
|
||
pos += TAILLE_GROUPE
|
||
|
||
reste = choristes[pos:]
|
||
|
||
if len(reste) == TAILLE_GROUPE - 1:
|
||
groupes.append(reste)
|
||
else:
|
||
for gid, pers in enumerate(reste):
|
||
groupes[gid].append(pers)
|
||
|
||
for groupe in groupes:
|
||
groupe.sort()
|
||
random.shuffle(groupes)
|
||
|
||
return groupes
|
||
|
||
|
||
def assigner_taches(task: Category | Task, group_count: int, cur_group: int = 0) -> int:
|
||
"""Assigne les tâches aux groupes (round-robin)"""
|
||
if isinstance(task, Task):
|
||
task.assigned = list(
|
||
map(
|
||
lambda x: x % group_count,
|
||
range(cur_group, cur_group + task.nb_groups),
|
||
)
|
||
)
|
||
return (cur_group + task.nb_groups) % group_count
|
||
for subtask in task.tasks:
|
||
cur_group = assigner_taches(subtask, group_count, cur_group)
|
||
return cur_group
|
||
|
||
|
||
def export_short_md(config: Config, groupes: list[list[str]]) -> str:
|
||
"""Exporte la liste des tâches au format Markdown court (pour vérification)"""
|
||
|
||
def export_taskcat(grp: Task | Category) -> str:
|
||
if isinstance(grp, Task):
|
||
assert grp.assigned is not None
|
||
return f'* {grp.qualified_name}: {", ".join(map(lambda x: str(x+1), grp.assigned))}'
|
||
out = "\n" + "#" * (2 + grp.depth) + f" {grp.name}"
|
||
if grp.time:
|
||
out += f" ({grp.time})"
|
||
out += "\n\n"
|
||
if grp.intro:
|
||
out += grp.intro + "\n\n"
|
||
out += "\n".join(map(export_taskcat, grp.tasks))
|
||
return out
|
||
|
||
out = "## Groupes\n\n"
|
||
for g_id, group in enumerate(groupes):
|
||
out += f"* Groupe {g_id+1} : " + ", ".join(group) + "\n"
|
||
|
||
out += "\n## Tâches\n"
|
||
|
||
out += "\n".join(map(export_taskcat, config.taches.tasks))
|
||
|
||
return out
|
||
|
||
|
||
def export_latex(config: Config, groupes: list[list[str]]) -> str:
|
||
"""Exporter la liste des tâches en LaTeX (à insérer dans un template)"""
|
||
j2_env = util.j2_environment()
|
||
template = j2_env.get_template("repartition.tex.j2")
|
||
env = {
|
||
"groupes": {g_id: grp for g_id, grp in enumerate(groupes)},
|
||
"taches": config.taches.tasks,
|
||
"couleur": util.group_colors,
|
||
}
|
||
return template.render(**env)
|
||
|
||
|
||
def main():
|
||
parser = argparse.ArgumentParser("Répartition des tâches")
|
||
parser.add_argument("taches", help="Fichier yaml contenant les tâches")
|
||
parser.add_argument("choristes", help="Fichier CSV contenant les choristes")
|
||
parser.add_argument("--to-tex", help="Exporter vers un fichier LaTeX")
|
||
parser.add_argument(
|
||
"--to-short-md",
|
||
help="Exporter vers un fichier Markdown (pour vérification uniquement)",
|
||
)
|
||
args = parser.parse_args()
|
||
|
||
config = Config(args.taches, args.choristes)
|
||
groupes = constituer_groupes(config.choristes)
|
||
assigner_taches(config.taches, len(groupes))
|
||
|
||
if args.to_tex:
|
||
util.write_to_file(args.to_tex, export_latex(config, groupes))
|
||
if args.to_short_md:
|
||
util.write_to_file(args.to_short_md, export_short_md(config, groupes))
|