diff --git a/draw/consumers.py b/draw/consumers.py index 7719b8d..f5b82cc 100644 --- a/draw/consumers.py +++ b/draw/consumers.py @@ -929,7 +929,7 @@ class DrawConsumer(AsyncJsonWebsocketConsumer): td.purposed = None await td.asave() - remaining = len(settings.PROBLEMS) - 5 - len(td.rejected) + remaining = len(settings.PROBLEMS) - settings.RECOMMENDED_SOLUTIONS_COUNT - len(td.rejected) # Update messages trigram = td.participation.team.trigram diff --git a/draw/models.py b/draw/models.py index 9e54e25..deb38c2 100644 --- a/draw/models.py +++ b/draw/models.py @@ -147,10 +147,10 @@ class Draw(models.Model): else: # The problem can be rejected s += "Elle peut décider d'accepter ou de refuser ce problème. " - if len(td.rejected) >= len(settings.PROBLEMS) - 5: + if len(td.rejected) >= len(settings.PROBLEMS) - settings.RECOMMENDED_SOLUTIONS_COUNT: s += "Refuser ce problème ajoutera une nouvelle pénalité de 25 % sur le coefficient de l'oral de la défense." else: - s += f"Il reste {len(settings.PROBLEMS) - 5 - len(td.rejected)} refus sans pénalité." + s += f"Il reste {len(settings.PROBLEMS) - settings.RECOMMENDED_SOLUTIONS_COUNT - len(td.rejected)} refus sans pénalité." case 'WAITING_FINAL': # We are between the two rounds of the final tournament s += "Le tirage au sort pour le tour 2 aura lieu à la fin du premier tour. Bon courage !" @@ -193,10 +193,10 @@ class Round(models.Model): choices=[ (1, _('Round 1')), (2, _('Round 2')), - ], + ] + ([] if settings.NB_ROUNDS == 2 else [(3, _('Round 3'))]), verbose_name=_('number'), - help_text=_("The number of the round, 1 or 2"), - validators=[MinValueValidator(1), MaxValueValidator(2)], + help_text=_("The number of the round, 1 or 2 (or 3 for ETEAM)"), + validators=[MinValueValidator(1), MaxValueValidator(settings.NB_ROUNDS)], ) current_pool = models.ForeignKey( @@ -524,10 +524,10 @@ class TeamDraw(models.Model): @property def penalty_int(self): """ - The number of penalties, which is the number of rejected problems after the P - 5 free rejects, - where P is the number of problems. + The number of penalties, which is the number of rejected problems after the P - 5 free rejects + (P - 6 for ETEAM), where P is the number of problems. """ - return max(0, len(self.rejected) - (len(settings.PROBLEMS) - 5)) + return max(0, len(self.rejected) - (len(settings.PROBLEMS) - settings.RECOMMENDED_SOLUTIONS_COUNT)) @property def penalty(self): diff --git a/draw/static/tfjm/js/draw.js b/draw/static/tfjm/js/draw.js index 03e17fc..ea0075d 100644 --- a/draw/static/tfjm/js/draw.js +++ b/draw/static/tfjm/js/draw.js @@ -4,6 +4,9 @@ await Notification.requestPermission() })() +// TODO ETEAM Mieux paramétriser (5 pour le TFJM², 6 pour l'ETEAM) +const RECOMMENDED_SOLUTIONS_COUNT = 6 + const problems_count = JSON.parse(document.getElementById('problems_count').textContent) const tournaments = JSON.parse(document.getElementById('tournaments_list').textContent) @@ -658,15 +661,16 @@ document.addEventListener('DOMContentLoaded', () => { recapDiv.textContent = `🗑️ ${rejected.join(', ')}` let penaltyDiv = document.getElementById(`recap-${tid}-round-${round}-team-${team}-penalty`) - if (rejected.length > problems_count - 5) { + if (rejected.length > problems_count - RECOMMENDED_SOLUTIONS_COUNT) { // If more than P - 5 problems were rejected, add a penalty of 25% of the coefficient of the oral defender + // This is P - 6 for the ETEAM if (penaltyDiv === null) { penaltyDiv = document.createElement('div') penaltyDiv.id = `recap-${tid}-round-${round}-team-${team}-penalty` penaltyDiv.classList.add('badge', 'rounded-pill', 'text-bg-info') recapDiv.parentNode.append(penaltyDiv) } - penaltyDiv.textContent = `❌ ${25 * (rejected.length - (problems_count - 5))} %` + penaltyDiv.textContent = `❌ ${25 * (rejected.length - (problems_count - RECOMMENDED_SOLUTIONS_COUNT))} %` } else { // Eventually remove this div if (penaltyDiv !== null) diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 7f9121e..e18817e 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: TFJM\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-06-07 13:50+0200\n" +"POT-Creation-Date: 2024-06-07 14:13+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Emmy D'Anello \n" "Language-Team: LANGUAGE \n" @@ -37,7 +37,7 @@ msgstr "Canaux d'équipes" msgid "Private channels" msgstr "Messages privés" -#: chat/models.py:29 participation/models.py:35 participation/models.py:263 +#: chat/models.py:29 participation/models.py:35 participation/models.py:264 #: participation/tables.py:18 participation/tables.py:34 msgid "name" msgstr "nom" @@ -78,8 +78,8 @@ msgstr "Type de permission nécessaire pour écrire un message dans un canal." #: chat/models.py:62 draw/admin.py:53 draw/admin.py:71 draw/admin.py:88 #: draw/models.py:26 participation/admin.py:79 participation/admin.py:140 -#: participation/admin.py:171 participation/models.py:693 -#: participation/models.py:717 participation/models.py:935 +#: participation/admin.py:171 participation/models.py:694 +#: participation/models.py:718 participation/models.py:936 #: registration/models.py:756 #: registration/templates/registration/payment_form.html:53 msgid "tournament" @@ -95,7 +95,7 @@ msgstr "" #: chat/models.py:73 draw/models.py:429 draw/models.py:456 #: participation/admin.py:136 participation/admin.py:155 -#: participation/models.py:1434 participation/models.py:1443 +#: participation/models.py:1435 participation/models.py:1444 #: participation/tables.py:84 msgid "pool" msgstr "poule" @@ -108,8 +108,8 @@ msgstr "" "concernée." #: chat/models.py:84 draw/templates/draw/tournament_content.html:277 -#: participation/admin.py:167 participation/models.py:252 -#: participation/models.py:708 +#: participation/admin.py:167 participation/models.py:253 +#: participation/models.py:709 #: participation/templates/participation/tournament_harmonize.html:15 #: registration/models.py:157 registration/models.py:747 #: registration/tables.py:39 @@ -254,13 +254,13 @@ msgid "Chat" msgstr "Chat" #: draw/admin.py:39 draw/admin.py:57 draw/admin.py:75 -#: participation/admin.py:109 participation/models.py:253 +#: participation/admin.py:109 participation/models.py:254 #: participation/tables.py:88 msgid "teams" msgstr "équipes" #: draw/admin.py:92 draw/models.py:234 draw/models.py:448 -#: participation/models.py:939 +#: participation/models.py:940 msgid "round" msgstr "tour" @@ -378,13 +378,17 @@ msgstr "Tour 1" msgid "Round 2" msgstr "Tour 2" +#: draw/models.py:196 +msgid "Round 3" +msgstr "Tour 3" + #: draw/models.py:197 msgid "number" msgstr "numéro" #: draw/models.py:198 -msgid "The number of the round, 1 or 2" -msgstr "Le numéro du tour, 1 ou 2" +msgid "The number of the round, 1 or 2 (or 3 for ETEAM)" +msgstr "Le numéro du tour, 1 ou 2 (ou 3 pour ETEAM)" #: draw/models.py:208 msgid "current pool" @@ -398,7 +402,7 @@ msgstr "La poule en cours, où les équipes choisissent leurs problèmes" msgid "rounds" msgstr "tours" -#: draw/models.py:257 participation/models.py:947 +#: draw/models.py:257 participation/models.py:948 msgid "letter" msgstr "lettre" @@ -436,12 +440,12 @@ msgstr "L'instance complète de la poule." msgid "Pool {letter}{number}" msgstr "Poule {letter}{number}" -#: draw/models.py:430 participation/models.py:1435 +#: draw/models.py:430 participation/models.py:1436 msgid "pools" msgstr "poules" -#: draw/models.py:442 participation/models.py:925 participation/models.py:1584 -#: participation/models.py:1614 participation/models.py:1656 +#: draw/models.py:442 participation/models.py:926 participation/models.py:1585 +#: participation/models.py:1615 participation/models.py:1657 msgid "participation" msgstr "participation" @@ -465,8 +469,8 @@ msgid "" msgstr "" "L'ordre de choix dans la poule, entre 0 et la taille de la poule moins 1." -#: draw/models.py:479 draw/models.py:502 participation/models.py:1457 -#: participation/models.py:1621 +#: draw/models.py:479 draw/models.py:502 participation/models.py:1458 +#: participation/models.py:1622 #, python-brace-format msgid "Problem #{problem}" msgstr "Problème n°{problem}" @@ -677,26 +681,26 @@ msgstr "Changelog de type \"{action}\" pour le modèle {model} le {timestamp}" msgid "valid" msgstr "valide" -#: participation/admin.py:87 participation/models.py:729 +#: participation/admin.py:87 participation/models.py:730 msgid "selected for final" msgstr "sélectionnée pour la finale" #: participation/admin.py:124 participation/admin.py:183 -#: participation/models.py:1464 participation/tables.py:112 +#: participation/models.py:1465 participation/tables.py:112 msgid "defender" msgstr "défenseur⋅se" -#: participation/admin.py:128 participation/models.py:1471 -#: participation/models.py:1668 +#: participation/admin.py:128 participation/models.py:1472 +#: participation/models.py:1669 msgid "opponent" msgstr "opposant⋅e" -#: participation/admin.py:132 participation/models.py:1478 -#: participation/models.py:1669 +#: participation/admin.py:132 participation/models.py:1479 +#: participation/models.py:1670 msgid "reporter" msgstr "rapporteur⋅rice" -#: participation/admin.py:187 participation/models.py:1619 +#: participation/admin.py:187 participation/models.py:1620 msgid "problem" msgstr "numéro de problème" @@ -704,7 +708,7 @@ msgstr "numéro de problème" msgid "This name is already used." msgstr "Ce nom est déjà utilisé." -#: participation/forms.py:36 participation/models.py:42 +#: participation/forms.py:36 msgid "The trigram must be composed of three uppercase letters." msgstr "Le trigramme doit être composé de trois lettres majuscules." @@ -797,27 +801,32 @@ msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème." msgid "The PDF file must not have more than 2 pages." msgstr "Le fichier PDF ne doit pas avoir plus de 2 pages." -#: participation/models.py:41 participation/tables.py:39 -msgid "trigram" -msgstr "trigramme" +#: participation/models.py:41 +msgid "code" +msgstr "code" -#: participation/models.py:47 +#: participation/models.py:42 +#, python-brace-format +msgid "The code must be composed of {nb_letters} uppercase letters." +msgstr "Le code doit être composé de {nb_letters} lettres majuscules." + +#: participation/models.py:48 msgid "This trigram is forbidden." msgstr "Ce trigramme est interdit." -#: participation/models.py:53 +#: participation/models.py:54 msgid "access code" msgstr "code d'accès" -#: participation/models.py:54 +#: participation/models.py:55 msgid "The access code let other people to join the team." msgstr "Le code d'accès permet aux autres participants de rejoindre l'équipe." -#: participation/models.py:58 +#: participation/models.py:59 msgid "motivation letter" msgstr "lettre de motivation" -#: participation/models.py:99 +#: participation/models.py:100 #, python-brace-format msgid "" "The team {trigram} is not registered to any tournament. You can register the " @@ -826,11 +835,11 @@ msgstr "" "L'équipe {trigram} n'est inscrite à aucun tournoi. Vous pouvez inscrire " "l'équipe à un tournoi en cliquant sur ce lien." -#: participation/models.py:104 +#: participation/models.py:105 msgid "No tournament" msgstr "Pas de tournoi" -#: participation/models.py:110 +#: participation/models.py:111 msgid "" "Registrations for the tournament of {tournament} are ending on the {date:%Y-" "%m-%d %H:%M}." @@ -838,11 +847,11 @@ msgstr "" "Les inscriptions pour le tournoi de {tournament} se terminent le {date:%d/%m/" "%Y %H:%M}." -#: participation/models.py:115 +#: participation/models.py:116 msgid "Registrations closure" msgstr "Clôture des inscriptions" -#: participation/models.py:122 +#: participation/models.py:123 #, python-brace-format msgid "" "The team {trigram} has not uploaded a motivation letter. You can upload your " @@ -852,11 +861,11 @@ msgstr "" "envoyer votre lettre de motivation en cliquant sur ce lien." -#: participation/models.py:127 +#: participation/models.py:128 msgid "No motivation letter" msgstr "Pas de lettre de motivation" -#: participation/models.py:136 +#: participation/models.py:137 #, python-brace-format msgid "" "The team {trigram} has less than 4 students ({nb_students}). You can invite " @@ -866,11 +875,11 @@ msgstr "" "plus d'élèves à rejoindre l'équipe en utilisant le code d'invitation " "{code}." -#: participation/models.py:141 +#: participation/models.py:142 msgid "Not enough students" msgstr "Pas assez d'élèves" -#: participation/models.py:148 +#: participation/models.py:149 #, python-brace-format msgid "" "The team {trigram} has no coach. You can invite a coach to join the team " @@ -880,11 +889,11 @@ msgstr "" "encadrant⋅e à rejoindre l'équipe en utilisant le code d'invitation " "{code}." -#: participation/models.py:152 +#: participation/models.py:153 msgid "No coach" msgstr "Pas d'encadrant⋅e" -#: participation/models.py:159 +#: participation/models.py:160 #, python-brace-format msgid "" "The team {trigram} has more than 6 students ({nb_students}) or more than 2 " @@ -895,11 +904,11 @@ msgstr "" "encadrant⋅es ({nb_coaches}). Vous devez restreindre le nombre d'élèves et " "d'encadrant⋅es à 6 et 2, respectivement." -#: participation/models.py:164 +#: participation/models.py:165 msgid "Too many members" msgstr "Trop de membres" -#: participation/models.py:171 +#: participation/models.py:172 #, python-brace-format msgid "" "The team {trigram} is ready to be validated. You can request validation on " @@ -908,11 +917,11 @@ msgstr "" "L'équipe {trigram} est prête à être validée. Vous pouvez demander la " "validation sur la page de votre équipe." -#: participation/models.py:176 participation/models.py:187 +#: participation/models.py:177 participation/models.py:188 msgid "Validate team" msgstr "Valider l'équipe" -#: participation/models.py:182 +#: participation/models.py:183 #, python-brace-format msgid "" "The team {trigram} has enough participants, but is not ready to be " @@ -925,7 +934,7 @@ msgstr "" "documents requis. Pour inviter plus de participant⋅es, utilisez le code " "d'invitation {code}." -#: participation/models.py:193 +#: participation/models.py:194 #, python-brace-format msgid "" "The team {trigram} has not been validated by the organizers yet. Please be " @@ -934,115 +943,115 @@ msgstr "" "L'équipe {trigram} n'a pas encore été validée par les organisateurices. " "Merci de patienter." -#: participation/models.py:196 registration/models.py:575 +#: participation/models.py:197 registration/models.py:575 msgid "Pending validation" msgstr "Validation en attente" -#: participation/models.py:249 +#: participation/models.py:250 #, python-brace-format msgid "Team {name} ({trigram})" msgstr "Équipe {name} ({trigram})" -#: participation/models.py:268 +#: participation/models.py:269 msgid "start" msgstr "début" -#: participation/models.py:273 +#: participation/models.py:274 msgid "end" msgstr "fin" -#: participation/models.py:279 +#: participation/models.py:280 #: participation/templates/participation/tournament_detail.html:18 msgid "place" msgstr "lieu" -#: participation/models.py:283 +#: participation/models.py:284 msgid "max team count" msgstr "nombre maximal d'équipes" -#: participation/models.py:288 +#: participation/models.py:289 #: participation/templates/participation/tournament_detail.html:21 msgid "price" msgstr "prix" -#: participation/models.py:293 +#: participation/models.py:294 #: participation/templates/participation/tournament_detail.html:24 msgid "remote" msgstr "à distance" -#: participation/models.py:298 +#: participation/models.py:299 msgid "limit date for registrations" msgstr "date limite d'inscription" -#: participation/models.py:303 +#: participation/models.py:304 msgid "limit date to upload solutions" msgstr "date limite pour envoyer les solutions" -#: participation/models.py:308 +#: participation/models.py:309 msgid "random draw for solutions" msgstr "tirage au sort des solutions" -#: participation/models.py:313 +#: participation/models.py:314 msgid "limit date to upload the syntheses for the first phase" msgstr "date limite pour envoyer les notes de synthèses pour la première phase" -#: participation/models.py:318 +#: participation/models.py:319 msgid "date when the solutions for the second round become available" msgstr "date à laquelle les solutions pour le second tour sont accessibles" -#: participation/models.py:323 +#: participation/models.py:324 msgid "limit date to upload the syntheses for the second phase" msgstr "date limite d'envoi des notes de synthèse pour la seconde phase" -#: participation/models.py:328 +#: participation/models.py:329 #: participation/templates/participation/tournament_detail.html:48 msgid "description" msgstr "description" -#: participation/models.py:334 +#: participation/models.py:335 #: participation/templates/participation/tournament_detail.html:12 msgid "organizers" msgstr "organisateur⋅rices" -#: participation/models.py:339 +#: participation/models.py:340 #: participation/templates/participation/team_detail.html:161 msgid "final" msgstr "finale" -#: participation/models.py:347 +#: participation/models.py:348 msgid "Google Sheet ID" msgstr "ID de la feuille Google Sheets" -#: participation/models.py:694 registration/admin.py:125 +#: participation/models.py:695 registration/admin.py:125 msgid "tournaments" msgstr "tournois" -#: participation/models.py:723 +#: participation/models.py:724 msgid "valid team" msgstr "équipe valide" -#: participation/models.py:724 +#: participation/models.py:725 msgid "The participation got the validation of the organizers." msgstr "La participation a été validée par les organisateur⋅rices." -#: participation/models.py:730 +#: participation/models.py:731 msgid "The team is selected for the final tournament." msgstr "L'équipe est sélectionnée pour la finale." -#: participation/models.py:734 +#: participation/models.py:735 msgid "mention" msgstr "mention" -#: participation/models.py:741 +#: participation/models.py:742 msgid "mention (final)" msgstr "Mention (pour la finale) :" -#: participation/models.py:751 +#: participation/models.py:752 #, python-brace-format msgid "Participation of the team {name} ({trigram})" msgstr "Participation de l'équipe {name} ({trigram})" -#: participation/models.py:758 +#: participation/models.py:759 #, python-brace-format msgid "" "

