1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2025-05-18 18:12:47 +00:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Emmy D'Anello
bee04b0522
Update synthesis sheets templates
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
2024-03-24 20:24:57 +01:00
Emmy D'Anello
b6d54d27cd
Update ODS note sheets
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
2024-03-24 20:05:07 +01:00
8 changed files with 111 additions and 66 deletions

View File

@ -17,6 +17,7 @@ from django.db.models.functions import Concat
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from pypdf import PdfReader from pypdf import PdfReader
from registration.models import VolunteerRegistration
from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament from .models import Note, Participation, Passage, Pool, Solution, Synthesis, Team, Tournament
@ -291,7 +292,7 @@ class UploadNotesForm(forms.Form):
def process(self, csvfile: Iterable[str], cleaned_data: dict): def process(self, csvfile: Iterable[str], cleaned_data: dict):
parsed_notes = {} parsed_notes = {}
valid_lengths = [1 + 6 * 3, 1 + 7 * 4, 1 + 6 * 5] # Per pool sizes valid_lengths = [2 + 6 * 3, 2 + 7 * 4, 2 + 6 * 5] # Per pool sizes
pool_size = 0 pool_size = 0
line_length = 0 line_length = 0
for line in csvfile: for line in csvfile:
@ -310,29 +311,24 @@ class UploadNotesForm(forms.Form):
name = line[0] name = line[0]
if name.lower() in ["rôle", "juré", "moyenne", "coefficient", "sous-total", "équipe", "equipe"]: if name.lower() in ["rôle", "juré", "moyenne", "coefficient", "sous-total", "équipe", "equipe"]:
continue continue
notes = line[1:line_length] notes = line[2:line_length]
if not all(s.isnumeric() or s[0] == '-' and s[1:].isnumeric() for s in notes): if not all(s.isnumeric() or s[0] == '-' and s[1:].isnumeric() for s in notes):
continue continue
notes = list(map(int, notes)) notes = list(map(int, notes))
max_notes = pool_size * ([20, 16, 9, 10, 9, 10] + ([4] if pool_size == 4 else [])) max_notes = pool_size * ([20, 20, 10, 10, 10, 10] + ([4] if pool_size == 4 else []))
for n, max_n in zip(notes, max_notes): for n, max_n in zip(notes, max_notes):
if n > max_n: if n > max_n:
self.add_error('file', self.add_error('file',
_("The following note is higher of the maximum expected value:") _("The following note is higher of the maximum expected value:")
+ str(n) + " > " + str(max_n)) + str(n) + " > " + str(max_n))
# Search by "{first_name} {last_name}" # Search by volunteer id
jury = User.objects.annotate(full_name=Concat('first_name', Value(' '), 'last_name', jury = VolunteerRegistration.objects.filter(pk=line[1])
output_field=CharField())) \
.filter(full_name=name.replace('', '\''), registration__volunteerregistration__isnull=False)
if jury.count() != 1: if jury.count() != 1:
self.add_error('file', _("The following user was not found:") + " " + name) raise ValidationError({'file': _("The following user was not found:") + " " + name})
continue
jury = jury.get() jury = jury.get()
parsed_notes[jury] = notes
vr = jury.registration
parsed_notes[vr] = notes
cleaned_data['parsed_notes'] = parsed_notes cleaned_data['parsed_notes'] = parsed_notes

View File

@ -680,7 +680,7 @@ class Passage(models.Model):
@property @property
def average_defender(self) -> float: def average_defender(self) -> float:
return self.average_defender_writing + (2 - 0.5 * self.defender_penalties) * self.average_defender_oral return self.average_defender_writing + (1.6 - 0.4 * self.defender_penalties) * self.average_defender_oral
@property @property
def average_opponent_writing(self) -> float: def average_opponent_writing(self) -> float:
@ -692,7 +692,7 @@ class Passage(models.Model):
@property @property
def average_opponent(self) -> float: def average_opponent(self) -> float:
return self.average_opponent_writing + 2 * self.average_opponent_oral return 0.9 * self.average_opponent_writing + 2 * self.average_opponent_oral
@property @property
def average_reporter_writing(self) -> float: def average_reporter_writing(self) -> float:
@ -704,7 +704,7 @@ class Passage(models.Model):
@property @property
def average_reporter(self) -> float: def average_reporter(self) -> float:
return self.average_reporter_writing + self.average_reporter_oral return 0.9 * self.average_reporter_writing + self.average_reporter_oral
@property @property
def average_observer(self) -> float: def average_observer(self) -> float:

View File

@ -9,6 +9,7 @@
{% trans "Templates:" %} {% trans "Templates:" %}
<a class="alert-link" href="{% static "Fiche_synthèse.pdf" %}"> PDF</a> <a class="alert-link" href="{% static "Fiche_synthèse.pdf" %}"> PDF</a>
<a class="alert-link" href="{% static "Fiche_synthèse.tex" %}"> TEX</a> <a class="alert-link" href="{% static "Fiche_synthèse.tex" %}"> TEX</a>
<a class="alert-link" href="{% static "Fiche_synthèse.odt" %}"> ODT</a>
<a class="alert-link" href="{% static "Fiche_synthèse.docx" %}" title="{% trans "Warning: non-free format" %}"> DOCX</a> <a class="alert-link" href="{% static "Fiche_synthèse.docx" %}" title="{% trans "Warning: non-free format" %}"> DOCX</a>
</div> </div>
{% csrf_token %} {% csrf_token %}

View File

@ -1176,6 +1176,10 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
first_col_style.addElement(TableColumnProperties(columnwidth="9cm", breakbefore="auto")) first_col_style.addElement(TableColumnProperties(columnwidth="9cm", breakbefore="auto"))
doc.automaticstyles.addElement(first_col_style) doc.automaticstyles.addElement(first_col_style)
jury_id_style = Style(name="co_jury_id", family="table-column")
jury_id_style.addElement(TableColumnProperties(columnwidth="1cm", breakbefore="auto"))
doc.automaticstyles.addElement(jury_id_style)
col_style = Style(name="co2", family="table-column") col_style = Style(name="co2", family="table-column")
col_style.addElement(TableColumnProperties(columnwidth="2.6cm", breakbefore="auto")) col_style.addElement(TableColumnProperties(columnwidth="2.6cm", breakbefore="auto"))
doc.automaticstyles.addElement(col_style) doc.automaticstyles.addElement(col_style)
@ -1188,6 +1192,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
doc.spreadsheet.addElement(table) doc.spreadsheet.addElement(table)
table.addElement(TableColumn(stylename=first_col_style)) table.addElement(TableColumn(stylename=first_col_style))
table.addElement(TableColumn(stylename=jury_id_style))
for i in range(line_length): for i in range(line_length):
table.addElement(TableColumn(stylename=obs_col_style if pool_size == 4 table.addElement(TableColumn(stylename=obs_col_style if pool_size == 4
@ -1198,7 +1203,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(header_pb) table.addElement(header_pb)
problems_tc = TableCell(valuetype="string", stylename=title_style_topleft) problems_tc = TableCell(valuetype="string", stylename=title_style_topleft)
problems_tc.addElement(P(text="Problème")) problems_tc.addElement(P(text="Problème"))
problems_tc.setAttribute('numbercolumnsspanned', "2")
header_pb.addElement(problems_tc) header_pb.addElement(problems_tc)
header_pb.addElement(CoveredTableCell())
for passage in self.object.passages.all(): for passage in self.object.passages.all():
tc = TableCell(valuetype="string", stylename=title_style_topleftright) tc = TableCell(valuetype="string", stylename=title_style_topleftright)
tc.addElement(P(text=f"Problème {passage.solution_number}")) tc.addElement(P(text=f"Problème {passage.solution_number}"))
@ -1212,7 +1219,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(header_role) table.addElement(header_role)
role_tc = TableCell(valuetype="string", stylename=title_style_left) role_tc = TableCell(valuetype="string", stylename=title_style_left)
role_tc.addElement(P(text="Rôle")) role_tc.addElement(P(text="Rôle"))
role_tc.setAttribute('numbercolumnsspanned', "2")
header_role.addElement(role_tc) header_role.addElement(role_tc)
header_role.addElement(CoveredTableCell())
for i in range(pool_size): for i in range(pool_size):
defender_tc = TableCell(valuetype="string", stylename=title_style_left) defender_tc = TableCell(valuetype="string", stylename=title_style_left)
defender_tc.addElement(P(text="Défenseur⋅se")) defender_tc.addElement(P(text="Défenseur⋅se"))
@ -1243,7 +1252,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(header_notes) table.addElement(header_notes)
jury_tc = TableCell(valuetype="string", value="Juré⋅e", stylename=title_style_botleft) jury_tc = TableCell(valuetype="string", value="Juré⋅e", stylename=title_style_botleft)
jury_tc.addElement(P(text="Juré⋅e")) jury_tc.addElement(P(text="Juré⋅e"))
jury_tc.setAttribute('numbercolumnsspanned', "2")
header_notes.addElement(jury_tc) header_notes.addElement(jury_tc)
header_notes.addElement(CoveredTableCell())
for i in range(pool_size): for i in range(pool_size):
defender_w_tc = TableCell(valuetype="string", stylename=title_style_botleft) defender_w_tc = TableCell(valuetype="string", stylename=title_style_botleft)
@ -1251,11 +1262,11 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
header_notes.addElement(defender_w_tc) header_notes.addElement(defender_w_tc)
defender_o_tc = TableCell(valuetype="string", stylename=title_style_bot) defender_o_tc = TableCell(valuetype="string", stylename=title_style_bot)
defender_o_tc.addElement(P(text="Oral (/16)")) defender_o_tc.addElement(P(text="Oral (/20)"))
header_notes.addElement(defender_o_tc) header_notes.addElement(defender_o_tc)
opponent_w_tc = TableCell(valuetype="string", stylename=title_style_bot) opponent_w_tc = TableCell(valuetype="string", stylename=title_style_bot)
opponent_w_tc.addElement(P(text="Écrit (/9)")) opponent_w_tc.addElement(P(text="Écrit (/10)"))
header_notes.addElement(opponent_w_tc) header_notes.addElement(opponent_w_tc)
opponent_o_tc = TableCell(valuetype="string", stylename=title_style_bot) opponent_o_tc = TableCell(valuetype="string", stylename=title_style_bot)
@ -1263,7 +1274,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
header_notes.addElement(opponent_o_tc) header_notes.addElement(opponent_o_tc)
reporter_w_tc = TableCell(valuetype="string", stylename=title_style_bot) reporter_w_tc = TableCell(valuetype="string", stylename=title_style_bot)
reporter_w_tc.addElement(P(text="Écrit (/9)")) reporter_w_tc.addElement(P(text="Écrit (/10)"))
header_notes.addElement(reporter_w_tc) header_notes.addElement(reporter_w_tc)
reporter_o_tc = TableCell(valuetype="string", reporter_o_tc = TableCell(valuetype="string",
@ -1285,6 +1296,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
name_tc = TableCell(valuetype="string", stylename=style_leftright) name_tc = TableCell(valuetype="string", stylename=style_leftright)
name_tc.addElement(P(text=f"{jury.user.first_name} {jury.user.last_name}")) name_tc.addElement(P(text=f"{jury.user.first_name} {jury.user.last_name}"))
jury_row.addElement(name_tc) jury_row.addElement(name_tc)
jury_id_tc = TableCell(valuetype="float", value=jury.pk, stylename=style_leftright)
jury_id_tc.addElement(P(text=str(jury.pk)))
jury_row.addElement(jury_id_tc)
for passage in self.object.passages.all(): for passage in self.object.passages.all():
notes = Note.objects.get(jury=jury, passage=passage) notes = Note.objects.get(jury=jury, passage=passage)
@ -1297,14 +1311,16 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
jury_size = self.object.juries.count() jury_size = self.object.juries.count()
min_row = 4 min_row = 4
max_row = 4 + jury_size - 1 max_row = 4 + jury_size - 1
min_column = 2 min_column = 3
# Add line for averages # Add line for averages
average_row = TableRow() average_row = TableRow()
table.addElement(average_row) table.addElement(average_row)
average_tc = TableCell(valuetype="string", stylename=title_style_topleftright) average_tc = TableCell(valuetype="string", stylename=title_style_topleftright)
average_tc.addElement(P(text="Moyenne")) average_tc.addElement(P(text="Moyenne"))
average_tc.setAttribute('numbercolumnsspanned', "2")
average_row.addElement(average_tc) average_row.addElement(average_tc)
average_row.addElement(CoveredTableCell())
for i, passage in enumerate(self.object.passages.all()): for i, passage in enumerate(self.object.passages.all()):
for j, note in enumerate(passage.averages): for j, note in enumerate(passage.averages):
tc = TableCell(valuetype="float", value=note, tc = TableCell(valuetype="float", value=note,
@ -1321,17 +1337,19 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(coeff_row) table.addElement(coeff_row)
coeff_tc = TableCell(valuetype="string", stylename=title_style_leftright) coeff_tc = TableCell(valuetype="string", stylename=title_style_leftright)
coeff_tc.addElement(P(text="Coefficient")) coeff_tc.addElement(P(text="Coefficient"))
coeff_tc.setAttribute('numbercolumnsspanned', "2")
coeff_row.addElement(coeff_tc) coeff_row.addElement(coeff_tc)
coeff_row.addElement(CoveredTableCell())
for passage in self.object.passages.all(): for passage in self.object.passages.all():
defender_w_tc = TableCell(valuetype="float", value=1, stylename=style_left) defender_w_tc = TableCell(valuetype="float", value=1, stylename=style_left)
defender_w_tc.addElement(P(text="1")) defender_w_tc.addElement(P(text="1"))
coeff_row.addElement(defender_w_tc) coeff_row.addElement(defender_w_tc)
defender_o_tc = TableCell(valuetype="float", value=2 - 0.5 * passage.defender_penalties, stylename=style) defender_o_tc = TableCell(valuetype="float", value=1.6 - 0.4 * passage.defender_penalties, stylename=style)
defender_o_tc.addElement(P(text=str(2 - 0.5 * passage.defender_penalties))) defender_o_tc.addElement(P(text=str(2 - 0.4 * passage.defender_penalties)))
coeff_row.addElement(defender_o_tc) coeff_row.addElement(defender_o_tc)
opponent_w_tc = TableCell(valuetype="float", value=1, stylename=style) opponent_w_tc = TableCell(valuetype="float", value=0.9, stylename=style)
opponent_w_tc.addElement(P(text="1")) opponent_w_tc.addElement(P(text="1"))
coeff_row.addElement(opponent_w_tc) coeff_row.addElement(opponent_w_tc)
@ -1339,7 +1357,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
opponent_o_tc.addElement(P(text="2")) opponent_o_tc.addElement(P(text="2"))
coeff_row.addElement(opponent_o_tc) coeff_row.addElement(opponent_o_tc)
reporter_w_tc = TableCell(valuetype="float", value=1, stylename=style) reporter_w_tc = TableCell(valuetype="float", value=0.9, stylename=style)
reporter_w_tc.addElement(P(text="1")) reporter_w_tc.addElement(P(text="1"))
coeff_row.addElement(reporter_w_tc) coeff_row.addElement(reporter_w_tc)
@ -1358,7 +1376,9 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(subtotal_row) table.addElement(subtotal_row)
subtotal_tc = TableCell(valuetype="string", stylename=title_style_botleft) subtotal_tc = TableCell(valuetype="string", stylename=title_style_botleft)
subtotal_tc.addElement(P(text="Sous-total")) subtotal_tc.addElement(P(text="Sous-total"))
subtotal_tc.setAttribute('numbercolumnsspanned', "2")
subtotal_row.addElement(subtotal_tc) subtotal_row.addElement(subtotal_tc)
subtotal_row.addElement(CoveredTableCell())
for i, passage in enumerate(self.object.passages.all()): for i, passage in enumerate(self.object.passages.all()):
def_w_col = getcol(min_column + passage_width * i) def_w_col = getcol(min_column + passage_width * i)
def_o_col = getcol(min_column + passage_width * i + 1) def_o_col = getcol(min_column + passage_width * i + 1)
@ -1406,6 +1426,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
table.addElement(scores_header) table.addElement(scores_header)
team_tc = TableCell(valuetype="string", stylename=title_style_topbotleft) team_tc = TableCell(valuetype="string", stylename=title_style_topbotleft)
team_tc.addElement(P(text="Équipe")) team_tc.addElement(P(text="Équipe"))
team_tc.setAttribute('numbercolumnsspanned', "2")
scores_header.addElement(team_tc) scores_header.addElement(team_tc)
problem_tc = TableCell(valuetype="string", stylename=title_style_topbot) problem_tc = TableCell(valuetype="string", stylename=title_style_topbot)
problem_tc.addElement(P(text="Problème")) problem_tc.addElement(P(text="Problème"))
@ -1452,6 +1473,7 @@ class PoolNotesTemplateView(VolunteerMixin, DetailView):
team_tc = TableCell(valuetype="string", team_tc = TableCell(valuetype="string",
stylename=style_botleft if passage.position == pool_size else style_left) stylename=style_botleft if passage.position == pool_size else style_left)
team_tc.addElement(P(text=f"{passage.defender.team.name} ({passage.defender.team.trigram})")) team_tc.addElement(P(text=f"{passage.defender.team.name} ({passage.defender.team.trigram})"))
team_tc.setAttribute('numbercolumnsspanned', "2")
team_row.addElement(team_tc) team_row.addElement(team_tc)
problem_tc = TableCell(valuetype="string", problem_tc = TableCell(valuetype="string",

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -49,20 +49,19 @@ Tour \underline{~~~~} poule \underline{~~~~}
\medskip \medskip
Problème \underline{~~~~} défendu par l'équipe \underline{~~~~~~~~~~~~~~~~~~~~~~~~} Problème \underline{~~~~} défendu par l'équipe \underline{~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
\medskip \medskip
Synthèse par l'équipe \underline{~~~~~~~~~~~~~~~~~~~~~~~~} dans le rôle de : ~ $\square$ Opposant ~ $\square$ Rapporteur Synthèse par l'équipe \underline{~~~~~~~~~~~~~~~~~~~~~~~~~~~~} dans le rôle de : ~ $\square$ Opposante ~ $\square$ Rapporteure
\section*{Questions traitées}
\begin{tabular}{r c l} \section*{\'Evaluation question par question de la solution}
\noindent
\begin{tabular}{|c|c|c|c|c|c|} \begin{tabular}{|c|c|c|c|c|c|}
\hline \hline
Question ~ & ER & ~PR~ & QE & NT \\ Question & ER & ~PR~ & ~QE~ & NT \\
\hline
& & & & \\
\hline \hline
& & & & \\ & & & & \\
\hline \hline
@ -83,10 +82,10 @@ Synthèse par l'équipe \underline{~~~~~~~~~~~~~~~~~~~~~~~~} dans le rôle de :
& & & & \\ & & & & \\
\hline \hline
\end{tabular} \end{tabular}
& ~~ & \hfill
\begin{tabular}{|c|c|c|c|c|c|} \begin{tabular}{|c|c|c|c|c|c|}
\hline \hline
Question ~ & ER & ~PR~ & QE & NT \\ Question & ER & ~PR~ & ~QE~ & NT \\
\hline \hline
& & & & \\ & & & & \\
\hline \hline
@ -106,44 +105,36 @@ Synthèse par l'équipe \underline{~~~~~~~~~~~~~~~~~~~~~~~~} dans le rôle de :
\hline \hline
& & & & \\ & & & & \\
\hline \hline
& & & & \\ \end{tabular}
\hline \hfill
\end{tabular} \\ \begin{minipage}{.27\textwidth}
ER : entièrement résolue, ni erreur, ni manque mathématique
& & \\
ER : entièrement résolue & & PR : partiellement résolue \\
\smallskip \smallskip
QE : quelques éléments de réponse & & NT : non traitée PR : partiellement résolue
\end{tabular}
~
\smallskip \smallskip
Remarque : il est possible de cocher entre les cases pour un cas intermédiaire. QE : quelques éléments de réponse
\section*{Evaluation qualitative de la solution} \smallskip
Donnez votre avis concernant la solution. Mettez notamment en valeur les points positifs (des idées NT : non traitée
importantes, originales, etc.) et précisez ce qui aurait pu améliorer la solution.
\vfill
\textbf{Evaluation générale :} ~ $\square$ Excellente ~ $\square$ Bonne ~ $\square$ Suffisante ~ $\square$ Passable
\newpage
\section*{Erreurs et imprécisions}
Listez ci-dessous les cinq erreurs et/ou imprécisions les plus importantes selon vous, par ordre d'importance, en précisant la
question concernée, la page, le paragraphe et le type de remarque.
\bigskip \bigskip
1. Question \underline{~~~~} Page \underline{~~~~} Paragraphe \underline{~~~~} Remarque : il est possible de cocher entre les cases pour un cas intermédiaire.
\end{minipage}
\section*{Erreurs et imprécisions}
Listez ci-dessous par ordre décroissant d'importance au plus quatre erreurs et/ou imprécisions selon vous, en précisant la question concernée, la page, le paragraphe et le type de remarque.
\medskip
1. Question \underline{~~~~~~} Page \underline{~~~~~~} Paragraphe \underline{~~~~~~}
$\square$ Erreur majeure ~ $\square$ Erreur mineure ~ $\square$ Imprécision ~ $\square$ Autre : \underline{~~~~~~~~} $\square$ Erreur majeure ~ $\square$ Erreur mineure ~ $\square$ Imprécision ~ $\square$ Autre : \underline{~~~~~~~~}
@ -151,7 +142,7 @@ Description :
\vfill \vfill
2. Question \underline{~~~~} Page \underline{~~~~} Paragraphe \underline{~~~~} 2. Question \underline{~~~~~~} Page \underline{~~~~~~} Paragraphe \underline{~~~~~~}
$\square$ Erreur majeure ~ $\square$ Erreur mineure ~ $\square$ Imprécision ~ $\square$ Autre : \underline{~~~~~~~~} $\square$ Erreur majeure ~ $\square$ Erreur mineure ~ $\square$ Imprécision ~ $\square$ Autre : \underline{~~~~~~~~}
@ -159,7 +150,7 @@ Description :
\vfill \vfill
3. Question \underline{~~~~} Page \underline{~~~~} Paragraphe \underline{~~~~} 3. Question \underline{~~~~~~} Page \underline{~~~~~~} Paragraphe \underline{~~~~~~}
$\square$ Erreur majeure ~ $\square$ Erreur mineure ~ $\square$ Imprécision ~ $\square$ Autre : \underline{~~~~~~~~} $\square$ Erreur majeure ~ $\square$ Erreur mineure ~ $\square$ Imprécision ~ $\square$ Autre : \underline{~~~~~~~~}
@ -167,7 +158,7 @@ Description :
\vfill \vfill
4. Question \underline{~~~~} Page \underline{~~~~} Paragraphe \underline{~~~~} 4. Question \underline{~~~~~~} Page \underline{~~~~~~} Paragraphe \underline{~~~~~~}
$\square$ Erreur majeure ~ $\square$ Erreur mineure ~ $\square$ Imprécision ~ $\square$ Autre : \underline{~~~~~~~~} $\square$ Erreur majeure ~ $\square$ Erreur mineure ~ $\square$ Imprécision ~ $\square$ Autre : \underline{~~~~~~~~}
@ -175,17 +166,52 @@ Description :
\vfill \vfill
5. Question \underline{~~~~} Page \underline{~~~~} Paragraphe \underline{~~~~} \newpage
$\square$ Erreur majeure ~ $\square$ Erreur mineure ~ $\square$ Imprécision ~ $\square$ Autre : \underline{~~~~~~~~}
\section*{Aspects positifs}
%Identifiez au plus deux points forts de la solution et dites pourquoi (exemples: propositions majeures, idées importantes, généralisations pertinentes, exemples significatifs, constructions originales,...).
Identifiez au plus deux points forts spécifiques de la solution et dites pourquoi (exemples : propositions majeures, idées importantes, généralisations pertinentes, exemples significatifs, constructions originales,...).
\medskip
1. Question \underline{~~~~~~} Page \underline{~~~~~~} Paragraphe \underline{~~~~~~}
Description : Description :
\vfill \vfill
\section*{Remarques formelles (facultatif)} 2. Question \underline{~~~~~~} Page \underline{~~~~~~} Paragraphe \underline{~~~~~~}
Donnez votre avis concernant la présentation de la solution (lisibilité, etc.). Description :
\vfill
\section*{\'Evaluation qualitative de la solution}
%Donnez votre avis concernant la solution. Mettez notamment en valeur les points positifs (des idées importantes, originales, etc.) et précisez ce qui aurait pu améliorer la solution.
Donnez votre avis concernant la solution en général. Mettez notamment en valeur ses qualités globales, et précisez ce qui aurait pu l'améliorer.
\vfill
\vfill
\vfill
\begin{center}
\textbf{\'Evaluation générale :} ~ $\square$ Excellente ~ $\square$ Bonne ~ $\square$ Suffisante ~ $\square$ Passable
\end{center}
\section*{Autres remarques (facultatif)}
Présentation, lisibilité, orthographe, etc.
\vfill \vfill