sage/main.py

337 lines
8.7 KiB
Python
Raw Normal View History

2019-03-25 08:19:04 +00:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Name: main.py
Author: Jeff LANCE <jeff.lance@mala.fr>
Date: 29/03/2018
Générateur de plan de classe.
Cette application nécessite une liste d'élèves donnée sous forme d'un ficher
CSV d'en-tête "ID";"NAME";"CHAT LEVEL", avec:
ID: Numéro d'identification arbitraire de l'élève.
NAME: Nom de l'élève.
CHAT LEVEL: Coefficient de bavardage de l'élève.
"""
# Imports de modules
import random
from itertools import islice
from sage import SeatingPlan, Engine, interface
# Instanciation des objets
seatingplan = SeatingPlan()
engine = Engine()
# Fonctions du menu
def mainmenu_option1():
""" Option 1 du menu principal.
Redimensionne le plan de classe selon le nombre de rangées et de colonnes
demandés à l'utilisateur.
:return:
Rien.
"""
# on demande les nouvelles dimensions du plan de classe
row, col = interface.console_ask_seatingplan_size()
if row is not None and col is not None:
# on redimensionne le plan de classe
seatingplan.resize(row, col)
def mainmenu_option2():
"""Option 2 du menu principal.
Demande à l'utilisateur le fichier contenant la liste des élèves à
intégrer dans le plan de classe.
:return:
Rien ou la liste des élèves.
:rtype: list
"""
filepath = interface.dialog_ask_file()
# L'utilisateur a-t'il annulé sa recherche de fichier ?
if filepath:
# Non, on renvoie le fichier ouvert
dataframe = interface.open_file(filepath)
students_list = interface.load_users(dataframe, seatingplan)
return students_list
else:
# Oui
print('Opération annulée')
def mainmenu_option3(students_list):
"""Option 3 du menu principal.
Affiche la liste des élèves dans la console, si celle-ci n'est pas vide.
:param students_list:
Liste des élèves.
:type students_list: list
:return:
Rien.
"""
if students_list:
# on affiche la liste des élèves
interface.console_display_students(students_list)
else:
print("Votre liste d'élèves est vide")
def mainmenu_option4(students_list):
"""Option 4 du menu principal.
Demande à l'utilisateur l'identifiant d'un élève ainsi que les coordonnées
d'une place dans le plan de classe.
Positionne cet élève à la place indiquée.
:param students_list:
Liste des élèves.
:type students_list: list
:return:
Rien.
"""
# Si la liste contient des élèves
if students_list:
# On demande l'ID de l'élève
student_id = interface.console_ask_student_id()
# Si on a pu récupérer une valeur
if student_id is not None:
# On récupère l'élève associé à l'ID
student = students_list[student_id]
# On demande le siège où l'asseoir
2022-03-05 17:09:26 +00:00
student_seat = interface.console_ask_student_seat(seatingplan)
2019-03-25 08:19:04 +00:00
# Si on a pu récupérer une valeur
if seatingplan.is_a_seat(student_seat):
# On positionne l'élève
seatingplan.place_student(student, student_seat)
else:
print("Votre liste d'élèves est vide")
def mainmenu_option5(students_list):
"""Option 5 du menu principal.
Demande à l'utilisateur l'identifiant d'un élève.
Retire cet élève du plan de classe.
:param students_list:
Liste des élèves.
:type students_list: list
:return:
Rien.
"""
# Si la liste contient des élèves
if students_list:
# on demande l'ID de l'élève
student_id = interface.console_ask_student_id()
# Si on a pu récupérer une valeur
if student_id is not None:
# On récupère l'élève associé à l'ID
student = students_list[student_id]
# Et on le retire de sa place
seatingplan.remove_student(student)
else:
print("Votre liste d'élèves est vide")
def mainmenu_option6(students_list):
"""Option 6 du menu principal.
Demande à l'utilisateur les identifiants de deux élèves.
Échange les places de ces élèves.
:param students_list:
Liste des élèves.
:type students_list: list
:return:
Rien.
"""
# On demande l'ID du 1er élève
print('1er élève')
id1 = interface.console_ask_student_id()
# Si on a pu récupérer une valeur
if id1 is not None:
# On demande l'ID du 2nd élève
print('2ème élève')
id2 = interface.console_ask_student_id()
# Si on a pu récupérer une valeur
if id2 is not None:
# On échange les deux élèves de place
seatingplan.swap_students(students_list[id1], students_list[id2])
def mainmenu_option7(students_list):
"""Option 7 du menu principal.
Démarre une recherche des agencements possibles des élèves dans le plan
de classe.
:param students_list:
Liste des élèves.
:type students_list: list
:return:
Plan de classe possible.
:rtype: iterator
"""
2022-03-05 17:09:26 +00:00
number_of_proposals = input('Nombre maximal de propositions à faire (5 par défaut) : ')
number_of_proposals = int(number_of_proposals or "5")
2019-03-25 08:19:04 +00:00
print('Presser Ctrl-C pour interrompre...')
try:
return iter(list(islice(engine.solve(seatingplan, students_list),
number_of_proposals)))
# return iter(list(engine.solve(seatingplan, students_list)))
except KeyboardInterrupt:
pass
else:
print('Appuyer sur "n" pour afficher la disposition suivante...')
def mainmenu_option8():
"""Option 8 du menu principal.
Efface le contenu du plan de classe courant.
:return: None
"""
print('Effacement du plan de classe...')
2022-03-05 17:09:26 +00:00
# engine.flush_seatingplan(seatingplan)
seatingplan.flush()
2019-03-25 08:19:04 +00:00
def mainmenu_option_next(solution):
"""Option n du menu principal.
Affiche l'agencement de plan de classe possible suivant.
:param solution:
Agencement de plan de classe.
:type solution: dict
:return:
Rien.
"""
if solution:
try:
2022-03-05 17:09:26 +00:00
# engine.flush_seatingplan(seatingplan)
seatingplan.flush()
# engine.write_solution_to_seatingplan(next(solution), seatingplan)
seatingplan.write_solution(next(solution))
2019-03-25 08:19:04 +00:00
except StopIteration:
print("Il n'y a plus de propositions de placement")
else:
print("Vous devez le calcul de solutions d'abord")
2022-03-05 17:09:26 +00:00
def mainmenu_option9():
"""Option 9 du menu principal.
:return: None
"""
print('Teste plan de classe...')
print(engine.verify_solution(seatingplan))
2019-03-25 08:19:04 +00:00
def settingsmenu():
""" Menu paramètres.
Affiche le menu paramètres dans la console.
:return:
Rien.
"""
while True:
interface.console_display_settingsmenu(engine)
command = input('>>> ')
if (command == 'b'):
return None
elif not command:
print('Choisissez une option')
else:
interface.console_set_engine_levels(engine, command)
def mainmenu():
""" Menu principal.
Affiche le menu principal dans la console.
:return:
Rien.
"""
while True:
# affichage de l'interface et du prompt
interface.console_display(seatingplan)
command = input('>>> ')
if (command == '1'):
mainmenu_option1()
elif (command == '2'):
students_list = mainmenu_option2()
elif (command == '3'):
mainmenu_option3(students_list)
elif (command == '4'):
mainmenu_option4(students_list)
elif (command == '5'):
mainmenu_option5(students_list)
elif (command == '6'):
mainmenu_option6(students_list)
elif (command == '7'):
proposals = mainmenu_option7(students_list)
2022-03-05 17:09:26 +00:00
# On affiche la première solution
mainmenu_option_next(proposals)
2019-03-25 08:19:04 +00:00
elif (command == '8'):
mainmenu_option8()
2022-03-05 17:09:26 +00:00
elif (command == '9'):
mainmenu_option9()
2019-03-25 08:19:04 +00:00
elif (command == 'n'):
mainmenu_option_next(proposals)
elif (command == 'DEBUG'):
def f(s):
if s is not None:
return s.name
return s
# DEBUG: print solutions
2022-03-05 17:09:26 +00:00
try:
for s in engine.solve(seatingplan, students_list):
print({p: f(s) for p, s in s.items()})
except KeyboardInterrupt:
pass
2019-03-25 08:19:04 +00:00
# DEBUG
elif (command == 's'):
settingsmenu()
elif (command == 'q'):
exit(0)
mainmenu()