The team {trigram} has {nb_missing_payments} missing payments. Each " @@ -1055,11 +1064,11 @@ msgstr "" "notification de bourse) pour participer au tournoi.

Les participant⋅es " "qui n'ont pas encore payé sont : {participants}.

" -#: participation/models.py:766 +#: participation/models.py:767 msgid "Missing payments" msgstr "Paiements manquants" -#: participation/models.py:783 +#: participation/models.py:784 msgid "" "

The solutions for the tournament of {tournament} are due on the {date:%Y-" "%m-%d %H:%M}.

You have currently sent {nb_solutions} " @@ -1074,11 +1083,11 @@ msgstr "" "pouvez envoyer vos solutions sur votre page de " "participation.

" -#: participation/models.py:793 participation/models.py:807 +#: participation/models.py:794 participation/models.py:808 msgid "Solutions due" msgstr "Rendu des solutions" -#: participation/models.py:799 +#: participation/models.py:800 msgid "" "

The solutions for the tournament of {tournament} are due on the {date:%Y-" "%m-%d %H:%M}.

Remember that you can only fix minor changes to your " @@ -1091,7 +1100,7 @@ msgstr "" "parties.

Vous pouvez envoyer vos solutions sur votre " "page de participation.

" -#: participation/models.py:813 registration/models.py:600 +#: participation/models.py:814 registration/models.py:600 msgid "" "

