Compare commits

..

No commits in common. "dev" and "devbis" have entirely different histories.
dev ... devbis

18 changed files with 160 additions and 1175 deletions

View File

@ -1,60 +1,2 @@
# Gestion des tournois
## Introduction
Ces instructions vous permettent de :
- récupérer le programme,
- d'installer l'environnement nécessaire à son exécution,
- de l'exécuter,
- de l'utiliser
### Pré-requis
```
paquets : python 3.11, python3.11-venv, git
```
### Installation
Voici les étapes à suivre pour avoir un environnement d'exécution opérationnel :
créer l'environnement virtuel
```
python3.11 -m venv env
source env/bin/activate
```
cloner le dépôt, aller dans le bon dossier
```
git clone https://mcstn.fr/gitea/Yann/Projet4.git
cd Projet4
```
## Exécution
exécuter la commande :
```
python3 main.py
```
## Utilisation
Toutes les actions se font via le menu affiché.
Il y a deux menus : général et rapport.
Si vous souhaitez spécifier une liste de joueurs au format JSON, il vous faut la placer
dans le répertoire `data`
Sinon, vous pouvez créer des joueurs via le menu
Le répertoire, nom des fichiers joueurs et tournois sont des constantes de models.py
Ils sont placés dans le dossier `data`
## Auteur
Yann <yann@needsome.coffee>
## License
N/A
# work in progress

View File

@ -1,244 +0,0 @@
from models.models import (Player, Round, Match, MatchHistory)
from models.models import DATAPATH, PLAYERFILE, TOURNAMENTFILE
from random import shuffle
import os
import json
class Save:
def __init__(self, view):
self.view = view
def load_file(self, file):
try:
os.mkdir(DATAPATH)
except FileExistsError:
pass
# test if file exists... could be done more gracefully
try:
with open(file, "r") as json_file:
data_tmp = json.load(json_file)
return data_tmp
except json.decoder.JSONDecodeError:
self.view.display_format_error()
except FileNotFoundError:
return False
def write_file(self, data_tmp, file):
with open(file, "w") as json_file:
json_file.write(json.dumps(data_tmp))
return "Done."
def player_write(self, player) -> bool:
data_tmp = []
if self.load_file(PLAYERFILE):
data_tmp = (self.load_file(PLAYERFILE))
data_tmp.append(player)
self.write_file(data_tmp, PLAYERFILE)
self.view.ok_player()
return True
def player_load(self) -> list:
"""Load and create player from JSON file
returns:
list of Player"""
if self.load_file(PLAYERFILE):
data_tmp = self.load_file(PLAYERFILE)
data_list = []
for player in data_tmp:
data_list.append(Player(name=player['name'],
lastname=player['lastname'],
birthdate=player['birthdate'],
ine=player['ine']))
return data_list
else:
self.view.display_file_error("joueur")
def tournament_write(self, tournament):
data = {
tournament.name: tournament.data()
}
if self.load_file(TOURNAMENTFILE):
data_tmp = self.load_file(TOURNAMENTFILE)
data_tmp[tournament.name] = tournament.data()
self.write_file(data_tmp, TOURNAMENTFILE)
else:
self.write_file(data, TOURNAMENTFILE)
return True
def tournament_load(self):
if self.load_file(TOURNAMENTFILE):
data_tmp = self.load_file(TOURNAMENTFILE)
return data_tmp
else:
self.view.display_file_error("tournoi")
class Application:
def __init__(self, tournament, save, view, menu):
self.tournament = tournament
self.save = save
self.match = Match()
self.match_history = MatchHistory()
self.view = view
self.menu = menu
def sort_by_score(self):
self.tournament.players_list.sort(key=lambda t: t.score, reverse=True)
def create_tournament(self):
"""update existing tournament with data from view"""
tournament_details = self.view.prompt_for_tournament()
self.tournament.name = tournament_details['name']
self.tournament.location = tournament_details['location']
self.tournament.date_start = tournament_details['date_start']
self.tournament.date_end = tournament_details['date_end']
self.tournament.description = tournament_details['description']
self.tournament.total_round = tournament_details['total_round']
self.tournament.round_list = []
if self.save.player_load():
self.tournament.players_list = self.save.player_load()
self.save.tournament_write(self.tournament)
else:
self.view.display_player_instructions()
self.menu_manager()
def run_tournament(self):
"""creates all round iteration
"""
shuffle(self.tournament.players_list)
self.view.display_players(self.tournament.players_list)
for each_round in range(1, self.tournament.total_round + 1):
self.tournament.current_round += 1
self.round = Round()
self.round.name = "Round " + str(each_round)
self.view.prompt_for_round(self.round)
# set round start time
self.round.start_time = self.round.get_time()
# create matches TODO : check from history
self.round.match_list = self.create_match()
self.match_history.add(self.round.match_list)
# display matches
self.view.display_matches(self.round.match_list)
self.view.prompt_for_scores()
self.round.end_time = self.round.get_time()
self.scores(self.round.match_list)
self.sort_by_score()
self.tournament.round_list.append(self.round.save())
self.save.tournament_write(self.tournament)
self.view.display_round_info(self.round)
self.view.display_scores(self.tournament.players_list)
self.view.ok_done(self.tournament.name)
def check_match(self, match, match_history):
"""check if match is in list
For future usage
"""
for item in match_history:
if match in item:
return True
else:
return False
def create_match(self) -> list:
"""Create match with two consecutive players
returns :
list of Match
"""
match_list = []
j = 0
for i in range(0, len(self.tournament.players_list), 2):
j += 1
match = Match()
try:
match.player1 = self.tournament.players_list[i]
match.player2 = self.tournament.players_list[i+1]
if self.match_history.check(match):
# match.player2 = self.tournament.players_list[i+2]
self.view.display_error_already()
match_list.append(match)
except IndexError:
pass
return match_list
def scores(self, match_list) -> list:
"""user asked to enter scores, update Player
returns:
list of tuples
"""
matches = []
for match in match_list:
count = match_list.index(match) + 1
result = self.view.input_scores(match, count)
if result in ("1", "2", "3"):
if result == "1":
match.player1.score += 1
match.score1 = 1
elif result == "2":
match.player2.score += 1
match.score2 = 1
elif result == "3":
match.player1.score += 0.5
match.player2.score += 0.5
match.score1 = match.score2 = 0.5
matches.append(match.get_data())
return matches
def menu_manager(self):
menu_choice = self.menu.items(1)
while True:
# Quit
if menu_choice == "4":
self.view.display_quit()
quit()
# Rapports
elif menu_choice == "3":
rapport_choice = self.menu.items(2)
# Go back
if rapport_choice == "4":
self.menu_manager()
# Display players from file
elif rapport_choice == "1":
if self.save.player_load():
self.view.display_players(self.save.player_load())
self.view.prompt_next()
# Display list of tournaments
elif rapport_choice == "2":
if self.save.tournament_load():
self.view.display_tournaments(
self.save.tournament_load())
self.view.prompt_next()
# display tournament's details
elif rapport_choice == "3":
temp = {}
if self.save.tournament_load():
temp = self.save.tournament_load()
name = self.view.prompt_tournament_to_display(temp)
if name in temp:
self.view.display_tournament_detail(
temp[name])
else:
self.view.display_error()
# create new player and save it in file
elif menu_choice == "2":
joueur = self.view.prompt_for_new_player()
self.save.player_write(joueur)
self.view.prompt_next()
self.menu_manager()
# create new tournament
elif menu_choice == "1":
self.view.ok_go()
self.create_tournament()
self.run_tournament()
self.menu_manager()

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="48"
viewBox="0 0 32 48"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="back.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#3d3d3d"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="47.245066"
inkscape:cy="13.218734"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
width="32px"
inkscape:window-width="1535"
inkscape:window-height="876"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1004.3622)">
<g
id="g5305"
transform="translate(0,-3.5)">
<path
inkscape:connector-curvature="0"
id="path5301"
d="M 15.577993,1039.1732 4.7040093,1028.3079 15.469253,1017.5512"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path5303"
d="m 4.921489,1028.3622 26.53252,0"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:6;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="48"
viewBox="0 0 32 48"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="file.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#3d3d3d"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="24.812518"
inkscape:cy="18.901073"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
width="32px"
inkscape:window-width="1535"
inkscape:window-height="876"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1004.3622)">
<path
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 4.1360619,1007.3622 0,34.375 23.7278761,0 0,-29.9038 -4.471158,-4.4712 -19.2567181,0 z m 18.5469091,0.6084 4.471159,4.4712 -4.471159,0 0,-4.4712 z m -16.6202866,7.8079 19.8746316,0 0,1.8252 -19.8746316,0 0,-1.8252 z m 0,3.2448 19.8746316,0 0,1.8253 -19.8746316,0 0,-1.8253 z m 0,6.0841 19.8746316,0 0,1.8252 -19.8746316,0 0,-1.8252 z m 0,8.2135 19.8746316,0 0,1.8252 -19.8746316,0 0,-1.8252 z"
id="path4749"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1,30 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>flake8 violations</title>
<meta http-equiv="Content-Type" value="text/html; charset=UTF-8">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="masthead" class="sev-4"></div>
<div id="page">
<h1>flake8 violations</h1>
<p id="versions">Generated on 2025-02-14 11:49
with Installed plugins: flake8-html: 0.4.3, mccabe: 0.7.0, pycodestyle: 2.12.1, pyflakes: 3.2.0
</p>
<ul id="index">
<li>
<div id="all-good">
<span class="count sev-4">
<span class="tick">&#x2713;</span>
</span>
<h2>All good!</h2>
<p>No flake8 errors found in 8 files scanned.</p>
</div>
</li>
</ul>
</div>
</body>
</html>

View File

@ -1,327 +0,0 @@
html {
font-family: sans-serif;
font-size: 90%;
}
#masthead {
position: fixed;
left: 0;
top: 0;
right: 0;
height: 40%;
}
h1, h2 {
font-family: sans-serif;
font-weight: normal;
}
h1 {
color: white;
font-size: 36px;
margin-top: 1em;
}
h1 img {
margin-right: 0.3em;
}
h2 {
margin-top: 0;
}
h1 a {
color: white;
}
#versions {
color: rgba(255, 255, 255, 0.7);
}
#page {
position: relative;
max-width: 960px;
margin: 0 auto;
}
#index {
background-color: white;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.8);
padding: 0;
margin: 0;
}
#index li {
list-style: none;
margin: 0;
padding: 1px 0;
}
#index li + li {
border-top: solid silver 1px;
}
.details p {
margin-left: 3em;
color: #888;
}
#index a {
display: block;
padding: 0.8em 1em;
cursor: pointer;
}
#index #all-good {
padding: 1.4em 1em 0.8em;
}
#all-good .count .tick {
font-size: 2em;
}
#all-good .count {
float: left;
}
#all-good h2,
#all-good p {
margin-left: 50px;
}
#index a:hover {
background-color: #eee;
}
.count {
display: inline-block;
border-radius: 50%;
text-align: center;
width: 2.5em;
line-height: 2.5em;
height: 2.5em;
color: white;
margin-right: 1em;
}
.sev-1 {
background-color: #a00;
}
.sev-2 {
background-color: #b80;
}
.sev-3 {
background-color: #28c;
}
.sev-4 {
background-color: #383;
}
a {
text-decoration: none;
}
#doc {
background-color: white;
margin: 1em 0;
padding: 1em;
padding-left: 1.2em;
position: relative;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.8);
}
#doc pre {
margin: 0;
padding: 0.07em;
}
.violations {
position: absolute;
margin: 1.2em 0 0 3em;
padding: 0.5em 1em;
font-size: 14px;
background-color: white;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.4);
display: none;
}
.violations .count {
font-size: 70%;
}
.violations li {
padding: 0.1em 0.3em;
list-style: none;
}
.line-violations::before {
display: block;
content: "";
position: absolute;
left: -1em;
width: 14px;
height: 14px;
border-radius: 50%;
background-color: red;
}
.code:hover .violations {
display: block;
}
tt {
white-space: pre-wrap;
font-family: Consolas, monospace;
font-size: 10pt;
}
tt i {
color: silver;
display: inline-block;
text-align: right;
width: 3em;
box-sizing: border-box;
height: 100%;
border-right: solid #eee 1px;
padding-right: 0.2em;
}
.le {
background-color: #ffe8e8;
cursor: pointer;
}
.le:hover {
background-color: #fcc;
}
.details {
clear: both;
}
#index .details {
border-top-style: none;
margin: 1em;
}
ul.details {
margin-left: 0;
padding-left: 0;
}
#index .details li {
list-style: none;
border-top-style: none;
margin: 0.3em 0;
padding: 0;
}
#srclink {
float: right;
font-size: 36px;
margin: 0;
}
#srclink a {
color: white;
}
#index .details a {
padding: 0;
color: inherit;
}
.le {
background-color: #ffe8e8;
cursor: pointer;
}
.le.sev-1 {
background-color: #f88;
}
.le.sev-2 {
background-color: #fda;
}
.le.sev-3 {
background-color: #adf;
}
img {
height: 1.2em;
vertical-align: -0.35em;
}
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.hll { background-color: #ffffcc }
.c { color: #3D7B7B; font-style: italic } /* Comment */
.err { border: 1px solid #F00 } /* Error */
.k { color: #008000; font-weight: bold } /* Keyword */
.o { color: #666 } /* Operator */
.ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
.cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
.cp { color: #9C6500 } /* Comment.Preproc */
.cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
.c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
.cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
.gd { color: #A00000 } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.gr { color: #E40000 } /* Generic.Error */
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
.gi { color: #008400 } /* Generic.Inserted */
.go { color: #717171 } /* Generic.Output */
.gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.gt { color: #04D } /* Generic.Traceback */
.kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.kp { color: #008000 } /* Keyword.Pseudo */
.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.kt { color: #B00040 } /* Keyword.Type */
.m { color: #666 } /* Literal.Number */
.s { color: #BA2121 } /* Literal.String */
.na { color: #687822 } /* Name.Attribute */
.nb { color: #008000 } /* Name.Builtin */
.nc { color: #00F; font-weight: bold } /* Name.Class */
.no { color: #800 } /* Name.Constant */
.nd { color: #A2F } /* Name.Decorator */
.ni { color: #717171; font-weight: bold } /* Name.Entity */
.ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
.nf { color: #00F } /* Name.Function */
.nl { color: #767600 } /* Name.Label */
.nn { color: #00F; font-weight: bold } /* Name.Namespace */
.nt { color: #008000; font-weight: bold } /* Name.Tag */
.nv { color: #19177C } /* Name.Variable */
.ow { color: #A2F; font-weight: bold } /* Operator.Word */
.w { color: #BBB } /* Text.Whitespace */
.mb { color: #666 } /* Literal.Number.Bin */
.mf { color: #666 } /* Literal.Number.Float */
.mh { color: #666 } /* Literal.Number.Hex */
.mi { color: #666 } /* Literal.Number.Integer */
.mo { color: #666 } /* Literal.Number.Oct */
.sa { color: #BA2121 } /* Literal.String.Affix */
.sb { color: #BA2121 } /* Literal.String.Backtick */
.sc { color: #BA2121 } /* Literal.String.Char */
.dl { color: #BA2121 } /* Literal.String.Delimiter */
.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.s2 { color: #BA2121 } /* Literal.String.Double */
.se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
.sh { color: #BA2121 } /* Literal.String.Heredoc */
.si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
.sx { color: #008000 } /* Literal.String.Other */
.sr { color: #A45A77 } /* Literal.String.Regex */
.s1 { color: #BA2121 } /* Literal.String.Single */
.ss { color: #19177C } /* Literal.String.Symbol */
.bp { color: #008000 } /* Name.Builtin.Pseudo */
.fm { color: #00F } /* Name.Function.Magic */
.vc { color: #19177C } /* Name.Variable.Class */
.vg { color: #19177C } /* Name.Variable.Global */
.vi { color: #19177C } /* Name.Variable.Instance */
.vm { color: #19177C } /* Name.Variable.Magic */
.il { color: #666 } /* Literal.Number.Integer.Long */

51
main.py
View File

@ -1,21 +1,40 @@
from models.models import Tournament
from controllers.base import Application, Save
from views.base import View
from views.menu import Menu
def main():
tournament = Tournament()
view = View()
save = Save(view)
menu = Menu()
application = Application(tournament=tournament,
save=save,
view=view,
menu=menu)
# launch application
application.menu_manager()
if __name__ == "__main__":
#Menu
## creer un nouveau tournoi
## enregistrer un nouveau joueur
## rapport
### afficher la liste des joueurs inscrits
### liste des tournois
### afficher un tounroi en particulier :
#### liste des joueurs du tournoi (alphab.)
#### liste des tours, matchs
# Nouveau Tournoi :
## entrer les infos :
## nom, lieu, date début, date fin, nombre de tours(opt)
# Participants / joueurs :
## besoin d'enregistrer des nouveaux joueurs ?
## selection des participant dans la liste des joueurs du club
## Creation du 1er tour : affichage du tour, de la liste des matchs (paire nom.prenom) :
## En attente saisie séquentielle des résultats pour chaque match :
### Saisie résultat match 1 : 1. Bob LEPONGE / 2. Bernard DINAMOUK / 3.Match Nul
### ?
## Tour suivant (puis itération) : affichage du tour, de la liste des matchs (paire nom.prenom) :
## etc
## Après le dernier tour : affichage du vainqueur
## sauvegarde du tournoi : tournois/{date.nom.lieu}/{date.nom.lieu}.json, matchs.json
##
if __name__ == "__main__" :
main()

View File

@ -1,151 +0,0 @@
from datetime import datetime
from collections import UserList
DATAPATH = ("data/")
PLAYERFILE = DATAPATH + "liste_joueurs.json"
TOURNAMENTFILE = DATAPATH + "liste_tournois.json"
class Tournament:
"""Chess tournament with player_list, keeps a list with all rounds"""
def __init__(self,
name="None",
players_list=None,
location="club",
total_round=4
):
self.name = name
self.location = location
self.start = datetime.now().strftime("%d-%m-%Y")
self.end = self.start
self.total_round = total_round
self.round_list = []
self.current_round = 0
self.players_list = players_list
self.scores = []
self.description = "Pas de description"
def __str__(self):
return "Tournoi " + self.name + " à " + self.location
def data(self):
"""Save tournament in file"""
players = []
for i in self.players_list:
# players.append(i.name + " " + i.lastname)
players.append(i.data())
tournament_dict = {
"name": self.name,
"location": self.location,
"description": self.location,
"start": self.start,
"end": self.end,
"total_rounds": self.total_round,
"current": self.current_round,
"players": players,
"rounds": self.round_list}
return tournament_dict
class Player:
"""A Chess player"""
def __init__(self, name, lastname, birthdate, ine):
self.lastname = lastname
self.name = name
self.birthdate = birthdate
self.ine = ine
self.score = 0
def __str__(self):
"""Used in print"""
return self.ine
def __repr__(self):
return str(self)
def data(self):
player_dict = {
'prénom': self.name,
'nom': self.lastname,
'date de naissance': self.birthdate,
'ine': self.ine,
'score': self.score
}
return player_dict
class Match:
def __init__(self, player1=None, player2=None):
self.player1 = player1
self.player2 = player2
self.score1 = 0
self.score2 = 0
def __str__(self):
return self.player1.ine + " / " + self.player2.ine
def get_data(self):
return ([self.player1.ine, self.score1],
[self.player2.ine, self.score2])
def get_scores(self) -> list:
return (self.player1.ine
+ " : " + str(self.score1)
+ " - " + self.player2.ine
+ " : " + str(self.score2))
class Round:
def __init__(self, name="Round 1"):
self.name = name
self.start_time = None
self.end_time = None
self.match_list = []
def __str__(self):
return (self.name
+ ": début le "
+ self.start_time
+ " et terminé le "
+ self.end_time)
def get_time(self) -> str:
return datetime.now().strftime("%d-%m-%Y à %Hh%M,%Ss")
def save(self) -> dict:
matches = []
for match in self.match_list:
matches.append(match.get_data())
dico = {
"Nom": self.name,
"Debut": self.start_time,
"Fin": self.end_time,
"Matches": matches
}
return dico
class MatchHistory(UserList):
"""Keep a history of matches to avoid same match occur
returns a list of matches
"""
def __init__(self):
self.matches = []
def add(self, match_list):
for match in match_list:
self.matches.append(match)
def __str__(self):
return self.matches
def check(self, given_match):
for match in self.matches:
if (given_match.player1 == match.player1
or given_match.player1 == match.player2):
if (given_match.player2 == match.player2
or given_match.player2 == match.player2):
return True
return False

14
tournoi/menu.py Normal file
View File

@ -0,0 +1,14 @@
class Menu:
def items(self):
print("[1] Créer un nouveau tournoi", end='\n')
print("[2] Enregistrer un nouveau joueur", end='\n')
print("[3] Rapports", end='\n')
print("[4] Quitter", end='\n')
def rapports():
print("[1] Afficher la liste des joueurs", end='\n')
print("[2] Afficher l'historique des tournois", end='\n')
print("[3] Afficher le détail d'un tournoi", end='\n')
print("[4] Quitter", end='\n')

19
tournoi/player.py Normal file
View File

@ -0,0 +1,19 @@
import json
class Player:
"""Define player, should store only data for now ? Don't see further"""
def get_new_player(self):
get_player = {}
print("Enregistrez un nouveau joueur :\n")
get_player['lastname'] = input('Nom de famille :\n')
get_player['name'] = input('Prénom :\n')
get_player['birth_date'] = input('Date de naissance :\n')
#convert dict in json object and write it in players.json file (with "a" append to file)
with open("players.json", "a") as output:
output.write(json.dumps(get_player, indent=3))
new = Player()
new.get_new_player()

10
tournoi/players.json Normal file
View File

@ -0,0 +1,10 @@
{
"lastname": "Prout",
"name": "Joe",
"birth_date": "23/02/2003"
}
{
"lastname": "Dupont",
"name": "Pierre",
"birth_date": "20/01/2002"
}

74
tournoi/turn.py Normal file
View File

@ -0,0 +1,74 @@
from random import choice
class Turn():
def __init__(self, name, matchs):
self.name = name
self.matchs = matchs
self.match_history = []
def rambling(self, player_list):
"""jumble (random order) players in list and return list"""
self.tmp_list = []
self.picked_player = []
for i in range(2^len(player_list)):
self.picked_player = choice(player_list)
self.tmp_list.append(self.picked_player)
return self.tmp_list
def sorting(self, player_list):
"""order players on score : use second index (for every item in the list) as key (given by function score)"""
def score(couple):
return couple[1]
return sorted(player_list, key=score)
def associate(self, player_list):
"""create a match list"""
self.match_list = []
self.couple = ()
for i in range(len(player_list)):
if i % 2 == 0 :
self.couple = (player_list[i][0], player_list[i+1][0])
if self.couple in self.match_history:
self.couple = (player_list[i][0], player_list[i + 2][0])
self.match_list.append(self.couple)
else:
self.match_list.append(self.couple)
self.match_history.append(self.name)
self.match_history.append(self.match_list)
return self.match_list
def matchmarking(self, player_list):
pass
list = [['Player1', 8],
['Player2', 2],
['Player3', 0],
['Player4', 5],
['Player5', 8],
['Player6', 3],
['Player7', 1],
['Player8', 6],
['Player9', 3],
['Player10', 4],
['Player11', 3],
['Player12', 2],
['Player13', 8],
['Player14', 4],
['Player15', 2],
['Player16', 7]]
tour = Turn("tour1", 1)
print(tour.sorting(list))
print(tour.rambling(list))
print(tour.associate(tour.sorting(list)))
print(f"Voici l'historique des matchs : {tour.match_history}")
tour2 = Turn()

View File

@ -1,173 +0,0 @@
from datetime import datetime
import re
class View:
"""Prompt menu, get choices"""
def __init__(self):
pass
def check_date(self):
while True:
date = input("Date de naissance (jj/mm/aaaa) ? : ")
if datetime.strptime(date, '%d/%m/%Y'):
break
else:
print("La date doit être au format jj/mm/aaaa")
def test_ine(self):
ine_pattern = r'[a-zA-Z]{2}\d{5}'
while True:
ine = input("Identifiant National d'Echecs (ine) ? : ")
if re.match(ine_pattern, ine):
break
else:
print("Mauvais format d'ine")
def prompt_for_scores(self):
print()
input("Saisir les scores ? (y)")
return True
def prompt_next(self):
print()
input("?")
return True
def prompt_for_round(self, round):
print()
input(f"Prêt à lancer le {round.name} ? (y)")
return True
def prompt_for_new_player(self) -> dict:
print("Enregistrez un nouveau joueur :\n")
lastname = input("Nom de famille ? : ")
name = input("Prénom ? : ")
birthdate = input("Date de naissance (jj/mm/aaaa) ? : ")
ine = input("Identifiant National d'Echecs (ine) ? : ")
return {'name': name,
'lastname': lastname,
'birthdate': birthdate,
'ine': ine}
def prompt_for_tournament(self) -> dict:
tournament_details = {}
tournament_details['name'] = str.lower(input("Nom du tournoi ? : "))
tournament_details['location'] = str.lower(input("Lieu du tournoi : "))
tournament_details['date_start'] = (
input("date de début (jj/mm/aaaa) : [today] "
or datetime.now().strftime("%d/%m/%Y")))
tournament_details['date_end'] = (
input("date de fin (jj/mm/aaaa) : [today] "
or datetime.now().strftime("%d/%m/%Y")))
tournament_details['description'] = input("Description ? : ")
total_round = input("Nombre de tours ? (4 par défaut) : ") or 4
tournament_details['total_round'] = int(total_round)
return tournament_details
def prompt_tournament_to_display(self, tournament_list_to_display):
i = 0
temp_list = []
for tournament in tournament_list_to_display:
i += 1
print(i, ".", tournament)
temp_list.append(tournament)
num = int(input("Numéro du tournoi à afficher ? "))
return temp_list[num - 1]
def input_scores(self, match, count):
print("Scores pour le match", count, " :")
while True:
try:
result = input(f"1.{match.player1}, "
f"2.{match.player2}, "
f"3.Nul\n")
if result in ("1", "2", "3"):
return result
else:
print("Entrez un chiffre entre 1 et 3")
except ValueError:
print("Veuillez entrer un chiffre")
def display_matches(self, match_list):
print("Liste des matchs : ")
for match in match_list:
print(match.player1.name, match.player1.lastname.upper(),
"contre", match.player2.name, match.player2.lastname.upper(),
"(", match, ")"
)
def display_round_info(self, round):
print("\n -> ", round)
def display_scores(self, players_list):
print("\nLes scores sont :")
print("-----------------")
for i in players_list:
print(i.ine, ':', i.name, i.lastname, i.score)
def display_players(self, player_list_to_display):
print("\nListe des joueurs :")
for player in player_list_to_display:
print(f"{player.name} {str.upper(player.lastname)} ({player.ine})")
def display_tournaments(self, tournament_list_to_display):
print("\nListe des tournois : ")
for tournament in tournament_list_to_display:
print("-", tournament,
"le",
tournament_list_to_display[tournament]['start'])
def display_tournament_detail(self, tournament_to_display):
i = tournament_to_display
print("\n***************************************************")
print("\nNom du tournoi : ", i['name'])
print("Lieu : ", i['location'])
print("Description : ", i['description'])
print("Le tournoi a débuté le : ", i['start'])
print("Et s'est terminé le : ", i['end'])
print("\nLes participants étaient : ")
for j in i['players']:
print(j['ine'], "-", j['prénom'], str.upper(j['nom']))
print("\nLes matches et leurs résultats étaient :")
for j in i['rounds']:
print(j['Nom'])
print("Commencé à ", j['Debut'])
print("Terminé à ", j['Fin'])
print("Liste des matchs :")
for k in j['Matches']:
print(k)
print()
print("Les scores finaux :")
for j in i['players']:
print(j['prénom'], str.upper(j['nom']), ":", j['score'])
print("\n***************************************************")
def display_error(self):
print("Erreur de saisie, recommencez;")
def display_format_error(self):
print("\n**** Erreur de format de fichier")
def display_file_error(self, file):
print(f"\n**** Pas de fichier {file} trouvé :/")
def display_player_instructions(self):
print("Placez un fichier joueur dans le répertoire data "
"ou créez des nouveaux joueurs depuis le menu")
print()
def display_quit(self):
print("Bye !")
def display_error_already(self):
print("Déjà joué")
def ok_player(self):
print("\nJoueur créé.")
def ok_go(self):
print("\n!!! C'est parti !!!\n")
def ok_done(self, name):
print(f"\nLe tournoi {name} est terminé !\n")

View File

@ -1,38 +0,0 @@
class Menu:
def __init__(self):
self.ITEMS = [
"[1] Créer un nouveau tournoi",
"[2] Enregistrer un nouveau joueur",
"[3] Rapports",
"[4] Quitter"
]
self.RAPPORTS = [
"[1] Afficher la liste des joueurs",
"[2] Afficher l'historique des tournois",
"[3] Afficher le détail d'un tournoi",
"[4] Retour"
]
def items(self, value):
"""displays menu depending on given value"""
menu_type = []
if value == 1:
menu_type = self.ITEMS
print()
print("MENU GENERAL")
if value == 2:
menu_type = self.RAPPORTS
print()
print("MENU RAPPORTS")
for i in menu_type:
print(i)
while True:
try:
choice = input("Choix ? : ")
if int(choice) not in range(1, len(menu_type) + 1):
print("Choisissez un chiffre entre 1 et", len(menu_type))
else:
return choice
except ValueError:
print("Veuillez entrer un chiffre")

7
vrac.py Normal file
View File

@ -0,0 +1,7 @@
# generate player list
from random import randint
list = []
for i in range(16):
list.append(["Player"+str(i+1), randint(0, 8)])