Skip to content
Snippets Groups Projects
Commit fc5e68e9 authored by Derrode Stéphane's avatar Derrode Stéphane :dromedary_camel:
Browse files

Dépot du sujet #1 (4h)

parent 0bb7435b
Branches
No related tags found
No related merge requests found
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
Chers étudiants,
*A compléter*
\ No newline at end of file
ce _repo_ contient l'ensemble des sujets de BE pour l'enseignement `INF-TC2` de l'École centrale de Lyon. Pour voir le sujet, il vous suffit de cliquer sur le fichier markdown (extension _.md_) du répertoire correspondant à la séance.
Pour rappel (vu en cours), les BE #3 et #5 seront évalués par votre encadrant. Les consignes pour le rendu sont précisées dans les répertoires respectifs.
Les slides du cours sont disponibles à l'adresse https://pedagogie1.ec-lyon.fr/course/view.php?id=969. C'est également à cette adresse que vous déposerez vos rendus de BE noté.
Stéphane Derrode et Thibault Rafaillac
# <center>TD1 : Bibliothèque</center>
**Sommaire**
[[_TOC_]]
_Remarque introductive_ : Les sujets de BE sont rédigés dans le format _Markdown_.
# TD1 : Bibliothèque
> _Markdown est un langage de balisage léger créé en 2004 par John Gruber avec l'aide d'Aaron Swartz. Son but est d'offrir une syntaxe facile à lire et à écrire. Un document balisé par Markdown peut être lu en l'état sans donner l'impression d'avoir été balisé ou formaté par des instructions particulières. Il peut être converti en HTML, en PDF ou en d'autres formats._
Si cela vous intéresse, vous trouverez des informations et un tutoriel en suivant ce lien : [Wikipédia markdown](https://fr.wikipedia.org/wiki/Markdown). Noter que savoir utiliser le format Markdown n'est pas nécessaire pour cet enseignement mais pourrait être d'un intérêt certain durant votre scolarité. Ici, il permet de faciliter les copier-coller de code que vous rencontrerez dans les sujets ; les formats propriétaires Word ou Pdf introduisent des caractères spéciaux ou cachés qui brouillent l'interpréteur Python, et génèrent bien souvent des incompréhensions pour les programmeurs débutants.
Pour améliorer la lisibilité, nous avons fait appel à quelques commandes html complémentaires.
_Remarque introductive_ : Les sujets de BE sont rédigés dans le format _Markdown_. Si ce format vous intéresse, vous trouverez des pointeurs vers des logiciels open source et des tutoriels sur le site du cours, sur https://pedagogie1.ec-lyon.fr/course/view.php?id=969.
---
> _Markdown est un langage de balisage léger créé en 2004 par John Gruber avec l'aide d'Aaron Swartz. Son but est d'offrir une syntaxe facile à lire et à écrire. Un document balisé par Markdown peut être lu en l'état sans donner l'impression d'avoir été balisé ou formaté par des instructions particulières. Il peut être converti en HTML, en PDF ou en d'autres formats._
# Objectif du sujet
## Objectif du sujet
Dans cet énoncé, nous abordons deux concepts de base de la programmation orientée objet, __l'encapsulation__ et la __composition__, qui ont été abordées lors du premier cours. Nous nous exercerons également aux diagrammes de classe du langage graphique UML. Pour vos propres diagrammes, vous pouvez utiliser https://app.diagrams.net pour dessiner en ligne (et sauvegarder localement vos diagrammes sur votre machine).
......@@ -19,7 +17,7 @@ Dans ce BE, il s'agit de concevoir et de réaliser un programme _simple_ de gest
_Remarque_ : Cet énoncé part d'un problème simple et connu qui permet d'en faire la conception et la réalisation dans le temps qui nous est imparti par les contraintes scolaires. Les choix de conception et de réalisation sont donc orientés par ces contraintes et par les objectifs pédagogiques, à savoir : apprendre la programmation orientée objet en Python. Il est clair que le même problème dans un cadre professionnel serait traité d’une autre manière et une solution basée sur des bases de données émergerait naturellement, solution que nous écartons a priori car en dehors du périmètre de ce cours.
# Cahier des charges
## Cahier des charges
Le cahier des charges de notre application est décrit ci-dessous. Il est volontairement donné de manière informelle.
......@@ -59,7 +57,7 @@ _Remarque_ : Même si ce n'est pas pas obligatoire, il vous est demandé de dév
---
# Classe Lecteur et classe Livre (75 minutes)
## Classe Lecteur et classe Livre (75 minutes)
**Point 1. du cahier des charges**
......@@ -110,10 +108,8 @@ Un programme principal typique aura l'allure suivante:
print('B4 -->', B4)
```
---
# Classe Bibliothèque (75 minutes)
## Classe Bibliothèque (75 minutes)
**Points 3. et 5. du cahier des charges**
......@@ -133,7 +129,7 @@ Dessinez ensuite le détail de la boîte UML de la classe __Bibliothèque__, de
1. Faites de même avec les livres. On ne vérifiera pas si le livre déjà présent dans la collection avant de l'ajouter.
# Les emprunts (90 minutes)
## Les emprunts (90 minutes)
**Points 4. et 5. du cahier des charges**
......@@ -232,7 +228,7 @@ Un emprunt serra modélisé par un objet qui associe un lecteur (connu par son i
```
# Questions ouvertes supplémentaires
## Questions ouvertes supplémentaires
**Point 6. (facultatif) du cahier des charges**
......@@ -330,4 +326,4 @@ Un emprunt serra modélisé par un objet qui associe un lecteur (connu par son i
1. Un livre qui n'aurait plus d’exemplaire ne doit plus apparaître dans la liste des livres à disposition de la bibliothèque.
1. Comment implémenter un mécanisme de vérification de l'unicité de l'identifiant d'un lecteur et de celui d'un livre ?
1. Comment implémenter un mécanisme de vérification de l'unicité de l'identifiant d'un lecteur et de celui d'un livre ?
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="348px" height="181px" viewBox="-0.5 -0.5 348 181" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2020-09-02T07:51:36.488Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36&quot; etag=&quot;fuW20ZwMJLSmCLgNqiah&quot; version=&quot;13.6.6&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;QcHEdDH7hetbROZjSo9L&quot; name=&quot;Page-1&quot;&gt;7Vptb5swEP41+biJd8LHkDabJrWa1kprP1rBCdYMjsBpyH79TLAD2CGFDPKyVZEifDZn5567x75zRuY0yr4kYBU+kADikaEF2ci8GxmGO3bYdy7YFgLLtQrBMkFBIdJLwRP6DblQ49I1CmBaG0gJwRSt6sI5iWM4pzUZSBKyqQ9bEFyfdQWWUBE8zQFWpT9RQMNCOjbcUv4VomUoZtYdr+iJgBjMf0kagoBsKiLzfmROE0Jo8RRlU4hz2wm7FO/NGnr3C0tgTNu8ED4uXp2H1ewh3fjPmanRb9rsE9fyBvCa/2C+WLoVFoBxMMkNyVpzDNIUzUemH9IIM4HOHtV1cKUwqJmWr+oLJBGkyZYN2JQGtbmRwoothSyBGFD0VgcEcFyXe3X7Gb4TxFZiaNwFDY3r2QqItLqKlKyTOeRvVQ0oKbKNdxRRkCwhVRSxh8rPLkU7fDpgZfz7WJlO3cTeiVDJevbrOxNU5vtQJWQdBzBXojFgNiGi8GkF5nnvhjFpHbcFwnhKMElYOyYxG+SnNCG/oBCODPN+4viOs+8RbHUU9jeYUJgdBV5Y1JOcX1i44hjWAcdwtWYfqFm9q4mtTtHAjRaANNzZXL+xuGiyfufAkBWdmcPsD9R6oDNF0cCouQpqmQIb4xFah6fOUBzLA0wGMFrG+Y7FYIRM7ueshNgRbMI7IhQE+TQHWbLOowsS0xmIEM4t9YwidnQ0tEe4Yd8/SATifsjQbjpSvEOGxlBkOFYA2v7XAJmmtP9bFwZIOEjnw1vKQpsePdO1sKhyVvB3H9bD5uQ5lykmq7SvnWAtS4LZPJFgZUXnJlhdzcPC2w3gfMghZ+shsC0psPWxfeHAVrMy/IFciwTi8pTcIkm7PkqGGaIvHND8+bXyfJdVG1vRiJm1XvjKdo3Xak/50q4l3mpEvKDUFhFRUGaLgdeymdgNDtp5M5EU6XIOPPRm0iY1xhit0ibe6ObKTaTRpmjh267p3fXDMIZcnzvAMLp2wIHkzb4/iuk13RWhr1dCXz8a+qcHsTDllcTmvowkoJXreW1j03C8z3Zd1ZkrILrTp080InwlwKmVC+9E4GQPkBUNDZuaYt/AaeHa3UMNx/1tTQ+Rfe591/twkTNQf4lzZxeRDwiqqqGv8NQyUHLDpdQB00VDTvRt9TB31nTRUEs0yQ0XWYeETt7z3UtDp9ZoVGLeJ0RpCFZwR8RkHZx0NfsX5ldY3HEnvjcb6lbXki4yxi0zphNudVmz/K9LwaflH4bM+z8=&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><path d="M 7 30 L 320.63 30" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 325.88 30 L 318.88 33.5 L 320.63 30 L 318.88 26.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><path d="M 167 10 L 167 163.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 167 168.88 L 163.5 161.88 L 167 163.63 L 170.5 161.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"/><rect x="197" y="80" width="40" height="70" fill="none" stroke="#ea6b66" pointer-events="all"/><path d="M 197 80 L 197 30" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 197 80 L 167 80" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><rect x="307" y="30" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 40px; margin-left: 308px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Times New Roman; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">x</div></div></div></foreignObject><text x="327" y="44" fill="#000000" font-family="Times New Roman" font-size="12px" text-anchor="middle">x</text></switch></g><rect x="137" y="160" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 170px; margin-left: 138px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Times New Roman; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">y</div></div></div></foreignObject><text x="157" y="174" fill="#000000" font-family="Times New Roman" font-size="12px" text-anchor="middle">y</text></switch></g><path d="M 247 145.88 L 247 84.12" fill="none" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 247 148.88 L 245 144.88 L 247 145.88 L 249 144.88 Z" fill="#b3b3b3" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="all"/><path d="M 247 81.12 L 249 85.12 L 247 84.12 L 245 85.12 Z" fill="#b3b3b3" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="all"/><rect x="237" y="105" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 115px; margin-left: 238px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Times New Roman; color: #B3B3B3; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">h</div></div></div></foreignObject><text x="257" y="119" fill="#B3B3B3" font-family="Times New Roman" font-size="12px" text-anchor="middle">h</text></switch></g><rect x="197" y="160" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 170px; margin-left: 198px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Times New Roman; color: #B3B3B3; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">l</div></div></div></foreignObject><text x="217" y="174" fill="#B3B3B3" font-family="Times New Roman" font-size="12px" text-anchor="middle">l</text></switch></g><path d="M 201.12 160 L 232.88 160" fill="none" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 198.12 160 L 202.12 158 L 201.12 160 L 202.12 162 Z" fill="#b3b3b3" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="all"/><path d="M 235.88 160 L 231.88 162 L 232.88 160 L 231.88 158 Z" fill="#b3b3b3" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="all"/><ellipse cx="77" cy="90" rx="50" ry="30" fill="none" stroke="#b5739d" pointer-events="all"/><path d="M 77 90 L 76.5 30" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 167 89 L 77 89" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/><path d="M 76.5 115.88 L 76.5 94.12" fill="none" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 76.5 118.88 L 74.5 114.88 L 76.5 115.88 L 78.5 114.88 Z" fill="#b3b3b3" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="all"/><path d="M 76.5 91.12 L 78.5 95.12 L 76.5 94.12 L 74.5 95.12 Z" fill="#b3b3b3" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="all"/><path d="M 72.88 89.5 L 31.12 89.5" fill="none" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 75.88 89.5 L 71.88 91.5 L 72.88 89.5 L 71.88 87.5 Z" fill="#b3b3b3" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="all"/><path d="M 28.12 89.5 L 32.12 87.5 L 31.12 89.5 L 32.12 91.5 Z" fill="#b3b3b3" stroke="#b3b3b3" stroke-miterlimit="10" pointer-events="all"/><rect x="37" y="70" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 80px; margin-left: 38px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Times New Roman; color: #B3B3B3; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">rx</div></div></div></foreignObject><text x="57" y="84" fill="#B3B3B3" font-family="Times New Roman" font-size="12px" text-anchor="middle">rx</text></switch></g><rect x="67" y="90" width="40" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 38px; height: 1px; padding-top: 100px; margin-left: 68px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Times New Roman; color: #B3B3B3; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">ry</div></div></div></foreignObject><text x="87" y="104" fill="#B3B3B3" font-family="Times New Roman" font-size="12px" text-anchor="middle">ry</text></switch></g><path d="M 232 17.5 C 212 17.5 207 35 223 38.5 C 207 46.2 225 63 238 56 C 247 70 277 70 287 56 C 307 56 307 42 294.5 35 C 307 21 287 7 269.5 14 C 257 3.5 237 3.5 232 17.5 Z" fill="none" stroke="#67ab9f" stroke-miterlimit="10" pointer-events="all"/></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://desk.draw.io/support/solutions/articles/16000042487" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>
\ No newline at end of file
seance2_4h/figures/spyder-tests-dark.png

45.4 KiB

seance2_4h/figures/spyder-tests.png

40.3 KiB

seance2_4h/figures/spyder-unittest.png

4.52 KiB

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="701px" height="168px" viewBox="-0.5 -0.5 701 168" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2020-09-02T12:41:38.977Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36&quot; etag=&quot;ruTGXMro8CwttfHMEE6F&quot; version=&quot;13.6.6&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;ZFG0j7v5SNXi1jvCDSdx&quot; name=&quot;Page-1&quot;&gt;7Zptb9owEMc/TV5SkYQE9pKHPkkwdWVapb2Z3MRJrJoYOaZAP/0uiU0Ah422S9NJlhDE53Nyvt/Z5B+w3PFic83RMpmxEFPL6YYby51YjtMf+PCeG7alwXPc0hBzEpYmuzLMyQuWxq60rkiIswNHwRgVZHloDFia4kAc2BDnbH3oFjF6eNUlirFmmAeI6tYHEoqktA6cfmW/wSRO1JVt/0vZs0DKWc4kS1DI1nsm99Jyx5wxUR4tNmNM89ypvJTjrk707gLjOBXnDHBiPhOb7Y8vs5+j+c2v+2A4CzqeU57mGdGVnPE9pBGlMSSgDFtsVS6yNVlQlEJrFLFUzGWPDW1ESZzCcQDBYA6GZ8wFgTQOZYdgS7AGCaHhFG3ZKg85Eyh4Uq1Rwjh5gdMiKs8J3VzIinD8A495PhLMXbBynIHPncqDfWSaoc2B4xRlQhoCRilaZuRxN40F4jFJR0wItpBOiAcyBtvLg8KQcSQYHzPKYKKTlBUJUbm5IpQedynw+eliirJMHqsxU5KqALInLIJEBcxWaYhD2VpiThYYsjtfooCksTRHexe0HDeKIicIiuxx9oT3ekL/0ffyNOqFI2spZ4Y3eyZZSNeYwYX5FlzUspY1LRe1q9rraons6j7ZXx5+Ty5NuSzj3amryoUDWbyvKWRfK2TLGZURD+ED5kqgMI9LGuYrtGRJbpGOUpU5xZE4WeRZyWda+Ex6leVeJiI3MRgb0aIsEhKGOC14CyRQWY0FcUZSUSTKG8EL8jnuXniWB4GPoW1XbXjl7lyMWQpzQaQgi6HU1zgv9xrmf94O/l4JEr3jn0de+b0H/O232+kLXw8f7nvrYNgJEbv62rFPcN8a7k1yVyM+gnt9yK4GvgNNarA3ib0/aHm56/crOfXEUG+Sut3ttb3avZpt/ggzJeXtVoFZ3azbb2K8AFoUV1C/58wnHVsD7+rg3RrIFD1iescyIgjLz89L3yP47fF1z7x/GzS0qvW93Bo71rCrMTZL+d2oP3AHr4+5r8G+pBT0vBGcRnCeEpyu/ekUp39KeRjF+ZodrH92KXwWxXnqSYNRnI1yb19xDmq1B5frPWSrx5qHpob7O7m3Ljl16VFg3xrsTWJvX3P6XaM5G+TbtubUd3OjOZtC3bbm9PXHhpZ7ZfSm0Zsn9KbnvVVvuk3tV3bd15HRm6/cvXY7wf+jN23zE2cr4FsXnL7+WPzi4sKA/tegP1Jh1odsft1qEO/ZSrKxb+6au08jNZphbTe3aUOz+rdm0bf3l1f38jc=&lt;/diagram&gt;&lt;/mxfile&gt;"><defs><clipPath id="mx-clip-4-31-212-26-0"><rect x="4" y="31" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-57-212-26-0"><rect x="4" y="57" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-83-212-26-0"><rect x="4" y="83" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-109-212-26-0"><rect x="4" y="109" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-143-212-26-0"><rect x="4" y="143" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-31-212-26-0"><rect x="244" y="31" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-57-212-26-0"><rect x="244" y="57" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-83-212-26-0"><rect x="244" y="83" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-109-212-26-0"><rect x="244" y="109" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-143-212-26-0"><rect x="244" y="143" width="212" height="26"/></clipPath><clipPath id="mx-clip-484-31-212-26-0"><rect x="484" y="31" width="212" height="26"/></clipPath><clipPath id="mx-clip-484-57-212-26-0"><rect x="484" y="57" width="212" height="26"/></clipPath><clipPath id="mx-clip-484-83-212-26-0"><rect x="484" y="83" width="212" height="26"/></clipPath><clipPath id="mx-clip-484-117-212-26-0"><rect x="484" y="117" width="212" height="26"/></clipPath></defs><g><path d="M 0 26 L 0 0 L 220 0 L 220 26" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all"/><path d="M 0 26 L 0 164 L 220 164 L 220 26" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 0 26 L 220 26" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="109.5" y="17.5">Rectangle</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-31-212-26-0)" font-size="12px"><text x="5.5" y="43.5">+ x: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-57-212-26-0)" font-size="12px"><text x="5.5" y="69.5">+ y: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-83-212-26-0)" font-size="12px"><text x="5.5" y="95.5">- l: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-109-212-26-0)" font-size="12px"><text x="5.5" y="121.5">- h: entier</text></g><path d="M 0 134 L 220 134" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-143-212-26-0)" font-size="12px"/><path d="M 240 26 L 240 0 L 460 0 L 460 26" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 26 L 240 164 L 460 164 L 460 26" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 26 L 460 26" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="349.5" y="17.5">Ellipse</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-31-212-26-0)" font-size="12px"><text x="245.5" y="43.5">+ x: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-57-212-26-0)" font-size="12px"><text x="245.5" y="69.5">+ y: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-83-212-26-0)" font-size="12px"><text x="245.5" y="95.5">- rx: double</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-109-212-26-0)" font-size="12px"><text x="245.5" y="121.5">- ry: double</text></g><path d="M 240 134 L 460 134" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-143-212-26-0)" font-size="12px"/><path d="M 480 26 L 480 0 L 700 0 L 700 26" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 480 26 L 480 138 L 700 138 L 700 26" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 480 26 L 700 26" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="589.5" y="17.5">?</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-31-212-26-0)" font-size="12px"><text x="485.5" y="43.5">+ x: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-57-212-26-0)" font-size="12px"><text x="485.5" y="69.5">+ y: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-83-212-26-0)" font-size="12px"><text x="485.5" y="95.5">...</text></g><path d="M 480 108 L 700 108" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-117-212-26-0)" font-size="12px"/></g></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="701px" height="286px" viewBox="-0.5 -0.5 701 286" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2020-09-02T12:43:26.686Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36&quot; etag=&quot;WZoK8idbTfEnltmXA0ep&quot; version=&quot;13.6.6&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;ZFG0j7v5SNXi1jvCDSdx&quot; name=&quot;Page-1&quot;&gt;7Vtdb+I4FP01PFKRT+ARaJkZCVbdstqR5mVlEpNYNTFyTIH++r3BNiFxYJh2A+1sJNTGN7Zzfc/x9YkNLWe03H7haBVPWYhpy+6E25Zz37Ltbs+Hv5lhJw1u15WGiJNQmqzcMCOvWBk7yromIU4LFQVjVJBV0RiwJMGBKNgQ52xTrLZgtPjUFYqwYZgFiJrW7yQUsbT27G5u/4pJFOsnW35f3lkiXVmNJI1RyDZHJueh5Yw4Y0JeLbcjTLPY6bjIduMTdw+OcZyISxrYEZ+K7e7v/vTHcPb1n6dgMA3ani27eUF0rUb8BGFESQQBkG6LnY5FuiFLihIoDRcsETN1x4IyoiRK4DoAZzAHwwvmgkAYB+qGYCuwBjGh4QTt2DpzORUoeNalYcw4eYVuEVV9wm0uFCNsv1BjlrUEcwesHKdQ51HHwSqZpmhbqDhBqVCGgFGKVimZH4axRDwiyZAJwZaqEuKB8sHyMqcwRBwJxkeMMhjofcL2AdGxGRNKy7c08Fl3EUVpqq51mwlJtAPpMxZBrB1m6yTEoSqtMCdLDNGdrVBAkkiZF0cPbNnOYrGwg2AfPc6e8dGd0J/7XhZGkziKSxlmeHtkUkT6ghk8mO+gip7WitNqUju6vMmnyIH3cWF6KL4hNS2jQ9c5c+FCkfdXiOwYRG5DEfoYwD8YKQFalgkNoxVGqBRqCxNITXKKF+IkxVOJzmRf597NLU8qDJmJQdsF3ZMiJmGIkz3aAgkkubjHm5FE7MPkDeED0Rx17ryWB46PoGzlZfhk1bkYsQTGgsgeVwxE3+CM7BWIn08GP+eBAt72L8Nd13sP7N/+/DZ55ZvB9yd3EwzaIWLjP9pm+spQjxvU60Rdt7gG6tUuewbsBsqUyOS7R1kv3dabIF4CWBTnmP6VQX7ftgzcHRN3pwJjiuaYPrKUCMKy/rmsW8L+ZvB2e5fB26sLXd9Ed2S3Bh0D42YmvxPq3hXzd7XLXQPrB0pB3Dfqs1Gfp9SnY308+dmrFCJ8K5VIyNbziheqJn9VJ4PPoz9NIbKHfdfAXifsNxegfqcRoPXBe0UBWjmpG/15LaRvrj99cwOh5Ywb7dlozxPa0/PeqD17tVHY3Pm8u7trctX5XHWY+B9Sa1a73Ox61QjvpZqyLtFhVUjKRnXUArV/YcqubyabuwUGyjgJB9n5NZTmlGVr/jAWS60QcBhhrUIghDGLWILoQ24tLaHQm17LfVnMlmu9GheyhX1uoUzZmgf4nAZUIwEFE+FzsLkquNlIzoJ2hJJXAZK2cUyRIC+44G4VcuoJjxlRj/aUnNK63u8Uu5AjV63so2P2cke9UkduqSMZGaMjABvtjqqpiXTSYatfeo7XOeuXa5+tDxfSg5zVBwzeQfT+70v07uckut0p8aD3RqK75Rmjsf0J0f8rbnUrFszfhFt6Sfts3DIocW1u/WoS9ctvcx8xibrmftSY8WVzQtbsUpzapSifkB2S/u1OyFzzpLdlD6XLzZd1Ln3ZOeSCz7Nt4VWt00PpYAN8fcDf/JDMveAtt9mveiu8t/6WVtcy0f1/71cV5cBpVXEsIQwNVRtfajxqg2L+MwapevPfgjgP/wI=&lt;/diagram&gt;&lt;/mxfile&gt;"><defs><clipPath id="mx-clip-4-201-212-26-0"><rect x="4" y="201" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-227-212-26-0"><rect x="4" y="227" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-261-212-26-0"><rect x="4" y="261" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-201-212-26-0"><rect x="244" y="201" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-227-212-26-0"><rect x="244" y="227" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-261-212-26-0"><rect x="244" y="261" width="212" height="26"/></clipPath><clipPath id="mx-clip-484-201-212-26-0"><rect x="484" y="201" width="212" height="26"/></clipPath><clipPath id="mx-clip-484-235-212-26-0"><rect x="484" y="235" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-31-212-26-0"><rect x="244" y="31" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-57-212-26-0"><rect x="244" y="57" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-91-212-26-0"><rect x="244" y="91" width="212" height="26"/></clipPath></defs><g><path d="M 0 196 L 0 170 L 220 170 L 220 196" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all"/><path d="M 0 196 L 0 282 L 220 282 L 220 196" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 0 196 L 220 196" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="109.5" y="187.5">Rectangle</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-201-212-26-0)" font-size="12px"><text x="5.5" y="213.5">- l: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-227-212-26-0)" font-size="12px"><text x="5.5" y="239.5">- h: entier</text></g><path d="M 0 252 L 220 252" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-261-212-26-0)" font-size="12px"/><path d="M 240 196 L 240 170 L 460 170 L 460 196" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 196 L 240 282 L 460 282 L 460 196" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 196 L 460 196" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="349.5" y="187.5">Ellipse</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-201-212-26-0)" font-size="12px"><text x="245.5" y="213.5">- rx: double</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-227-212-26-0)" font-size="12px"><text x="245.5" y="239.5">- ry: double</text></g><path d="M 240 252 L 460 252" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-261-212-26-0)" font-size="12px"/><path d="M 480 196 L 480 170 L 700 170 L 700 196" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 480 196 L 480 256 L 700 256 L 700 196" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 480 196 L 700 196" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="589.5" y="187.5">?</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-201-212-26-0)" font-size="12px"><text x="485.5" y="213.5">...</text></g><path d="M 480 226 L 700 226" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-235-212-26-0)" font-size="12px"/><path d="M 120 170 L 120 150 L 350 150 L 350 132.24" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 350 114.24 L 359 132.24 L 341 132.24 Z" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 350 170 L 350 132.24" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 350 114.24 L 359 132.24 L 341 132.24 Z" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 580 170 L 580 150 L 350 150 L 350 132.24" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 350 114.24 L 359 132.24 L 341 132.24 Z" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 26 L 240 0 L 460 0 L 460 26" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 26 L 240 112 L 460 112 L 460 26" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 26 L 460 26" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="349.5" y="17.5">Forme</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-31-212-26-0)" font-size="12px"><text x="245.5" y="43.5">+ x: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-57-212-26-0)" font-size="12px"><text x="245.5" y="69.5">+ y: entier</text></g><path d="M 240 82 L 460 82" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-91-212-26-0)" font-size="12px"/></g></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="701px" height="482px" viewBox="-0.5 -0.5 701 482" content="&lt;mxfile host=&quot;app.diagrams.net&quot; modified=&quot;2020-09-02T12:43:54.091Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36&quot; etag=&quot;lFbpCapjlEMSZ9oZFN9N&quot; version=&quot;13.6.6&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;ZFG0j7v5SNXi1jvCDSdx&quot; name=&quot;Page-1&quot;&gt;7Vxdb6M4FP01kboPrQKEfDwmaTszq3Y124x21HmpHHDAGgdHxpkk/fV7ATsfGFLahaSdtVR14osx9j3H1/eeMG054/n6E0eL8J75mLbstr9uOdct2+71u/A7MWwyQ6fXyQwBJ35msnaGCXnG0tiW1iXxcXzQUTBGBVkcGj0WRdgTBzbEOVsddpsxevjUBQqwZph4iOrW78QXYWbt272d/TMmQaiebHUH2ZU5Up3lSuIQ+Wy1Z3JuWs6YMyayT/P1GNPEd8ov2X23JVe3E+M4ElVusAN+L9abfwb3P0aTz08P3vDeu3TtbJhfiC7lih/AjSgKwAHZtMVG+SJekTlFEbRGMxaJibxiQRtREkTw2YPJYA6GX5gLAm4cyguCLcDqhYT6d2jDlsmUY4G8n6o1ChknzzAsonJMuMyFZITdPegxSe4EcxusHMfQ56vyg5Uz3aP1Qcc7FAtp8BilaBGT6XYZc8QDEo2YEGwuOyHuyTlYbjIpDB5HgvExowwWeh2x1CHKN7eE0vwlBXwyXEBRHMvP6p47EqkJxD+x8EI1YbaMfOzL1gJzMsfg3ckCeSQKpHm298CW7cxmM9vzUu9x9hPvXfG7066buFEnjuRSghle75kkkT5hBg/mG+iitrXktNzUjmqvdltky/twb3vYPRkOkNyWwXboHXPhgyTva4jsaES+hCaMMYR/YKUEaJknNKxWaK6SqM10IBXJKZ6JUorHGTp3aZ/rzs7yIN2QmBjcO6MpKULi+zhK0RZIoIyLKd6MRCJ1kzuCH/DmuH3ltlyY+Bja1q4NP0l3LsYsgrUgkuKKgegrnJC9APHjweBlHkjg7W5F3GuA/cvfX+6e+Wr4/aGz8oaXPmK3f13q4StBPTSoN4m6uuMUqBdP2dVg11CmJAu+Kcrq6LbeBPEcwKJ4h+m3BPLrS0vD3dFxdwowpmiK6VcWE0FYMj7P+uawPxu8vX41ePtNodstQHeU5XjgiaUn8JJfrA/3+Dibf84EIzlW6nK990GQ+MNEibpp1K94Njidhs4Gq4RGaDYjXogvDOa1Y27ZVRPBOo6Gif8jfJz2rec/h5vHx/V18GNYCnqAxZNP5gB6uutfigeGGrVTo3PCXLGQGnqumFEjltQwZ8TpSdE7YSpZeEjoZeM21wDMI/GUuvHFbCMLK9t0Y8oYbY2d1nAA0BjW1M2aQcUM1bEbYk2nhDUcQyDBUQx5/RMsPCNPfLFul2emG/1ae20V0M0ysahZLcOpmLt0Gitrexqtbigli9hIsUaKLZNiHfVNyeu12MYK+L7G40SV4/IQ9dlyWvDtgglgxcHg44ixuiqXwr4xsDcJ+9nV2G67IBsyamxN8J5QjS3c1A2IsfmDYKxFCZPe1s6jU8qxxWHC6LEnB/38emyZvpLTY18OCYYctZPj7IpsmYyiFFlzUJyDFmfXZPXy0Wiy7541lTXZpr7uHZSwxmiyH5dVWwX/bJps19Zp5dxqSBs91uix2VXXfaMeaw0a47CehF9dXZlodTxabXf+uxRgi6ds3otsEN6qQmtTSpz6oue4FAc72yQitWPfPaGOUgy+Uc9ODnpVybQ50AuST1MJv3PWWAq1Fyvhxg6KMtHVlMIfmFZuxSOouVK4SJfLwYwjf5j8r1toTSlLCtFRKOaqbMV+gFVpDD4MWcAiRG921lxdB6OpArObNZMaUl48zGDtY9VbzJbcw0eWplI7KKsDfAw35dxkJUdR20PJLQBJ2TimSJBf+GC6RcjJJ3xNmLorNh0nV2wO2odDZCuXd+3w1wfq5wbq5AbKPKMNBGCjzV43uZNKJ2wNcs9x20fn1bGP9ocP2Qx2rN5i8B+IXiQl/iZE731MotvtHA/6byR6J79jFLYvEL0ubik16DfkljrTPhq3NEqcmluvDaLdvMT4HoNoR39x6JbxuXmV2UjnZdJ5/lVmq7J0XkcpVcxi/ZX8rJTKldym2qkS8D+QlO4WndOjvLBigK8b+LO/zdypUOWa71DeCu+5/7ZEr0xGf9XrzP9feesweSjPQfYTDi3jaoxdpxTsi6dc9hKSjxcUeXgOK77wC+jlG341G3gqq/Jv4AY0d3/GL6ufdn8L0bn5Fw==&lt;/diagram&gt;&lt;/mxfile&gt;"><defs><clipPath id="mx-clip-4-231-212-26-0"><rect x="4" y="231" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-257-212-26-0"><rect x="4" y="257" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-291-212-34-0"><rect x="4" y="291" width="212" height="34"/></clipPath><clipPath id="mx-clip-4-325-212-26-0"><rect x="4" y="325" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-351-212-26-0"><rect x="4" y="351" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-377-212-26-0"><rect x="4" y="377" width="212" height="26"/></clipPath><clipPath id="mx-clip-4-403-212-32-0"><rect x="4" y="403" width="212" height="32"/></clipPath><clipPath id="mx-clip-4-435-212-46-0"><rect x="4" y="435" width="212" height="46"/></clipPath><clipPath id="mx-clip-244-231-212-26-0"><rect x="244" y="231" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-257-212-26-0"><rect x="244" y="257" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-291-212-34-0"><rect x="244" y="291" width="212" height="34"/></clipPath><clipPath id="mx-clip-244-325-212-26-0"><rect x="244" y="325" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-351-212-26-0"><rect x="244" y="351" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-377-212-26-0"><rect x="244" y="377" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-403-212-34-0"><rect x="244" y="403" width="212" height="34"/></clipPath><clipPath id="mx-clip-244-437-212-46-0"><rect x="244" y="437" width="212" height="46"/></clipPath><clipPath id="mx-clip-484-231-212-26-0"><rect x="484" y="231" width="212" height="26"/></clipPath><clipPath id="mx-clip-484-265-212-26-0"><rect x="484" y="265" width="212" height="26"/></clipPath><clipPath id="mx-clip-484-291-212-26-0"><rect x="484" y="291" width="212" height="26"/></clipPath><clipPath id="mx-clip-484-317-212-38-0"><rect x="484" y="317" width="212" height="38"/></clipPath><clipPath id="mx-clip-484-355-212-46-0"><rect x="484" y="355" width="212" height="46"/></clipPath><clipPath id="mx-clip-244-31-212-26-0"><rect x="244" y="31" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-57-212-26-0"><rect x="244" y="57" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-91-212-26-0"><rect x="244" y="91" width="212" height="26"/></clipPath><clipPath id="mx-clip-244-117-212-26-0"><rect x="244" y="117" width="212" height="26"/></clipPath></defs><g><path d="M 0 226 L 0 200 L 220 200 L 220 226" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all"/><path d="M 0 226 L 0 476 L 220 476 L 220 226" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 0 226 L 220 226" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="109.5" y="217.5">Rectangle</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-231-212-26-0)" font-size="12px"><text x="5.5" y="243.5">- l: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-257-212-26-0)" font-size="12px"><text x="5.5" y="269.5">- h: entier</text></g><path d="M 0 282 L 220 282" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-291-212-34-0)" font-size="12px"><text x="5.5" y="303.5">+ constructeur(x: entier, y: entier,</text><text x="5.5" y="317.5">l: entier, h: entier)</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-325-212-26-0)" font-size="12px"><text x="5.5" y="337.5">+ affiche()</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-351-212-26-0)" font-size="12px"><text x="5.5" y="363.5">+ get_dim(): l: entier, h: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-377-212-26-0)" font-size="12px"><text x="5.5" y="389.5">+ set_dim(l: entier, h: entier)</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-403-212-32-0)" font-size="12px"><text x="5.5" y="415.5">+ contient_point(x: entier, y: entier):</text><text x="5.5" y="429.5">booléen</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-4-435-212-46-0)" font-size="12px"><text x="5.5" y="447.5">+ redimension_par_points(x0: entier,</text><text x="5.5" y="461.5">y0: entier, x1: entier, y1: entier)</text></g><path d="M 240 226 L 240 200 L 460 200 L 460 226" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 226 L 240 478 L 460 478 L 460 226" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 226 L 460 226" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="349.5" y="217.5">Ellipse</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-231-212-26-0)" font-size="12px"><text x="245.5" y="243.5">- rx: double</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-257-212-26-0)" font-size="12px"><text x="245.5" y="269.5">- ry: double</text></g><path d="M 240 282 L 460 282" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-291-212-34-0)" font-size="12px"><text x="245.5" y="303.5">+ constructeur(x: entier, y: entier,</text><text x="245.5" y="317.5">rx: double, ry: double)</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-325-212-26-0)" font-size="12px"><text x="245.5" y="337.5">+ affiche()</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-351-212-26-0)" font-size="12px"><text x="245.5" y="363.5">+ get_dim(): rx: double, ry: double</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-377-212-26-0)" font-size="12px"><text x="245.5" y="389.5">+ set_dim(rx: double, ry: double)</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-403-212-34-0)" font-size="12px"><text x="245.5" y="415.5">+ contient_point(x: entier, y: entier):</text><text x="245.5" y="429.5">booléen</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-437-212-46-0)" font-size="12px"><text x="245.5" y="449.5">+ redimension_par_points(x0: entier,</text><text x="245.5" y="463.5">y0: entier, x1: entier, y1: entier)</text></g><path d="M 480 226 L 480 200 L 700 200 L 700 226" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 480 226 L 480 396 L 700 396 L 700 226" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 480 226 L 700 226" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="589.5" y="217.5">?</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-231-212-26-0)" font-size="12px"><text x="485.5" y="243.5">...</text></g><path d="M 480 256 L 700 256" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-265-212-26-0)" font-size="12px"><text x="485.5" y="277.5">+ constructeur(...)</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-291-212-26-0)" font-size="12px"><text x="485.5" y="303.5">+ affiche()</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-317-212-38-0)" font-size="12px"><text x="485.5" y="329.5">+ contient_point(x: entier, y: entier):</text><text x="485.5" y="343.5">booléen</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-484-355-212-46-0)" font-size="12px"><text x="485.5" y="367.5">+ redimension_par_points(x0: entier,</text><text x="485.5" y="381.5">y0: entier, x1: entier, y1: entier)</text></g><path d="M 120 200 L 120 180 L 350 180 L 350 158.24" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 350 140.24 L 359 158.24 L 341 158.24 Z" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 350 200 L 350 158.24" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 350 140.24 L 359 158.24 L 341 158.24 Z" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 580 200 L 580 180 L 350 180 L 350 158.24" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 350 140.24 L 359 158.24 L 341 158.24 Z" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 26 L 240 0 L 460 0 L 460 26" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 26 L 240 138 L 460 138 L 460 26" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><path d="M 240 26 L 460 26" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" font-weight="bold" pointer-events="none" text-anchor="middle" font-size="12px"><text x="349.5" y="17.5">Forme</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-31-212-26-0)" font-size="12px"><text x="245.5" y="43.5">+ x: entier</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-57-212-26-0)" font-size="12px"><text x="245.5" y="69.5">+ y: entier</text></g><path d="M 240 82 L 460 82" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="none"/><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-91-212-26-0)" font-size="12px"><text x="245.5" y="103.5">+ constructeur(x: entier, y: entier)</text></g><g fill="#000000" font-family="Helvetica" pointer-events="none" clip-path="url(#mx-clip-244-117-212-26-0)" font-size="12px"><text x="245.5" y="129.5">+ deplacement(dx: entier, dy: entier)</text></g></g></svg>
\ No newline at end of file
# <center>TD2 : Modélisation de formes géométriques</center>
Nous allons aborder dans ce TD le concept d'héritage de la programmation objet, et l'utilisation de tests unitaires pour guider le développement logiciel et améliorer sa qualité.
Le but de ce TD est de concevoir un module pour manipuler des formes géométriques avec Python. Ce module sera utilisé dans les TDs suivants, donc les tests seront essentiels pour limiter les éventuels bugs. Vous commencerez par définir les classes et leurs attributs, puis écrirez les tests unitaires de votre module, et terminerez par l'implémentation des méthodes.
# Modélisation avec UML (1h)
Les formes géométriques sont représentées par des classes, et l'héritage sera utilisé pour factoriser les propriétés communes. Nous nous limitons à un repère à deux dimensions orthonormé, avec les axes croissant vers la droite et le bas. Les coordonnées dans ce repère sont des entiers relatifs (c'est-à-dire possiblement négatifs). Dans cet espace, nous choisissons de représenter les formes suivantes :
* Les rectangles caractérisés par leur origine (`x`, `y`) et leurs dimensions (`l`, `h`).
* Les ellipses caractérisées par leur origine (`x`, `y`) et leurs rayons aux axes (`rx`, `ry`).
* Un type de forme de votre choix (ex. triangle, polygone, étoile, ...), qui possède au moins une origine (`x`, `y`).
<center><img src="figures/formes.svg" style="width:50%"/></center>
__Exercice 1 -__ Représentez les 3 classes dans un diagramme de classes UML (_voir https://app.diagrams.net pour dessiner en ligne, avec l'onglet UML sur la gauche_). Il est recommandé de commencer les noms des classes par une majuscule et les attributs par une minuscule. Les attributs devraient-ils être publics ou privés ?
Les attributs `x` et `y` étant partagés par les trois classes, on introduit l'héritage pour les regrouper. Toutes les formes géométriques hériteront d'une même classe __Forme__. L'intérêt de cette classe est double :
* Du point de vue des développeurs du module, les méthodes dont le code est identique entre formes (ex. translation) sont fusionnées dans __Forme__, réduisant la quantité de code à (et donc la multiplication des erreurs possibles).
* Du point de vue des utilisateurs du module, on peut écrire du code qui manipule des rectangles et des ellipses (ex. système de collisions de formes) sans avoir à écrire du code séparément pour les rectangles et les ellipses. Cet aspect sera illustré dans un prochain TD.
__Exercice 2 -__ Mettez à jour le diagramme UML en incluant la classe __Forme__ et les relations d'héritage. Seuls les attributs seront inclus pour le moment.
Enfin, on vous demande de supporter a minima pour chaque forme les méthodes suivantes :
* `deplacement(dx, dy)`, qui effectue une translation selon un vecteur donné.
* `contient_point(x, y)`, qui renvoie `True` si et seulement si le point donné est à l'intérieur de la forme ou sur sa frontière.
* `redimension_par_points(x0, y0, x1, y1)`, qui redimensionne la forme pour faire correspondre sa [boîte englobante](https://en.wikipedia.org/wiki/Minimum_bounding_rectangle) avec celle représentée par les points donnés.
__Exercice 3 -__ Complétez le diagramme UML avec ces méthodes. Les constructeurs devront également être renseignés (méthode `__init__` en Python), ainsi que les méthodes d'affichage (méthode `__str__` en Python).
__Exercice 4 -__ Écrivez un squelette de code correspondant à votre diagramme UML, dans un fichier _formes.py_. Seuls les constructeurs devront être implémentés. À l'intérieur des autres méthodes, vous mettrez l'instruction `pass` de Python (qui ne fait rien mais vous rappelle que le code est inachevé).
# Tests unitaires (1h)
Il convient à présent de rédiger des tests, qui échoueront tant que chaque fonction ne sera pas implémentée et correcte. Dans la méthodologie _Test Driven Development_, on les écrit toujours avant le code, au début ils échouent tous, et à mesure de l'avancement du projet le nombre de tests passés augmente. Nous utiliserons le module _pytest_ présenté en cours.
## Installation de _pytest_
Nous allons d'abord installer _pytest_, ainsi qu'un module permettant de lancer les tests depuis l'interface de Spyder. Ouvrez le terminal d'Anaconda (sous Windows, Menu Démarrer -> Anaconda -> Anaconda Prompt, sous Linux/Mac le terminal de base suffit). Exécutez-y la commande suivante :
```sh
conda install -c spyder-ide spyder-unittest pytest
```
❗ Si vous rencontrez une erreur comme `conda: command not found`, c'est que l'exécutable `conda` n'est présent dans aucun des dossiers visités par le terminal (essayez `echo %PATH%` pour en afficher la liste sous Windows, et `echo $PATH` sous Linux/Mac). Sous Windows, vérifiez que vous ouvrez bien le terminal d'Anaconda (pas le terminal par défaut du système). Sous Linux/Mac, la commande `export PATH=~/anaconda3/bin:/usr/local/anaconda3/bin:/usr/anaconda3/bin:$PATH` va ajouter (temporairement) une liste de répertoires usuels à la liste de recherche.
Une fois les modules installés, __redémarrez Spyder__ et créez un fichier _test_formes.py_ avec l'exemple de code suivant :
```python
from formes import *
def test_heritage():
assert issubclass(Rectangle, Forme)
assert issubclass(Ellipse, Forme)
```
__Exécutez ce fichier__ dans Spyder (même s'il ne fait rien), ce qui a pour effet d'initialiser le répertoire courant de Spyder à votre répertoire de travail. Allez ensuite dans le menu Run -> Run unit tests, pour configurer le module _spyder-unittest_.
<center>![](figures/spyder-unittest.png)</center>
Sélectionnez _pytest_, vérifiez que le dossier indiqué correspond à votre dossier de travail (celui contenant les fichiers _formes.py_ et _test_formes.py_), et validez. Un nouvel onglet _Unit testing_ apparaît dans l'espace en haut à droite, avec un bouton _Run tests_. Lorsque vous cliquez dessus :
* _pytest_ cherche (dans le dossier que vous venez de configurer) tous les fichiers de la forme _test\_\*.py_ et _\*\_test.py_.
* Dans chacun de ces fichiers, _pytest_ exécute toutes les fonctions préfixées par `test`.
* Chaque test qui s'exécute sans déclencher d'exception est considéré valide.
* La fonction `test_heritage` dans le fichier _test_formes.py_ correspond à ces critères, donc elle est exécutée et son résultat contribue à un test "passé".
<center>![](figures/spyder-tests.png)</center>
## Définition des tests
__Exercice 5 -__ Dans le fichier _test_formes.py_, ajoutez une fonction `test_Rectangle_contient_point()` qui instancie un __Rectangle__ avec des coordonnées de votre choix, et vérifie avec `assert` que la méthode `contient_point` renvoie le bon résultat pour différentes coordonnées. L'exécution des tests doit échouer puisque votre code est encore vide.
Pour l'exercice suivant on vous donne un exemple d'implémentation de la méthode `contient_point` pour la classe __Rectangle__. La classe __Forme__ a été omise pour réduire la taille du code (mais dans votre code elle devra bien être présente).
```python
class Rectangle:
def __init__(self, x, y, l, h):
self.x = x
self.y = y
self.__l = l
self.__h = h
def contient_point(self, x, y):
return self.x < x < self.__l or \
self.y < y < self.__h
```
__Exercice 6 -__ Cette méthode est buggée. Comment la corriger ? Vos tests l'avaient-ils repéré ? Si ce n'est pas le cas, trouvez les coordonnées qui donnent un mauvais résultat et ajoutez-les en tests dans la fonction `test_Rectangle_contient_point`.
# Implémentation des méthodes (2h)
__Exercice 7 -__ Implémentez les méthodes d'affichage (`__str__`) de chacune des classes. Il ne sera pas nécessaire d'écrire des tests pour ces méthodes.
__Exercice 8 -__ Implémentez les méthodes d'accès getter/setter pour les champs privés de chacune des classes. À l'aide de [pytest.raises](https://docs.pytest.org/en/stable/assert.html#assertions-about-expected-exceptions), vous testerez le déclenchement d'erreurs si on essaie d'accéder directement aux attributs.
__Exercice 9 -__ Implémentez les méthodes `contient_point` des deux sous-classes restantes. Vous fournirez pour chacune une fonction de tests avec des jeux de coordonnées pertinents.
__Exercice 10 -__ Implémentez les méthodes `redimension_par_points` de chacune des sous-classes. Vous fournirez également des tests validant leur fonctionnement quels que soient les points en entrée.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment