leave pdoc for classic latex documentation

This commit is contained in:
Mylloon 2021-11-19 21:14:14 +01:00
parent cf833625e3
commit e6e87732f2
7 changed files with 184 additions and 1138 deletions

4
.gitignore vendored
View file

@ -1,4 +1,8 @@
__pycache__/
documentation/*
*.pdf
*.sqlite3
!documentation/documentation.pdf
!documentation/documentation.tex

View file

@ -52,9 +52,3 @@ A savoir :
- [ ] Exporter le ticket de caisse en format image
- [x] Lisibilité du code
- [x] Toutes les fonctions sont nommés et typés (j'utilises `Python 3.9.7`)
### Crédit pour la documentation
Pour générer la documentation présente [ici](doc/) vous aurez besoin de [pdoc](https://pdoc3.github.io/pdoc/), ainsi pour la générer, vous devez lancez cette commande :
```
python3 -m pdoc --html -fc "html_lang='fr'" -o ./documentation .
```

View file

@ -1,275 +0,0 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.10.0" />
<title>GesMag.db API documentation</title>
<meta name="description" content="" />
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>GesMag.db</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">import sqlite3
from sqlite3.dbapi2 import Cursor
class BaseDeDonnees:
&#34;&#34;&#34;Gère la base de donnée.&#34;&#34;&#34;
def __init__(self, urlBaseDeDonnee: str):
self.connexion = self.creerConnexion(urlBaseDeDonnee)
def creerConnexion(self, path: str):
&#34;&#34;&#34;Connexion à une base de donnée SQLite.&#34;&#34;&#34;
if not self.fichierExiste(path): # si l base de donnée n&#39;existe pas
open(path, &#34;x&#34;) # on la créer
try:
connnexion = sqlite3.connect(path)
except sqlite3.Error as e:
print(e) # on affiche l&#39;erreur
connnexion = None # et renvoie None
return connnexion
def fichierExiste(self, path: str) -&gt; bool:
&#34;&#34;&#34;Vérifie qu&#39;un fichier existe.&#34;&#34;&#34;
try: # on essaie d&#39;ouvrir le fichier
open(path, &#34;r&#34;)
except FileNotFoundError: # si le fichier n&#39;existe pas
return False
else: # si le fichier existe
return True
def requete(self, requete: str, valeurs = None):
&#34;&#34;&#34;Envois une requête vers la base de données.&#34;&#34;&#34;
try:
curseur = self.connexion.cursor()
if valeurs: # s&#39;il y a des valeurs alors on lance la commande `execute` avec ses dernières
if type(valeurs) not in [list, tuple]: # si la valeur c&#39;est juste une chaîne de charactère (par exemple), alors la converti en liste
valeurs = [valeurs]
curseur.execute(requete, valeurs)
else: # sinon on lance juste la requête
curseur.execute(requete)
self.connexion.commit() # applique les changements à la base de donnée
return (curseur, curseur.lastrowid) # renvoie le curseur et l&#39;ID de l&#39;élément modifié
except sqlite3.Error as e: # s&#39;il y a eu une erreur SQLite
print(e)
def affichageResultat(self, curseur: Cursor) -&gt; list:
&#34;&#34;&#34;Affiche le résultat d&#39;une requête.&#34;&#34;&#34;
tableau = []
if curseur == None: # si le curseur est vide il n&#39;y a rien a affiché (tableau vide)
return tableau
lignes = curseur[0].fetchall() # sinon on récupère les éléments
for ligne in lignes:
tableau.append(ligne) # on les ajoute au tableau
return tableau # on le renvoie</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="GesMag.db.BaseDeDonnees"><code class="flex name class">
<span>class <span class="ident">BaseDeDonnees</span></span>
<span>(</span><span>urlBaseDeDonnee: str)</span>
</code></dt>
<dd>
<div class="desc"><p>Gère la base de donnée.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class BaseDeDonnees:
&#34;&#34;&#34;Gère la base de donnée.&#34;&#34;&#34;
def __init__(self, urlBaseDeDonnee: str):
self.connexion = self.creerConnexion(urlBaseDeDonnee)
def creerConnexion(self, path: str):
&#34;&#34;&#34;Connexion à une base de donnée SQLite.&#34;&#34;&#34;
if not self.fichierExiste(path): # si l base de donnée n&#39;existe pas
open(path, &#34;x&#34;) # on la créer
try:
connnexion = sqlite3.connect(path)
except sqlite3.Error as e:
print(e) # on affiche l&#39;erreur
connnexion = None # et renvoie None
return connnexion
def fichierExiste(self, path: str) -&gt; bool:
&#34;&#34;&#34;Vérifie qu&#39;un fichier existe.&#34;&#34;&#34;
try: # on essaie d&#39;ouvrir le fichier
open(path, &#34;r&#34;)
except FileNotFoundError: # si le fichier n&#39;existe pas
return False
else: # si le fichier existe
return True
def requete(self, requete: str, valeurs = None):
&#34;&#34;&#34;Envois une requête vers la base de données.&#34;&#34;&#34;
try:
curseur = self.connexion.cursor()
if valeurs: # s&#39;il y a des valeurs alors on lance la commande `execute` avec ses dernières
if type(valeurs) not in [list, tuple]: # si la valeur c&#39;est juste une chaîne de charactère (par exemple), alors la converti en liste
valeurs = [valeurs]
curseur.execute(requete, valeurs)
else: # sinon on lance juste la requête
curseur.execute(requete)
self.connexion.commit() # applique les changements à la base de donnée
return (curseur, curseur.lastrowid) # renvoie le curseur et l&#39;ID de l&#39;élément modifié
except sqlite3.Error as e: # s&#39;il y a eu une erreur SQLite
print(e)
def affichageResultat(self, curseur: Cursor) -&gt; list:
&#34;&#34;&#34;Affiche le résultat d&#39;une requête.&#34;&#34;&#34;
tableau = []
if curseur == None: # si le curseur est vide il n&#39;y a rien a affiché (tableau vide)
return tableau
lignes = curseur[0].fetchall() # sinon on récupère les éléments
for ligne in lignes:
tableau.append(ligne) # on les ajoute au tableau
return tableau # on le renvoie</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="GesMag.db.BaseDeDonnees.affichageResultat"><code class="name flex">
<span>def <span class="ident">affichageResultat</span></span>(<span>self, curseur: sqlite3.Cursor) > list</span>
</code></dt>
<dd>
<div class="desc"><p>Affiche le résultat d'une requête.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def affichageResultat(self, curseur: Cursor) -&gt; list:
&#34;&#34;&#34;Affiche le résultat d&#39;une requête.&#34;&#34;&#34;
tableau = []
if curseur == None: # si le curseur est vide il n&#39;y a rien a affiché (tableau vide)
return tableau
lignes = curseur[0].fetchall() # sinon on récupère les éléments
for ligne in lignes:
tableau.append(ligne) # on les ajoute au tableau
return tableau # on le renvoie</code></pre>
</details>
</dd>
<dt id="GesMag.db.BaseDeDonnees.creerConnexion"><code class="name flex">
<span>def <span class="ident">creerConnexion</span></span>(<span>self, path: str)</span>
</code></dt>
<dd>
<div class="desc"><p>Connexion à une base de donnée SQLite.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def creerConnexion(self, path: str):
&#34;&#34;&#34;Connexion à une base de donnée SQLite.&#34;&#34;&#34;
if not self.fichierExiste(path): # si l base de donnée n&#39;existe pas
open(path, &#34;x&#34;) # on la créer
try:
connnexion = sqlite3.connect(path)
except sqlite3.Error as e:
print(e) # on affiche l&#39;erreur
connnexion = None # et renvoie None
return connnexion</code></pre>
</details>
</dd>
<dt id="GesMag.db.BaseDeDonnees.fichierExiste"><code class="name flex">
<span>def <span class="ident">fichierExiste</span></span>(<span>self, path: str) > bool</span>
</code></dt>
<dd>
<div class="desc"><p>Vérifie qu'un fichier existe.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def fichierExiste(self, path: str) -&gt; bool:
&#34;&#34;&#34;Vérifie qu&#39;un fichier existe.&#34;&#34;&#34;
try: # on essaie d&#39;ouvrir le fichier
open(path, &#34;r&#34;)
except FileNotFoundError: # si le fichier n&#39;existe pas
return False
else: # si le fichier existe
return True</code></pre>
</details>
</dd>
<dt id="GesMag.db.BaseDeDonnees.requete"><code class="name flex">
<span>def <span class="ident">requete</span></span>(<span>self, requete: str, valeurs=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Envois une requête vers la base de données.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def requete(self, requete: str, valeurs = None):
&#34;&#34;&#34;Envois une requête vers la base de données.&#34;&#34;&#34;
try:
curseur = self.connexion.cursor()
if valeurs: # s&#39;il y a des valeurs alors on lance la commande `execute` avec ses dernières
if type(valeurs) not in [list, tuple]: # si la valeur c&#39;est juste une chaîne de charactère (par exemple), alors la converti en liste
valeurs = [valeurs]
curseur.execute(requete, valeurs)
else: # sinon on lance juste la requête
curseur.execute(requete)
self.connexion.commit() # applique les changements à la base de donnée
return (curseur, curseur.lastrowid) # renvoie le curseur et l&#39;ID de l&#39;élément modifié
except sqlite3.Error as e: # s&#39;il y a eu une erreur SQLite
print(e)</code></pre>
</details>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="GesMag" href="index.html">GesMag</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="GesMag.db.BaseDeDonnees" href="#GesMag.db.BaseDeDonnees">BaseDeDonnees</a></code></h4>
<ul class="">
<li><code><a title="GesMag.db.BaseDeDonnees.affichageResultat" href="#GesMag.db.BaseDeDonnees.affichageResultat">affichageResultat</a></code></li>
<li><code><a title="GesMag.db.BaseDeDonnees.creerConnexion" href="#GesMag.db.BaseDeDonnees.creerConnexion">creerConnexion</a></code></li>
<li><code><a title="GesMag.db.BaseDeDonnees.fichierExiste" href="#GesMag.db.BaseDeDonnees.fichierExiste">fichierExiste</a></code></li>
<li><code><a title="GesMag.db.BaseDeDonnees.requete" href="#GesMag.db.BaseDeDonnees.requete">requete</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
</footer>
</body>
</html>

View file

@ -1,70 +0,0 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.10.0" />
<title>GesMag API documentation</title>
<meta name="description" content="" />
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Namespace <code>GesMag</code></h1>
</header>
<section id="section-intro">
</section>
<section>
<h2 class="section-title" id="header-submodules">Sub-modules</h2>
<dl>
<dt><code class="name"><a title="GesMag.db" href="db.html">GesMag.db</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="GesMag.main" href="main.html">GesMag.main</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt><code class="name"><a title="GesMag.users" href="users.html">GesMag.users</a></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3><a href="#header-submodules">Sub-modules</a></h3>
<ul>
<li><code><a title="GesMag.db" href="db.html">GesMag.db</a></code></li>
<li><code><a title="GesMag.main" href="main.html">GesMag.main</a></code></li>
<li><code><a title="GesMag.users" href="users.html">GesMag.users</a></code></li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
</footer>
</body>
</html>

View file

@ -1,430 +0,0 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.10.0" />
<title>GesMag.main API documentation</title>
<meta name="description" content="" />
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>GesMag.main</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">import tkinter.messagebox as messagebox
from tkinter import *
from re import sub
from users import Utilisateurs # import de mon fichier pour gérer la base de donnée
def dimensionsFenetre(fenetre, taille: tuple):
&#34;&#34;&#34;Permet de définir une fenetre centrer sur l&#39;écran&#34;&#34;&#34;
largeur = fenetre.winfo_screenwidth()
hauteur = fenetre.winfo_screenheight()
x = (largeur // 2) - (taille[0] // 2)
y = (hauteur // 2) - (taille[1] // 2)
fenetre.geometry(f&#34;{taille[0]}x{taille[1]}+{x}+{y}&#34;)
class GesMag:
&#34;&#34;&#34;Programme de Gestion d&#39;une caise de magasin.&#34;&#34;&#34;
def demarrer(self) -&gt; None:
&#34;&#34;&#34;Lance le programme GesMag.&#34;&#34;&#34;
print(&#34;Lancement de l&#39;interface de gestion d&#39;une caisse d&#39;un magasin...&#34;)
self.font = (&#34;Comfortaa&#34;, 14) # police par défaut
Utilisateurs().creationTable() # on créer la base de donnée si elle n&#39;existe pas déjà
self.parent = Tk() # on créer notre fenêtre principale
self._interfaceConnexion() # on créer la variable `self.f` qui est la frame a affiché
self.f.grid() # on affiche la frame
self.parent.mainloop() # on affiche la fenêtre
def motDePasseCorrect(self, motDPasse: str) -&gt; tuple:
&#34;&#34;&#34;Détermine si un mot de passe suit la politique du programme ou non.&#34;&#34;&#34;
if len(motDPasse) == 0: # si le champs est vide
return (False, &#34;Mot de passe incorrect.&#34;)
if len(motDPasse) &lt; 8: # si le mot de passe est plus petit que 8 caractères
return (False, &#34;Un mot de passe doit faire 8 caractères minimum.&#34;)
&#34;&#34;&#34;
Pour le regex, je réfléchie comme dans la fonction `self.connexion`.
J&#39;utilises pas `match` parce que je suis plus à l&#39;aise avec `sub`.
&#34;&#34;&#34;
if not sub(r&#34;[A-Z]&#34;, &#39;&#39;, motDPasse) != motDPasse:
return (False, &#34;Un mot de passe doit au moins contenir une lettre majuscule.&#34;)
if not sub(r&#34;[a-z]&#34;, &#39;&#39;, motDPasse) != motDPasse:
return (False, &#34;Un mot de passe doit au moins contenir une lettre minuscule.&#34;)
if not sub(r&#34; *?[^\w\s]+&#34;, &#39;&#39;, motDPasse) != motDPasse:
return (False, &#34;Un mot de passe doit au moins contenir un caractère spécial.&#34;)
return (True,) # si aucun des tests précédents n&#39;est valide, alors le mot de passe est valide
def connexion(self, utilisateur: str, motDePasse: str):
&#34;&#34;&#34;Gère la connexion aux différentes interfaces de l&#39;application.&#34;&#34;&#34;
&#34;&#34;&#34;
Vérification nom d&#39;utilisateur / mot de passe correctement entré
-&gt; Pour le nom d&#39;utilisateur on vérifie si le champs n&#39;est pas vide
et si il y a bien que des lettres et des chiffres (le regex élimine tout
ce qui n&#39;est pas ça, alors si la fonction `sub` renvoie pas exactement
la même chaîne de charactère alors c&#39;est qu&#39;il y avait un charactère
interdit dans le nom d&#39;utilisateur).
-&gt; Pour le mot de passe on demande à la fonction `motDePasseCorrect` pour
éviter de faire tout les tests ici.
&#34;&#34;&#34;
if len(utilisateur) == 0 or sub(r&#34; *?[^\w\s]+&#34;, &#39;&#39;, utilisateur) != utilisateur:
messagebox.showerror(&#34;Erreur&#34;, &#34;Utilisateur incorrect.&#34;)
return
mdpOk = self.motDePasseCorrect(motDePasse)
if not mdpOk[0]:
messagebox.showerror(&#34;Erreur&#34;, mdpOk[1])
return
# Redirection vers la bonne interface
if Utilisateurs().verificationIdentifiants(utilisateur, motDePasse):
print(&#34;Bienvenue mon pote&#34;)
else:
print(f&#34;Bah nan frérot c&#39;est pas bon, ça c&#39;est la liste des utilisateurs : {Utilisateurs().listUtilisateurs()}&#34;)
def _interfaceConnexion(self):
&#34;&#34;&#34;Affiche la fenêtre de connexion.&#34;&#34;&#34;
# Paramètres de la fenêtre
dimensionsFenetre(self.parent, (400, 600))
self.parent.title(&#34;Fenêtre de connexion&#34;)
# Instanciation de la Frame, on va donc ajouter tout nos widgets à cet Frame
self.f = Frame(self.parent)
# Affichage des labels et boutons
tentativeDeConnexion = lambda _ = None: self.connexion(utilisateur.get(), motDpasse.get()) # lambda pour envoyer les informations entrés dans le formulaire
ecart = 80 # écart pour avoir un affichage centré
Label(self.f).grid(row=0, pady=50) # utilisé pour du padding (meilleur affichage)
Label(self.f, text=&#34;Utilisateur&#34;, font=self.font).grid(column=0, row=1, columnspan=2, padx=ecart - 20, pady=20, sticky=W)
utilisateur = Entry(self.f, font=self.font, width=18)
utilisateur.grid(column=1, row=2, columnspan=2, padx=ecart)
Label(self.f, text=&#34;Mot de passe&#34;, font=self.font).grid(column=0, row=3, columnspan=2, padx=ecart - 20, pady=20, sticky=W)
motDpasse = Entry(self.f, font=self.font, show=&#39;&#39;, width=18)
motDpasse.grid(column=1, row=4, columnspan=2, padx=ecart)
motDpasse.bind(&#34;&lt;Return&gt;&#34;, tentativeDeConnexion)
def __afficherMDP(self):
&#34;&#34;&#34;Permet de gérer l&#39;affichage du mot de passe dans le champs sur la page de connexion.&#34;&#34;&#34;
if self.mdpVisible == False: # si mot de passe caché, alors on l&#39;affiche
self.mdpVisible = True
motDpasse.config(show=&#39;&#39;)
bouttonAffichageMDP.config(font=(&#34;Arial&#34;, 10, &#34;overstrike&#34;))
else: # inversement
self.mdpVisible = False
motDpasse.config(show=&#39;&#39;)
bouttonAffichageMDP.config(font=(&#34;Arial&#34;, 10))
bouttonAffichageMDP = Button(self.f, text=&#39;👁&#39;, command=lambda: __afficherMDP(self))
bouttonAffichageMDP.grid(column=2, row=4, columnspan=2)
self.mdpVisible = False
bouton = Button(self.f, text=&#34;Se connecter&#34;, font=self.font, command=tentativeDeConnexion)
bouton.grid(column=0, row=5, columnspan=3, padx=ecart, pady=20)
bouton.bind(&#34;&lt;Return&gt;&#34;, tentativeDeConnexion)
Button(self.f, text=&#34;Quitter&#34;, font=self.font, command=quit).grid(column=0, row=6, columnspan=4, pady=20)
if __name__ == &#34;__main__&#34;:
&#34;&#34;&#34;&#34;Application &#34;GesMag&#34; pour le module de Programmation d&#39;interfaces (2021-2022)&#34;&#34;&#34;
print(&#34;-- Compte par défaut --\nNom d&#39;utilisateur: admin\nMot de passe: P@ssword\n&#34;)
GesMag().demarrer()</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="GesMag.main.dimensionsFenetre"><code class="name flex">
<span>def <span class="ident">dimensionsFenetre</span></span>(<span>fenetre, taille: tuple)</span>
</code></dt>
<dd>
<div class="desc"><p>Permet de définir une fenetre centrer sur l'écran</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def dimensionsFenetre(fenetre, taille: tuple):
&#34;&#34;&#34;Permet de définir une fenetre centrer sur l&#39;écran&#34;&#34;&#34;
largeur = fenetre.winfo_screenwidth()
hauteur = fenetre.winfo_screenheight()
x = (largeur // 2) - (taille[0] // 2)
y = (hauteur // 2) - (taille[1] // 2)
fenetre.geometry(f&#34;{taille[0]}x{taille[1]}+{x}+{y}&#34;)</code></pre>
</details>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="GesMag.main.GesMag"><code class="flex name class">
<span>class <span class="ident">GesMag</span></span>
</code></dt>
<dd>
<div class="desc"><p>Programme de Gestion d'une caise de magasin.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class GesMag:
&#34;&#34;&#34;Programme de Gestion d&#39;une caise de magasin.&#34;&#34;&#34;
def demarrer(self) -&gt; None:
&#34;&#34;&#34;Lance le programme GesMag.&#34;&#34;&#34;
print(&#34;Lancement de l&#39;interface de gestion d&#39;une caisse d&#39;un magasin...&#34;)
self.font = (&#34;Comfortaa&#34;, 14) # police par défaut
Utilisateurs().creationTable() # on créer la base de donnée si elle n&#39;existe pas déjà
self.parent = Tk() # on créer notre fenêtre principale
self._interfaceConnexion() # on créer la variable `self.f` qui est la frame a affiché
self.f.grid() # on affiche la frame
self.parent.mainloop() # on affiche la fenêtre
def motDePasseCorrect(self, motDPasse: str) -&gt; tuple:
&#34;&#34;&#34;Détermine si un mot de passe suit la politique du programme ou non.&#34;&#34;&#34;
if len(motDPasse) == 0: # si le champs est vide
return (False, &#34;Mot de passe incorrect.&#34;)
if len(motDPasse) &lt; 8: # si le mot de passe est plus petit que 8 caractères
return (False, &#34;Un mot de passe doit faire 8 caractères minimum.&#34;)
&#34;&#34;&#34;
Pour le regex, je réfléchie comme dans la fonction `self.connexion`.
J&#39;utilises pas `match` parce que je suis plus à l&#39;aise avec `sub`.
&#34;&#34;&#34;
if not sub(r&#34;[A-Z]&#34;, &#39;&#39;, motDPasse) != motDPasse:
return (False, &#34;Un mot de passe doit au moins contenir une lettre majuscule.&#34;)
if not sub(r&#34;[a-z]&#34;, &#39;&#39;, motDPasse) != motDPasse:
return (False, &#34;Un mot de passe doit au moins contenir une lettre minuscule.&#34;)
if not sub(r&#34; *?[^\w\s]+&#34;, &#39;&#39;, motDPasse) != motDPasse:
return (False, &#34;Un mot de passe doit au moins contenir un caractère spécial.&#34;)
return (True,) # si aucun des tests précédents n&#39;est valide, alors le mot de passe est valide
def connexion(self, utilisateur: str, motDePasse: str):
&#34;&#34;&#34;Gère la connexion aux différentes interfaces de l&#39;application.&#34;&#34;&#34;
&#34;&#34;&#34;
Vérification nom d&#39;utilisateur / mot de passe correctement entré
-&gt; Pour le nom d&#39;utilisateur on vérifie si le champs n&#39;est pas vide
et si il y a bien que des lettres et des chiffres (le regex élimine tout
ce qui n&#39;est pas ça, alors si la fonction `sub` renvoie pas exactement
la même chaîne de charactère alors c&#39;est qu&#39;il y avait un charactère
interdit dans le nom d&#39;utilisateur).
-&gt; Pour le mot de passe on demande à la fonction `motDePasseCorrect` pour
éviter de faire tout les tests ici.
&#34;&#34;&#34;
if len(utilisateur) == 0 or sub(r&#34; *?[^\w\s]+&#34;, &#39;&#39;, utilisateur) != utilisateur:
messagebox.showerror(&#34;Erreur&#34;, &#34;Utilisateur incorrect.&#34;)
return
mdpOk = self.motDePasseCorrect(motDePasse)
if not mdpOk[0]:
messagebox.showerror(&#34;Erreur&#34;, mdpOk[1])
return
# Redirection vers la bonne interface
if Utilisateurs().verificationIdentifiants(utilisateur, motDePasse):
print(&#34;Bienvenue mon pote&#34;)
else:
print(f&#34;Bah nan frérot c&#39;est pas bon, ça c&#39;est la liste des utilisateurs : {Utilisateurs().listUtilisateurs()}&#34;)
def _interfaceConnexion(self):
&#34;&#34;&#34;Affiche la fenêtre de connexion.&#34;&#34;&#34;
# Paramètres de la fenêtre
dimensionsFenetre(self.parent, (400, 600))
self.parent.title(&#34;Fenêtre de connexion&#34;)
# Instanciation de la Frame, on va donc ajouter tout nos widgets à cet Frame
self.f = Frame(self.parent)
# Affichage des labels et boutons
tentativeDeConnexion = lambda _ = None: self.connexion(utilisateur.get(), motDpasse.get()) # lambda pour envoyer les informations entrés dans le formulaire
ecart = 80 # écart pour avoir un affichage centré
Label(self.f).grid(row=0, pady=50) # utilisé pour du padding (meilleur affichage)
Label(self.f, text=&#34;Utilisateur&#34;, font=self.font).grid(column=0, row=1, columnspan=2, padx=ecart - 20, pady=20, sticky=W)
utilisateur = Entry(self.f, font=self.font, width=18)
utilisateur.grid(column=1, row=2, columnspan=2, padx=ecart)
Label(self.f, text=&#34;Mot de passe&#34;, font=self.font).grid(column=0, row=3, columnspan=2, padx=ecart - 20, pady=20, sticky=W)
motDpasse = Entry(self.f, font=self.font, show=&#39;&#39;, width=18)
motDpasse.grid(column=1, row=4, columnspan=2, padx=ecart)
motDpasse.bind(&#34;&lt;Return&gt;&#34;, tentativeDeConnexion)
def __afficherMDP(self):
&#34;&#34;&#34;Permet de gérer l&#39;affichage du mot de passe dans le champs sur la page de connexion.&#34;&#34;&#34;
if self.mdpVisible == False: # si mot de passe caché, alors on l&#39;affiche
self.mdpVisible = True
motDpasse.config(show=&#39;&#39;)
bouttonAffichageMDP.config(font=(&#34;Arial&#34;, 10, &#34;overstrike&#34;))
else: # inversement
self.mdpVisible = False
motDpasse.config(show=&#39;&#39;)
bouttonAffichageMDP.config(font=(&#34;Arial&#34;, 10))
bouttonAffichageMDP = Button(self.f, text=&#39;👁&#39;, command=lambda: __afficherMDP(self))
bouttonAffichageMDP.grid(column=2, row=4, columnspan=2)
self.mdpVisible = False
bouton = Button(self.f, text=&#34;Se connecter&#34;, font=self.font, command=tentativeDeConnexion)
bouton.grid(column=0, row=5, columnspan=3, padx=ecart, pady=20)
bouton.bind(&#34;&lt;Return&gt;&#34;, tentativeDeConnexion)
Button(self.f, text=&#34;Quitter&#34;, font=self.font, command=quit).grid(column=0, row=6, columnspan=4, pady=20)</code></pre>
</details>
<h3>Methods</h3>
<dl>
<dt id="GesMag.main.GesMag.connexion"><code class="name flex">
<span>def <span class="ident">connexion</span></span>(<span>self, utilisateur: str, motDePasse: str)</span>
</code></dt>
<dd>
<div class="desc"><p>Gère la connexion aux différentes interfaces de l'application.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def connexion(self, utilisateur: str, motDePasse: str):
&#34;&#34;&#34;Gère la connexion aux différentes interfaces de l&#39;application.&#34;&#34;&#34;
&#34;&#34;&#34;
Vérification nom d&#39;utilisateur / mot de passe correctement entré
-&gt; Pour le nom d&#39;utilisateur on vérifie si le champs n&#39;est pas vide
et si il y a bien que des lettres et des chiffres (le regex élimine tout
ce qui n&#39;est pas ça, alors si la fonction `sub` renvoie pas exactement
la même chaîne de charactère alors c&#39;est qu&#39;il y avait un charactère
interdit dans le nom d&#39;utilisateur).
-&gt; Pour le mot de passe on demande à la fonction `motDePasseCorrect` pour
éviter de faire tout les tests ici.
&#34;&#34;&#34;
if len(utilisateur) == 0 or sub(r&#34; *?[^\w\s]+&#34;, &#39;&#39;, utilisateur) != utilisateur:
messagebox.showerror(&#34;Erreur&#34;, &#34;Utilisateur incorrect.&#34;)
return
mdpOk = self.motDePasseCorrect(motDePasse)
if not mdpOk[0]:
messagebox.showerror(&#34;Erreur&#34;, mdpOk[1])
return
# Redirection vers la bonne interface
if Utilisateurs().verificationIdentifiants(utilisateur, motDePasse):
print(&#34;Bienvenue mon pote&#34;)
else:
print(f&#34;Bah nan frérot c&#39;est pas bon, ça c&#39;est la liste des utilisateurs : {Utilisateurs().listUtilisateurs()}&#34;)</code></pre>
</details>
</dd>
<dt id="GesMag.main.GesMag.demarrer"><code class="name flex">
<span>def <span class="ident">demarrer</span></span>(<span>self) > None</span>
</code></dt>
<dd>
<div class="desc"><p>Lance le programme GesMag.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def demarrer(self) -&gt; None:
&#34;&#34;&#34;Lance le programme GesMag.&#34;&#34;&#34;
print(&#34;Lancement de l&#39;interface de gestion d&#39;une caisse d&#39;un magasin...&#34;)
self.font = (&#34;Comfortaa&#34;, 14) # police par défaut
Utilisateurs().creationTable() # on créer la base de donnée si elle n&#39;existe pas déjà
self.parent = Tk() # on créer notre fenêtre principale
self._interfaceConnexion() # on créer la variable `self.f` qui est la frame a affiché
self.f.grid() # on affiche la frame
self.parent.mainloop() # on affiche la fenêtre</code></pre>
</details>
</dd>
<dt id="GesMag.main.GesMag.motDePasseCorrect"><code class="name flex">
<span>def <span class="ident">motDePasseCorrect</span></span>(<span>self, motDPasse: str) > tuple</span>
</code></dt>
<dd>
<div class="desc"><p>Détermine si un mot de passe suit la politique du programme ou non.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def motDePasseCorrect(self, motDPasse: str) -&gt; tuple:
&#34;&#34;&#34;Détermine si un mot de passe suit la politique du programme ou non.&#34;&#34;&#34;
if len(motDPasse) == 0: # si le champs est vide
return (False, &#34;Mot de passe incorrect.&#34;)
if len(motDPasse) &lt; 8: # si le mot de passe est plus petit que 8 caractères
return (False, &#34;Un mot de passe doit faire 8 caractères minimum.&#34;)
&#34;&#34;&#34;
Pour le regex, je réfléchie comme dans la fonction `self.connexion`.
J&#39;utilises pas `match` parce que je suis plus à l&#39;aise avec `sub`.
&#34;&#34;&#34;
if not sub(r&#34;[A-Z]&#34;, &#39;&#39;, motDPasse) != motDPasse:
return (False, &#34;Un mot de passe doit au moins contenir une lettre majuscule.&#34;)
if not sub(r&#34;[a-z]&#34;, &#39;&#39;, motDPasse) != motDPasse:
return (False, &#34;Un mot de passe doit au moins contenir une lettre minuscule.&#34;)
if not sub(r&#34; *?[^\w\s]+&#34;, &#39;&#39;, motDPasse) != motDPasse:
return (False, &#34;Un mot de passe doit au moins contenir un caractère spécial.&#34;)
return (True,) # si aucun des tests précédents n&#39;est valide, alors le mot de passe est valide</code></pre>
</details>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="GesMag" href="index.html">GesMag</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="GesMag.main.dimensionsFenetre" href="#GesMag.main.dimensionsFenetre">dimensionsFenetre</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="GesMag.main.GesMag" href="#GesMag.main.GesMag">GesMag</a></code></h4>
<ul class="">
<li><code><a title="GesMag.main.GesMag.connexion" href="#GesMag.main.GesMag.connexion">connexion</a></code></li>
<li><code><a title="GesMag.main.GesMag.demarrer" href="#GesMag.main.GesMag.demarrer">demarrer</a></code></li>
<li><code><a title="GesMag.main.GesMag.motDePasseCorrect" href="#GesMag.main.GesMag.motDePasseCorrect">motDePasseCorrect</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
</footer>
</body>
</html>

View file

@ -1,357 +0,0 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.10.0" />
<title>GesMag.users API documentation</title>
<meta name="description" content="" />
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>GesMag.users</code></h1>
</header>
<section id="section-intro">
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">from db import BaseDeDonnees
class Utilisateurs(BaseDeDonnees):
&#34;&#34;&#34;Gère une table &#34;utilisateurs&#34; pour une base de donnée donné.&#34;&#34;&#34;
def __init__(self):
super().__init__(r&#34;utilisateurs.sqlite3&#34;)
def creationTable(self) -&gt; None:
&#34;&#34;&#34;Créer la table qui stocker les utilisateurs.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
CREATE TABLE IF NOT EXISTS utilisateurs (
id INTEGER PRIMARY KEY,
pseudo TEXT,
passe TEXT,
metier INTEGER,
nom TEXT,
prenom TEXT,
naissance TEXT,
adresse TEXT,
postal INTEGER
);
&#34;&#34;&#34;
self.requete(requete)
# Ajout d&#39;un utilisateur par défaut si aucun utilisateur n&#39;existe dans la base de donnée
if len(self.listUtilisateurs()) == 0:
self.ajoutUtilisateurs(
pseudo=&#34;admin&#34;,
passe=&#34;P@ssword&#34;,
metier=0,
nom=&#34;Admin&#34;,
prenom=&#34;Admin&#34;,
naissance=&#34;2000/10/09&#34;,
adresse=&#34;12 Rue de Montmartre&#34;,
postal=46800
)
def ajoutUtilisateurs(self, pseudo: str, passe: str, metier: int, nom: str, prenom: str, naissance: str, adresse: str, postal: str) -&gt; list:
&#34;&#34;&#34;Ajoute un utilisateur et retourne l&#39;ID de ce dernier.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
INSERT INTO utilisateurs (
pseudo, passe, metier, nom, prenom, naissance, adresse, postal
) VALUES (
?, ?, ?, ?, ?, ?, ?, ?
);
&#34;&#34;&#34;
self.requete(requete, [pseudo, passe, metier, nom, prenom, naissance, adresse, postal])
return self.affichageResultat(self.requete(&#34;SELECT last_insert_rowid();&#34;))
def suppressionUtilisateurs(self, pseudo: str) -&gt; None:
&#34;&#34;&#34;Supprime un utilisateur.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
DELETE FROM utilisateurs
WHERE pseudo = ?
&#34;&#34;&#34;
self.requete(requete, pseudo)
def verificationIdentifiants(self, pseudo: str, motDePasse: str) -&gt; bool:
&#34;&#34;&#34;Renvoie vrai ou faux si les identifiants données sont bons.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
SELECT EXISTS (
SELECT 1 FROM utilisateurs
WHERE pseudo = ? AND passe = ?
)
&#34;&#34;&#34;
# Vrai si le premier élément que renvoie la requête au dessus est 1
return True if self.affichageResultat(self.requete(requete, [pseudo, motDePasse]))[0][0] == 1 else False
def listUtilisateurs(self) -&gt; list:
&#34;&#34;&#34;Retourne la liste des nom d&#39;utilisateurs.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
SELECT pseudo FROM utilisateurs
&#34;&#34;&#34;
# i[0] parce que sinon ça renvoie des Tuple qui ressemble à ça : `(Utilisateur,)`
return [i[0] for i in self.affichageResultat(self.requete(requete))]</code></pre>
</details>
</section>
<section>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="GesMag.users.Utilisateurs"><code class="flex name class">
<span>class <span class="ident">Utilisateurs</span></span>
</code></dt>
<dd>
<div class="desc"><p>Gère une table "utilisateurs" pour une base de donnée donné.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class Utilisateurs(BaseDeDonnees):
&#34;&#34;&#34;Gère une table &#34;utilisateurs&#34; pour une base de donnée donné.&#34;&#34;&#34;
def __init__(self):
super().__init__(r&#34;utilisateurs.sqlite3&#34;)
def creationTable(self) -&gt; None:
&#34;&#34;&#34;Créer la table qui stocker les utilisateurs.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
CREATE TABLE IF NOT EXISTS utilisateurs (
id INTEGER PRIMARY KEY,
pseudo TEXT,
passe TEXT,
metier INTEGER,
nom TEXT,
prenom TEXT,
naissance TEXT,
adresse TEXT,
postal INTEGER
);
&#34;&#34;&#34;
self.requete(requete)
# Ajout d&#39;un utilisateur par défaut si aucun utilisateur n&#39;existe dans la base de donnée
if len(self.listUtilisateurs()) == 0:
self.ajoutUtilisateurs(
pseudo=&#34;admin&#34;,
passe=&#34;P@ssword&#34;,
metier=0,
nom=&#34;Admin&#34;,
prenom=&#34;Admin&#34;,
naissance=&#34;2000/10/09&#34;,
adresse=&#34;12 Rue de Montmartre&#34;,
postal=46800
)
def ajoutUtilisateurs(self, pseudo: str, passe: str, metier: int, nom: str, prenom: str, naissance: str, adresse: str, postal: str) -&gt; list:
&#34;&#34;&#34;Ajoute un utilisateur et retourne l&#39;ID de ce dernier.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
INSERT INTO utilisateurs (
pseudo, passe, metier, nom, prenom, naissance, adresse, postal
) VALUES (
?, ?, ?, ?, ?, ?, ?, ?
);
&#34;&#34;&#34;
self.requete(requete, [pseudo, passe, metier, nom, prenom, naissance, adresse, postal])
return self.affichageResultat(self.requete(&#34;SELECT last_insert_rowid();&#34;))
def suppressionUtilisateurs(self, pseudo: str) -&gt; None:
&#34;&#34;&#34;Supprime un utilisateur.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
DELETE FROM utilisateurs
WHERE pseudo = ?
&#34;&#34;&#34;
self.requete(requete, pseudo)
def verificationIdentifiants(self, pseudo: str, motDePasse: str) -&gt; bool:
&#34;&#34;&#34;Renvoie vrai ou faux si les identifiants données sont bons.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
SELECT EXISTS (
SELECT 1 FROM utilisateurs
WHERE pseudo = ? AND passe = ?
)
&#34;&#34;&#34;
# Vrai si le premier élément que renvoie la requête au dessus est 1
return True if self.affichageResultat(self.requete(requete, [pseudo, motDePasse]))[0][0] == 1 else False
def listUtilisateurs(self) -&gt; list:
&#34;&#34;&#34;Retourne la liste des nom d&#39;utilisateurs.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
SELECT pseudo FROM utilisateurs
&#34;&#34;&#34;
# i[0] parce que sinon ça renvoie des Tuple qui ressemble à ça : `(Utilisateur,)`
return [i[0] for i in self.affichageResultat(self.requete(requete))]</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>db.BaseDeDonnees</li>
</ul>
<h3>Methods</h3>
<dl>
<dt id="GesMag.users.Utilisateurs.ajoutUtilisateurs"><code class="name flex">
<span>def <span class="ident">ajoutUtilisateurs</span></span>(<span>self, pseudo: str, passe: str, metier: int, nom: str, prenom: str, naissance: str, adresse: str, postal: str) > list</span>
</code></dt>
<dd>
<div class="desc"><p>Ajoute un utilisateur et retourne l'ID de ce dernier.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def ajoutUtilisateurs(self, pseudo: str, passe: str, metier: int, nom: str, prenom: str, naissance: str, adresse: str, postal: str) -&gt; list:
&#34;&#34;&#34;Ajoute un utilisateur et retourne l&#39;ID de ce dernier.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
INSERT INTO utilisateurs (
pseudo, passe, metier, nom, prenom, naissance, adresse, postal
) VALUES (
?, ?, ?, ?, ?, ?, ?, ?
);
&#34;&#34;&#34;
self.requete(requete, [pseudo, passe, metier, nom, prenom, naissance, adresse, postal])
return self.affichageResultat(self.requete(&#34;SELECT last_insert_rowid();&#34;))</code></pre>
</details>
</dd>
<dt id="GesMag.users.Utilisateurs.creationTable"><code class="name flex">
<span>def <span class="ident">creationTable</span></span>(<span>self) > None</span>
</code></dt>
<dd>
<div class="desc"><p>Créer la table qui stocker les utilisateurs.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def creationTable(self) -&gt; None:
&#34;&#34;&#34;Créer la table qui stocker les utilisateurs.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
CREATE TABLE IF NOT EXISTS utilisateurs (
id INTEGER PRIMARY KEY,
pseudo TEXT,
passe TEXT,
metier INTEGER,
nom TEXT,
prenom TEXT,
naissance TEXT,
adresse TEXT,
postal INTEGER
);
&#34;&#34;&#34;
self.requete(requete)
# Ajout d&#39;un utilisateur par défaut si aucun utilisateur n&#39;existe dans la base de donnée
if len(self.listUtilisateurs()) == 0:
self.ajoutUtilisateurs(
pseudo=&#34;admin&#34;,
passe=&#34;P@ssword&#34;,
metier=0,
nom=&#34;Admin&#34;,
prenom=&#34;Admin&#34;,
naissance=&#34;2000/10/09&#34;,
adresse=&#34;12 Rue de Montmartre&#34;,
postal=46800
)</code></pre>
</details>
</dd>
<dt id="GesMag.users.Utilisateurs.listUtilisateurs"><code class="name flex">
<span>def <span class="ident">listUtilisateurs</span></span>(<span>self) > list</span>
</code></dt>
<dd>
<div class="desc"><p>Retourne la liste des nom d'utilisateurs.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def listUtilisateurs(self) -&gt; list:
&#34;&#34;&#34;Retourne la liste des nom d&#39;utilisateurs.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
SELECT pseudo FROM utilisateurs
&#34;&#34;&#34;
# i[0] parce que sinon ça renvoie des Tuple qui ressemble à ça : `(Utilisateur,)`
return [i[0] for i in self.affichageResultat(self.requete(requete))]</code></pre>
</details>
</dd>
<dt id="GesMag.users.Utilisateurs.suppressionUtilisateurs"><code class="name flex">
<span>def <span class="ident">suppressionUtilisateurs</span></span>(<span>self, pseudo: str) > None</span>
</code></dt>
<dd>
<div class="desc"><p>Supprime un utilisateur.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def suppressionUtilisateurs(self, pseudo: str) -&gt; None:
&#34;&#34;&#34;Supprime un utilisateur.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
DELETE FROM utilisateurs
WHERE pseudo = ?
&#34;&#34;&#34;
self.requete(requete, pseudo)</code></pre>
</details>
</dd>
<dt id="GesMag.users.Utilisateurs.verificationIdentifiants"><code class="name flex">
<span>def <span class="ident">verificationIdentifiants</span></span>(<span>self, pseudo: str, motDePasse: str) > bool</span>
</code></dt>
<dd>
<div class="desc"><p>Renvoie vrai ou faux si les identifiants données sont bons.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def verificationIdentifiants(self, pseudo: str, motDePasse: str) -&gt; bool:
&#34;&#34;&#34;Renvoie vrai ou faux si les identifiants données sont bons.&#34;&#34;&#34;
requete = &#34;&#34;&#34;
SELECT EXISTS (
SELECT 1 FROM utilisateurs
WHERE pseudo = ? AND passe = ?
)
&#34;&#34;&#34;
# Vrai si le premier élément que renvoie la requête au dessus est 1
return True if self.affichageResultat(self.requete(requete, [pseudo, motDePasse]))[0][0] == 1 else False</code></pre>
</details>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul></ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="GesMag" href="index.html">GesMag</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="GesMag.users.Utilisateurs" href="#GesMag.users.Utilisateurs">Utilisateurs</a></code></h4>
<ul class="">
<li><code><a title="GesMag.users.Utilisateurs.ajoutUtilisateurs" href="#GesMag.users.Utilisateurs.ajoutUtilisateurs">ajoutUtilisateurs</a></code></li>
<li><code><a title="GesMag.users.Utilisateurs.creationTable" href="#GesMag.users.Utilisateurs.creationTable">creationTable</a></code></li>
<li><code><a title="GesMag.users.Utilisateurs.listUtilisateurs" href="#GesMag.users.Utilisateurs.listUtilisateurs">listUtilisateurs</a></code></li>
<li><code><a title="GesMag.users.Utilisateurs.suppressionUtilisateurs" href="#GesMag.users.Utilisateurs.suppressionUtilisateurs">suppressionUtilisateurs</a></code></li>
<li><code><a title="GesMag.users.Utilisateurs.verificationIdentifiants" href="#GesMag.users.Utilisateurs.verificationIdentifiants">verificationIdentifiants</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
</footer>
</body>
</html>

View file

@ -0,0 +1,180 @@
\documentclass{article}
\usepackage[french]{babel} % français
\usepackage[T1]{fontenc} % encodage
\usepackage[hidelinks]{hyperref} % liens cliquable dans la table des matières
\usepackage{graphicx} % images
\usepackage{listingsutf8} % intégration code
\usepackage{xcolor} % couleurs personnalisés
\usepackage{geometry} % change les dimensions de la page
\usepackage{enumitem} % liste personnalisée
\usepackage{amssymb, pifont} % police (todolist)
\geometry{ % définition taille pages
a4paper,
left=20mm,
top=20mm
}
% définition de la liste de choses à faire/faites (https://tex.stackexchange.com/q/247681/)
\newlist{todolist}{itemize}{3}
\setlist[todolist]{label=$\square$}
\newcommand{\fait}{\rlap{\raisebox{0.3ex}{\hspace{0.4ex}\scriptsize \ding{56}}}$\square$}
% définition blocs de codes
\lstset{
breaklines=true,
extendedchars=true,
inputencoding=utf8/latin1
}
% Python definition (c) 1998 Michael Weber
% Additional definitions (2013) Alexis Dimitriadis
% modified by https://tex.stackexchange.com/questions/235783/listings-recognize-numbers-and-1e-3
\definecolor{maroon}{cmyk}{0, 0.87, 0.68, 0.32}
\definecolor{halfgray}{gray}{0.55}
\definecolor{ipython_frame}{RGB}{207, 207, 207}
\definecolor{ipython_bg}{RGB}{247, 247, 247}
\definecolor{ipython_red}{RGB}{186, 33, 33}
\definecolor{ipython_green}{RGB}{0, 128, 0}
\definecolor{ipython_cyan}{RGB}{64, 128, 128}
\definecolor{ipython_purple}{RGB}{170, 34, 255}
\lstdefinelanguage{iPython}{
morekeywords={access,and,break,class,continue,def,del,elif,else,except,exec,finally,for,from,global,if,import,in,is,lambda,not,or,pass,print,raise,return,try,while},
morekeywords=[2]{abs,all,any,basestring,bin,bool,bytearray,callable,chr,classmethod,cmp,compile,complex,delattr,dict,dir,divmod,enumerate,eval,execfile,file,filter,float,format,frozenset,getattr,globals,hasattr,hash,help,hex,id,input,int,isinstance,issubclass,iter,len,list,locals,long,map,max,memoryview,min,next,object,oct,open,ord,pow,property,range,raw_input,reduce,reload,repr,reversed,round,set,setattr,slice,sorted,staticmethod,str,sum,super,tuple,type,unichr,unicode,vars,xrange,zip,apply,buffer,coerce,intern},
sensitive=true,
morecomment=[l]\#,
morestring=[b]',
morestring=[b]",
morecomment=[s]{"""}{"""},
morestring=[s]{'''}{'''},
morestring=[s]{r'}{'},
morestring=[s]{r"}{"},
morestring=[s]{r'''}{'''},
morestring=[s]{r"""}{"""},
morestring=[s]{u'}{'},
morestring=[s]{u"}{"},
morestring=[s]{u'''}{'''},
morestring=[s]{u"""}{"""},
literate=
*{+}{{{\color{ipython_purple}+}}}1
{-}{{{\color{ipython_purple}-}}}1
{*}{{{\color{ipython_purple}$^\ast$}}}1
{/}{{{\color{ipython_purple}/}}}1
{^}{{{\color{ipython_purple}\^{}}}}1
{?}{{{\color{ipython_purple}?}}}1
{!}{{{\color{ipython_purple}!}}}1
{\%}{{{\color{ipython_purple}\%}}}1
{<}{{{\color{ipython_purple}<}}}1
{>}{{{\color{ipython_purple}>}}}1
{|}{{{\color{ipython_purple}|}}}1
{\&}{{{\color{ipython_purple}\&}}}1
{~}{{{\color{ipython_purple}~}}}1
{==}{{{\color{ipython_purple}==}}}2
{<=}{{{\color{ipython_purple}<=}}}2
{>=}{{{\color{ipython_purple}>=}}}2
{+=}{{{+=}}}2
{-=}{{{-=}}}2
{*=}{{{$^\ast$=}}}2
{/=}{{{/=}}}2,
commentstyle=\color{ipython_cyan}\ttfamily,
stringstyle=\color{ipython_red}\ttfamily,
keepspaces=true,
showspaces=false,
showstringspaces=false,
rulecolor=\color{ipython_frame},
frame=single,
frameround={t}{t}{t}{t},
framexleftmargin=6mm,
numbers=left,
numberstyle=\tiny\color{halfgray},
backgroundcolor=\color{ipython_bg},
basicstyle=\scriptsize\ttfamily,
keywordstyle=\color{ipython_green}\ttfamily,
escapechar=,
escapebegin=\color{ipython_green},
}
\author{Anri Kennel}
\title{Programmation d'interfaces $\cdot$ Projet final}
\date{}
\begin{document}
\maketitle
\tableofcontents
\begin{center}
\emph{Les explications sont en commentaire du code.}
\end{center}
\clearpage
\section{Consigne}
\begin{todolist}
\item[\fait] Page de login \texttt{/1.5}
\begin{todolist}
\item[\fait] Nom d'utilisateur ne contient que des lettres et des chiffres
\item[\fait] Mot de passe de minimum 8 caractères dont 1 caractère spécial, une majuscule et une minuscule (possibilité d'afficher ou non en clair le mot de passe)
\item[\fait] Un bouton de connexion (possibilité aussi d'utiliser la touche Entrer pour aller plus vite) qui permet de se rendre sur l'interface Caissier ou Manager
\item[\fait] Un bouton pour quitter l'application
\end{todolist}
\item Page de manager (définit par un nom d'utilisateur et un mot de passe) \texttt{/7.5}
\begin{todolist}
\item Peut ajouter et supprimer un caissier
\item Peut voir la liste des caissiers
\item Un suivi des ventes
\item Un bouton pour vider tous les champs de saisie
\item Un bouton pour quitter l'application
\item Un bouton pour se mettre en "mode caissier"
\end{todolist}
\item Page de caissier (définit par un identifiant, un nom d'utilisateur, un mot de passe, un nom, un prenom, une date de naissance, une adresse et une code postal) \texttt{/6}
\begin{todolist}
\item Afficher le stock disponible
\begin{todolist}
\item 4 rayons de chacun au moins 10 articles de votre choix (fruits/légumes, boulangerie, boucherie/poissonnerie ou produits d'entretien)
\item Au clic sur le produit, l'identifiant, le nom, la quantité en stock et le prix s'affichent
\item Possibilité de rajouter des produits en stock
\end{todolist}
\item Affichage d'un ticket de caisse
\begin{todolist}
\item Date de vente
\item ID, nom, quantité, prix des produits achetés
\item Prix total
\item Un bouton pour valider
\end{todolist}
\item Interface d'export des statistiques (stock le montant total de vente par jour)
\end{todolist}
\end{todolist}
Avec à savoir :
\begin{todolist}
\item Ergonomie \texttt{/2}
\item[\fait] Utilisateurs stockés dans la base de donnée \texttt{/2}
\begin{todolist}
\item[\fait] Possibilité de recréer la base de donnée automatiquement si elle n'existe plus
\end{todolist}
\item Ajout d'autres fonctionnalités \texttt{/1}
\begin{todolist}
\item Heure de connexion stricte pour les caissiers
\item Meilleur caissier (avec le plus de ventes sur la journée/semaine précédente par exemple)
\item Exporter le ticket de caisse en format image
\end{todolist}
\item[\fait] Lisibilité du code
\begin{todolist}
\item[\fait] Toutes les fonctions sont nommés et typés \texttt{(j'utilises Python 3.9.7)}
\end{todolist}
\end{todolist}
\clearpage
\section{Code}
\subsection[\texttt{main.py}]{\texttt{main.py}, fichier principale}
\begin{lstinputlisting}[language=iPython]{../main.py}\end{lstinputlisting}
\subsection[\texttt{db.py}]{\texttt{db.py}, gère la communication avec la base de donnée en sa globalité}
\begin{lstinputlisting}[language=iPython]{../db.py}\end{lstinputlisting}
\subsection[\texttt{users.py}]{\texttt{users.py}, implante la partie pour les utilisateurs}
\begin{lstinputlisting}[language=iPython]{../users.py}\end{lstinputlisting}
\end{document}