The draw of the solutions for the tournament {tournament} is planned on " "the {date:%Y-%m-%d %H:%M}. You can join it on this link." @@ -1101,11 +1110,11 @@ msgstr "" "{date:%d/%m/%Y %H:%M}. Vous pouvez y participer sur ce lien.

" -#: participation/models.py:819 registration/models.py:607 +#: participation/models.py:820 registration/models.py:607 msgid "Draw of solutions" msgstr "Tirage au sort des solutions" -#: participation/models.py:829 +#: participation/models.py:830 #, python-brace-format msgid "" "

The solutions draw is ended. You can check the result on votre solution du problème " "{problem}.

" -#: participation/models.py:838 participation/models.py:880 +#: participation/models.py:839 participation/models.py:881 #, python-brace-format msgid "" "

You will oppose the solution of the team {opponent} on the problème {problem}. Vous pouvez envoyer votre note " "de synthèse sur cette page.

" -#: participation/models.py:847 participation/models.py:889 +#: participation/models.py:848 participation/models.py:890 #, python-brace-format msgid "" "

You will report the solution of the team {reporter} on the problème {problem}. Vous pouvez envoyer votre note " "de synthèse sur cette page.

" -#: participation/models.py:863 registration/models.py:622 +#: participation/models.py:864 registration/models.py:622 msgid "First round" msgstr "Premier tour" -#: participation/models.py:873 +#: participation/models.py:874 #, python-brace-format msgid "" "

For the second round, you will defend your " @@ -1152,11 +1161,11 @@ msgstr "" "

Pour le second tour, vous défendrez votre " "solution du problème {problem}.

" -#: participation/models.py:905 registration/models.py:633 +#: participation/models.py:906 registration/models.py:633 msgid "Second round" msgstr "Second tour" -#: participation/models.py:911 +#: participation/models.py:912 #, python-brace-format msgid "" "

The tournament {tournament} is ended. You can check the results on the Le tournoi {tournament} est terminé. Vous pouvez consulter les résultats " "sur la page du tournoi.

" -#: participation/models.py:916 +#: participation/models.py:917 msgid "Tournament ended" msgstr "Tournoi terminé" -#: participation/models.py:926 participation/models.py:969 +#: participation/models.py:927 participation/models.py:970 msgid "participations" msgstr "participations" -#: participation/models.py:941 participation/models.py:942 +#: participation/models.py:942 participation/models.py:943 +#: participation/models.py:944 #, python-brace-format msgid "Round {round}" msgstr "Tour {round}" -#: participation/models.py:957 +#: participation/models.py:958 msgid "room" msgstr "salle" -#: participation/models.py:959 +#: participation/models.py:960 msgid "Room 1" msgstr "Salle 1" -#: participation/models.py:960 +#: participation/models.py:961 msgid "Room 2" msgstr "Salle 2" -#: participation/models.py:963 +#: participation/models.py:964 msgid "For 5-teams pools only" msgstr "Pour les poules de 5 équipe uniquement" -#: participation/models.py:975 +#: participation/models.py:976 msgid "juries" msgstr "jurys" -#: participation/models.py:984 +#: participation/models.py:985 msgid "president of the jury" msgstr "président⋅e du jury" -#: participation/models.py:991 +#: participation/models.py:992 msgid "BigBlueButton URL" msgstr "Lien BigBlueButton" -#: participation/models.py:992 +#: participation/models.py:993 msgid "The link of the BBB visio for this pool." msgstr "Le lien du salon BBB pour cette poule." -#: participation/models.py:997 +#: participation/models.py:998 msgid "results available" msgstr "résultats disponibles" -#: participation/models.py:998 +#: participation/models.py:999 msgid "" "Check this case when results become accessible to teams. They stay " "accessible to you. Only averages are given." @@ -1223,33 +1233,33 @@ msgstr "" "Ils restent toujours accessibles pour vous. Seules les moyennes sont " "communiquées." -#: participation/models.py:1026 +#: participation/models.py:1027 msgid "The president of the jury must be part of the jury." msgstr "Læ président⋅e du jury doit faire partie du jury." -#: participation/models.py:1415 +#: participation/models.py:1416 #, python-brace-format msgid "The jury {jury} is not part of the jury for this pool." msgstr "{jury} ne fait pas partie du jury pour cette poule." -#: participation/models.py:1428 +#: participation/models.py:1429 #, python-brace-format msgid "Pool {code} for tournament {tournament} with teams {teams}" msgstr "Poule {code} du tournoi {tournament} avec les équipes {teams}" -#: participation/models.py:1448 +#: participation/models.py:1449 msgid "position" msgstr "position" -#: participation/models.py:1455 +#: participation/models.py:1456 msgid "defended solution" msgstr "solution défendue" -#: participation/models.py:1483 +#: participation/models.py:1484 msgid "penalties" msgstr "pénalités" -#: participation/models.py:1485 +#: participation/models.py:1486 msgid "" "Number of penalties for the defender. The defender will loose a 0.5 " "coefficient per penalty." @@ -1257,123 +1267,127 @@ msgstr "" "Nombre de pénalités pour l'équipe défenseuse. Elle perd un coefficient 0.5 " "sur sa présentation orale par pénalité." -#: participation/models.py:1554 participation/models.py:1557 -#: participation/models.py:1560 +#: participation/models.py:1555 participation/models.py:1558 +#: participation/models.py:1561 #, python-brace-format msgid "Team {trigram} is not registered in the pool." msgstr "L'équipe {trigram} n'est pas inscrite dans la poule." -#: participation/models.py:1565 +#: participation/models.py:1566 #, python-brace-format msgid "Passage of {defender} for problem {problem}" msgstr "Passage de {defender} pour le problème {problem}" -#: participation/models.py:1569 participation/models.py:1578 -#: participation/models.py:1663 participation/models.py:1705 +#: participation/models.py:1570 participation/models.py:1579 +#: participation/models.py:1664 participation/models.py:1706 msgid "passage" msgstr "passage" -#: participation/models.py:1570 +#: participation/models.py:1571 msgid "passages" msgstr "passages" -#: participation/models.py:1589 +#: participation/models.py:1590 msgid "difference" msgstr "différence" -#: participation/models.py:1590 +#: participation/models.py:1591 msgid "Score to add/remove on the final score" msgstr "Score à ajouter/retrancher au score final" -#: participation/models.py:1597 +#: participation/models.py:1598 msgid "tweak" msgstr "harmonisation" -#: participation/models.py:1598 +#: participation/models.py:1599 msgid "tweaks" msgstr "harmonisations" -#: participation/models.py:1626 +#: participation/models.py:1627 msgid "solution for the final tournament" msgstr "solution pour la finale" -#: participation/models.py:1631 participation/models.py:1674 +#: participation/models.py:1632 participation/models.py:1675 msgid "file" msgstr "fichier" -#: participation/models.py:1641 +#: participation/models.py:1642 #, python-brace-format msgid "Solution of team {team} for problem {problem}" msgstr "Solution de l'équipe {team} pour le problème {problem}" -#: participation/models.py:1643 +#: participation/models.py:1644 msgid "for final" msgstr "pour la finale" -#: participation/models.py:1646 +#: participation/models.py:1647 msgid "solution" msgstr "solution" -#: participation/models.py:1647 +#: participation/models.py:1648 msgid "solutions" msgstr "solutions" -#: participation/models.py:1680 +#: participation/models.py:1681 #, python-brace-format msgid "Synthesis of {team} as {type} for problem {problem} of {defender}" msgstr "" "Note de synthèse de l'équipe {team} en tant que {type} pour le problème " "{problem} de {defender}" -#: participation/models.py:1688 +#: participation/models.py:1689 msgid "synthesis" msgstr "note de synthèse" -#: participation/models.py:1689 +#: participation/models.py:1690 msgid "syntheses" msgstr "notes de synthèse" -#: participation/models.py:1698 +#: participation/models.py:1699 msgid "jury" msgstr "jury" -#: participation/models.py:1710 +#: participation/models.py:1711 msgid "defender writing note" msgstr "note d'écrit défenseur⋅se" -#: participation/models.py:1716 +#: participation/models.py:1717 msgid "defender oral note" msgstr "note d'oral défenseur⋅se" -#: participation/models.py:1722 +#: participation/models.py:1723 msgid "opponent writing note" msgstr "note d'écrit opposant⋅e" -#: participation/models.py:1728 +#: participation/models.py:1729 msgid "opponent oral note" msgstr "note d'oral opposant⋅e" -#: participation/models.py:1734 +#: participation/models.py:1735 msgid "reporter writing note" msgstr "note d'écrit rapporteur⋅rice" -#: participation/models.py:1740 +#: participation/models.py:1741 msgid "reporter oral note" msgstr "note d'oral du rapporteur⋅rice" -#: participation/models.py:1800 +#: participation/models.py:1801 #, python-brace-format msgid "Notes of {jury} for {passage}" msgstr "Notes de {jury} pour le {passage}" -#: participation/models.py:1803 +#: participation/models.py:1804 msgid "note" msgstr "note" -#: participation/models.py:1804 +#: participation/models.py:1805 msgid "notes" msgstr "notes" +#: participation/tables.py:39 +msgid "trigram" +msgstr "trigramme" + #: participation/tables.py:50 msgid "Validated" msgstr "Validée" @@ -3868,9 +3882,9 @@ msgid "" msgstr "" "N'hésitez pas à consulter la documentation du site, pour vérifier si la réponse n'y " -"est pas déjà. Référez-vous également bien sûr au règlement de l'ETEAM. Pour toute autre " -"question, n'hésitez pas à nous contacter par mail à l'adresse règlement de l'ETEAM. Pour toute " +"autre question, n'hésitez pas à nous contacter par mail à l'adresse eteam_moc@proton.me ." #: tfjm/templates/index_tfjm.html:18 @@ -4040,7 +4054,3 @@ msgstr "Aucun résultat." #: tfjm/templates/sidebar.html:10 tfjm/templates/sidebar.html:21 msgid "Informations" msgstr "Informations" - -#~ msgctxt "TFJM" -#~ msgid "TFJM² Platform" -#~ msgstr "Plateforme du TFJM²" diff --git a/participation/models.py b/participation/models.py index d2e4b8e..b592589 100644 --- a/participation/models.py +++ b/participation/models.py @@ -1,6 +1,6 @@ # Copyright (C) 2020 by Animath # SPDX-License-Identifier: GPL-3.0-or-later - +import math from datetime import date, timedelta import os @@ -37,12 +37,13 @@ class Team(models.Model): ) trigram = models.CharField( - max_length=3, - verbose_name=_("trigram"), - help_text=_("The trigram must be composed of three uppercase letters."), + max_length=settings.TEAM_CODE_LENGTH, + verbose_name=_("code"), + help_text=format_lazy(_("The code must be composed of {nb_letters} uppercase letters."), + nb_letters=settings.TEAM_CODE_LENGTH), unique=True, validators=[ - RegexValidator(r"^[A-Z]{3}$"), + RegexValidator(fr"^[A-Z]{{f'{settings.TEAM_CODE_LENGTH}'}}$"), RegexValidator(fr"^(?!{'|'.join(f'{t}$' for t in settings.FORBIDDEN_TRIGRAMS)})", message=_("This trigram is forbidden.")), ], @@ -940,7 +941,7 @@ class Pool(models.Model): choices=[ (1, format_lazy(_("Round {round}"), round=1)), (2, format_lazy(_("Round {round}"), round=2)), - ] + ] + ([] if settings.NB_ROUNDS == 2 else [(3, format_lazy(_("Round {round}"), round=3))]), ) letter = models.PositiveSmallIntegerField( @@ -1010,12 +1011,16 @@ class Pool(models.Model): def solutions(self): return [passage.defended_solution for passage in self.passages.all()] + @property + def coeff(self): + return 1 if self.round <= 2 else math.pi - 2 + def average(self, participation): - return sum(passage.average(participation) for passage in self.passages.all()) \ + return self.coeff * sum(passage.average(participation) for passage in self.passages.all()) \ + sum(tweak.diff for tweak in participation.tweaks.filter(pool=self).all()) async def aaverage(self, participation): - return sum([passage.average(participation) async for passage in self.passages.all()]) \ + return self.coeff * sum([passage.average(participation) async for passage in self.passages.all()]) \ + sum([tweak.diff async for tweak in participation.tweaks.filter(pool=self).all()]) def get_absolute_url(self): diff --git a/tfjm/settings.py b/tfjm/settings.py index 08fb323..759cae7 100644 --- a/tfjm/settings.py +++ b/tfjm/settings.py @@ -340,16 +340,6 @@ GOOGLE_SERVICE_CLIENT = { NOTES_DRIVE_FOLDER_ID = os.getenv("NOTES_DRIVE_FOLDER_ID", "CHANGE_ME_IN_ENV_SETTINGS") # Custom parameters -PROBLEMS = [ - "Triominos", - "Rassemblements mathématiques", - "Tournoi de ping-pong", - "Dépollution de la Seine", - "Électron libre", - "Pièces truquées", - "Drôles de cookies", - "Création d'un jeu", -] FORBIDDEN_TRIGRAMS = [ "BIT", "CNO", @@ -379,3 +369,38 @@ try: from .settings_local import * # noqa: F401,F403 except ImportError: pass + +if TFJM_APP == "TFJM": + TEAM_CODE_LENGTH = 3 + RECOMMENDED_SOLUTIONS_COUNT = 5 + NB_ROUNDS = 2 + + PROBLEMS = [ + "Triominos", + "Rassemblements mathématiques", + "Tournoi de ping-pong", + "Dépollution de la Seine", + "Électron libre", + "Pièces truquées", + "Drôles de cookies", + "Création d'un jeu", + ] +elif TFJM_APP == "ETEAM": + TEAM_CODE_LENGTH = 4 + RECOMMENDED_SOLUTIONS_COUNT = 6 + NB_ROUNDS = 3 + + PROBLEMS = [ + "Exploring Flatland", + "A Mazing Hive", + "Coin tossing", + "The rainbow bridge", + "Arithmetic and shopping", + "A fence for the goats", + "Generalized Tic-Tac-Toe", + "Polyhedral construction", + "Landing a probe", + "Catching the rabbit", + ] +else: + raise ValueError(f"Unknown app: {TFJM_APP}")