Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • master
  • vS5_2020-2021
2 results

Target

Select target project
No results found
Select Git revision
  • master
  • vS5_2020-2021
2 results
Show changes

Commits on Source 22

29 files
+ 423
352
Compare changes
  • Side-by-side
  • Inline

Files

panorama/Liste.md

deleted100644 → 0
+0 −88
Original line number Diff line number Diff line
**Sommaire**

[[TOC]]

# Informatique à l'ECL

*Remarque* Les liens vers les espaces Moodle sont ceux de 2020-2021. Ces pages sont parfois vides car l'enseignement n'a pas encore démarré cette année! Si c'est le cas, allez voir le site de l'année précédente (2019-2020).


## Enseignement de l'Informatique en 2A

### S7 - UE Approfondissement (App)

- [App 1-FH](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1105) - Multimédia : Concepts et technologies, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)    
- [App 2-FH](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1106) - Stratégies de résolution de problèmes, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr)    
- [App 3-EG](https://pedagogie2.ec-lyon.fr/course/view.php?id=1107) - Applications concurrentes, mobiles et réparties en Java, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr), [S. Derrode](mailto:stephane.derrode@ec-lyon.fr)    
- [App 4-EG](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1108) - Analyse de données et reconnaissance des formes, [L. Chen](liming.chen@ec-lyon.fr), [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)    

*Détails des enseignements:* [ici](https://www.ec-lyon.fr/sites/default/files/legacy-files/programme_du_tronc_commun_2020-2021_new.pdf)

### S8 - UE Électifs (ELC)

 - [ELC A11](https://pedagogie2.ec-lyon.fr/course/view.php?id=1137) - Programmation des interfaces graphiques en C++, [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr), [S. Derrode](mailto:stephane.derrode@ec-lyon.fr)    
 - [ELC B2](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1140) - Algorithme collaboratifs et applications, [P. Michel](philippe.michel@ec-lyon.fr), [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr)    
 - [ELC C4](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1152) - Capteurs et traitement d'images, [L. Chen](liming.chen@ec-lyon.fr)       
 - [ELC D3](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1160) - Applications Web, [D. Muller](mailto:daniel.muller@ec-lyon.fr), [R. Chalon](rene.chalon@ec-lyon.fr)    
 - [ELC E1](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1170) - Algorithme et raisonnement, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr), [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)     

*Détails des enseignements:* [ici](https://www.ec-lyon.fr/sites/default/files/programme_parcours_electif_s8_2019-20_23.10.19_new.pdf)

## Césure 2A / 3A - Centrale Digital Lab

Une année de césure professionnalisante et en immersion dans le numérique

 - 3 semaines de cours en *IA*, *Machine Learning*, *Big Data*, *Web*, *Data visualisation*    
 - 3 POC (*Proof-Of-Concept*) de 7 semaines, animés par des entreprises et en mode agile (formateurs CGI / Sopra)    
 - 1 stage en entreprise de 5 mois (à l'étranger)   

Plus d'information?

 - Teaser video : [youtube - Centrale Digital Lab](https://www.youtube.com/watch?v=dK0R9EFA4I8)    
 - Responsable du programme [Stéphane Derrode](mailto:stephane.derrode@ec-lyon.fr)  
 - Plus d'information auprès de [Fatima Chouikhi](mailto:fatima.chouikhi@ec-lyon.fr)    
 - Site de l'ECL : [Centrale Digital Lab](https://www.ec-lyon.fr/formation/ingenieur-generaliste/construire-son-projet-professionnel/lyon-centrale-digital-lab)


## Enseignement de l'Informatique en 3A

### S9 – Modules Ouverts Disciplinaires (MOD)

 - [MOD 2.1](https://pedagogie3.ec-lyon.fr/course/view.php?id=1210) - Défis informatique du Big Data, [S. Derrode](mailto:stephane.derrode@ec-lyon.fr)    
 - [MOD 3.2](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1203) - Apprentissage profond & Intelligence Artificielle, [L. Chen](liming.chen@ec-lyon.fr), A. Bosio, [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)    
 - [MOD 4.4](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1241) - Recherche opérationnelle, [M. Zine](abdel-malek.zine@ec-lyon.fr), N. Bousquet, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr)    
 - [MOD 4.6](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1249) - Systèmes de bases de données, [L. Chen](liming.chen@ec-lyon.fr)    
 - [MOD 5.3](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1252) - Traitement et analyse des données visuelles et sonores, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)    
 - [MOD 7.1](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1250) - Systèmes d'information en entreprise, [R. Vuillemot](mailto:romain.vuillemot@ec-lyon.fr)    
 - [MOD 7.2](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1218) - Introduction à la data science, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr)    
 - [MOD 8.4](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1243) - Représentation et manipulation de données structurées, [D. Muller](mailto:daniel.muller@ec-lyon.fr)   
 - [MOD 9.5](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1244) - Réseaux informatiques, [R. Chalon](rene.chalon@ec-lyon.fr)


*Détails des enseignements:* [ici](https://www.ec-lyon.fr/sites/default/files/legacy-files/programme_parcours_electif_s9_-_ue_mod_30.04.20_new.pdf)


### S9 – Modules Ouverts Sectoriels (MOS)

 - [MOS 4.3](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1423) - Informatique d'entreprise, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), [D. Muller](mailto:daniel.muller@ec-lyon.fr)    
 - [MOS 2.2](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1424) - Informatique graphique, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), N. Bonneel    
 - [MOS 4.4](https://pedagogie3.ec-lyon.fr/course/view.php?id=1430) - Nouvelles technologies de l'information et de la com., [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), [D. Muller](mailto:daniel.muller@ec-lyon.fr)   
 - [MOS 5.5](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1440) - Visualisation interactive de données,  [R. Vuillemot](mailto:romain.vuillemot@ec-lyon.fr)   

*Détails des enseignements:* [ici](https://www.ec-lyon.fr/sites/default/files/parcours_electif_s9_-_ue_secteurs_27.02.20_new.pdf)

Technologies informatiques du Big Data

### S9 – Modules Spécifiques Option (MSO)

 - [MSO 3.1](https://pedagogie3.ec-lyon.fr/course/view.php?id=1369) - Technologies informatiques du Big Data, [S. Derrode](mailto:stephane.derrode@ec-lyon.fr)   
 - [MSO 3.2](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1370) - Les systèmes d'information par la pratique, [R. Vuillemot](mailto:romain.vuillemot@ec-lyon.fr)   
 - [MSO 3.3](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1371) - Internet des objets, [R. Chalon](rene.chalon@ec-lyon.fr), [D. Muller](mailto:daniel.muller@ec-lyon.fr)   
 - [MSO 3.4](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1372) - Apprentissage automatique, [L. Chen](liming.chen@ec-lyon.fr), [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)   
 - [MSO 3.5](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1373) - Vision par ordinateur, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), [L. Chen](liming.chen@ec-lyon.fr)    
 - [MSO 3.6](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1374) - Calcul et modélisation géométrique pour  l'info. graphique, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr)   
 - [MSO 3.7](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1375) - Système temps réel, embarqué et mobile, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr)    
 - [MSO 3.8](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1376) - Projet Informatique, toute l'équipe pédagogique   


*Détails des enseignements:* [ici](https://www.ec-lyon.fr/sites/default/files/parcours_electif_s9_-_ue_secteurs_27.02.20_new.pdf)
+86 −0
Original line number Diff line number Diff line
**Sommaire**

[[TOC]]

# Informatique à l'ECL

*Remarque* Les liens vers les espaces Moodle sont ceux de 2020-2021. Je vous laisse rechercher les liens de ces mêmes cours pour l'année en cours !

---
## Enseignement de l'Informatique en 2A

### S7 - UE Approfondissement (App)

- [App 1-FH](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1105) - Multimédia : Concepts et technologies, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)    
- [App 2-FH](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1106) - Stratégies de résolution de problèmes, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr)    
- [App 3-EG](https://pedagogie2.ec-lyon.fr/course/view.php?id=1107) - Applications concurrentes, mobiles et réparties en Java, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr), [S. Derrode](mailto:stephane.derrode@ec-lyon.fr)    
- [App 4-EG](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1108) - Analyse de données et reconnaissance des formes, [L. Chen](liming.chen@ec-lyon.fr), [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)    

[*Détails des enseignements*](https://www.ec-lyon.fr/formation/ingenieure-generaliste/programme-formation/tronc-commun/offre-formation-tronc-commun?module=654102)

### S8 - UE Électifs (ELC)

- [ELC A11](https://pedagogie2.ec-lyon.fr/course/view.php?id=1137) - Programmation des interfaces graphiques en C++, [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr), [S. Derrode](mailto:stephane.derrode@ec-lyon.fr)    
- [ELC B2](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1140) - Algorithme collaboratifs et applications, [P. Michel](philippe.michel@ec-lyon.fr), [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr)    
- [ELC C4](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1152) - Capteurs et traitement d'images, [L. Chen](liming.chen@ec-lyon.fr)       
- [ELC D3](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1160) - Applications Web, [D. Muller](mailto:daniel.muller@ec-lyon.fr), [R. Chalon](rene.chalon@ec-lyon.fr)    
- [ELC E1](https://pedagogie2.ec-lyon.fr/enrol/index.php?id=1170) - Algorithme et raisonnement, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr), [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)     

[*Détails des enseignements*](https://www.ec-lyon.fr/formation/ingenieure-generaliste/programme-formation/parcours-electif/offre-formation-parcours?module=654204)

---
## Césure 2A / 3A - Centrale Digital Lab

Une année de césure professionnalisante et en immersion dans le numérique

 - 3 semaines de cours en *IA*, *Machine Learning*, *Big Data*, *Web*, *Data visualisation*    
 - 3 POC (*Proof-Of-Concept*) de 7 semaines, animés par des entreprises et en mode agile (formateurs CGI / Sopra)    
 - 1 stage en entreprise de 5 mois (à l'étranger)   

Plus d'information?

 - Teaser video : [youtube - Centrale Digital Lab](https://www.youtube.com/watch?v=dK0R9EFA4I8)    
 - Responsable du programme [René Chalon](mailto:rene.chalon@ec-lyon.fr)  
 - Plus d'information auprès de [Fatima Chouikhi](mailto:fatima.chouikhi@ec-lyon.fr)    
 - Site de l'ECL : [Centrale Digital Lab](https://www.ec-lyon.fr/formation/ingenieur-generaliste/construire-son-projet-professionnel/lyon-centrale-digital-lab)

---
## Enseignement de l'Informatique en 3A

### S9 – Modules Ouverts Disciplinaires (MOD)

- [MOD 2.1](https://pedagogie3.ec-lyon.fr/course/view.php?id=1210) - Défis informatique du Big Data, [S. Derrode](mailto:stephane.derrode@ec-lyon.fr)    
- [MOD 3.2](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1203) - Apprentissage profond & Intelligence Artificielle, [L. Chen](liming.chen@ec-lyon.fr), A. Bosio, [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)    
- [MOD 4.4](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1241) - Recherche opérationnelle, [M. Zine](abdel-malek.zine@ec-lyon.fr), N. Bousquet, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr)    
- [MOD 4.6](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1249) - Systèmes de bases de données, [L. Chen](liming.chen@ec-lyon.fr)    
- [MOD 5.3](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1252) - Traitement et analyse des données visuelles et sonores, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)    
- [MOD 7.1](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1250) - Systèmes d'information en entreprise, [R. Vuillemot](mailto:romain.vuillemot@ec-lyon.fr)
- [MOD 7.2](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1218) - Introduction à la data science, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr)
- [MOD 8.4](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1243) - Représentation et manipulation de données structurées, [D. Muller](mailto:daniel.muller@ec-lyon.fr)   
- [MOD 9.5](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1244) - Réseaux informatiques, [R. Chalon](rene.chalon@ec-lyon.fr)

[*Détails des enseignements*](https://www.ec-lyon.fr/formation/ingenieure-generaliste/programme-formation/parcours-electif/offre-formation-parcours?module=654017)


### S9 – Modules Ouverts Sectoriels (MOS)

- [MOS 4.3](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1423) - Informatique d'entreprise, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), [D. Muller](mailto:daniel.muller@ec-lyon.fr)    
- [MOS 2.2](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1424) - Informatique graphique, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), N. Bonneel    
- [MOS 4.4](https://pedagogie3.ec-lyon.fr/course/view.php?id=1430) - Nouvelles technologies de l'information et de la communication, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), [D. Muller](mailto:daniel.muller@ec-lyon.fr)   
- [MOS 5.5](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1440) - Visualisation interactive de données,  [R. Vuillemot](mailto:romain.vuillemot@ec-lyon.fr)   

[*Détails des enseignements*](https://www.ec-lyon.fr/formation/ingenieure-generaliste/programme-formation/parcours-electif/offre-formation-parcours?module=654023)


### S9 – Modules Spécifiques Option (MSO)

- [MSO 3.1](https://pedagogie3.ec-lyon.fr/course/view.php?id=1369) - Technologies informatiques du Big Data, [S. Derrode](mailto:stephane.derrode@ec-lyon.fr)   
- [MSO 3.2](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1370) - Les systèmes d'information par la pratique, [R. Vuillemot](mailto:romain.vuillemot@ec-lyon.fr)   
- [MSO 3.3](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1371) - Internet des objets, [R. Chalon](rene.chalon@ec-lyon.fr), [D. Muller](mailto:daniel.muller@ec-lyon.fr)   
- [MSO 3.4](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1372) - Apprentissage automatique, [L. Chen](liming.chen@ec-lyon.fr), [E. Dellandréa](mailto:emmanuel.dellandrea@ec-lyon.fr)   
- [MSO 3.5](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1373) - Vision par ordinateur, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr), [L. Chen](liming.chen@ec-lyon.fr)    
- [MSO 3.6](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1374) - Calcul et modélisation géométrique pour  l'info. graphique, [M. Ardabilian](mailto:mohsen.ardabilian@ec-lyon.fr)   
- [MSO 3.7](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1375) - Apprentissage bayésien et exploration de textes, [A. Saidi](mailto:alexandre.saidi@ec-lyon.fr), [S. Derrode](mailto:stephane.derrode@ec-lyon.fr)
- [MSO 3.8](https://pedagogie3.ec-lyon.fr/enrol/index.php?id=1376) - Projet Informatique, toute l'équipe pédagogique   

[*Détails des enseignements*](https://www.ec-lyon.fr/formation/ingenieure-generaliste/programme-formation/parcours-electif/offre-formation-parcours?module=654039)
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@

# BE #1 : Bibliothèque


---
## Objectif du sujet

@@ -23,7 +22,7 @@ On doit pouvoir gérer le fond documentaire d'une bibliothèque identifiée par

1. Notre application doit être capable de gérer des lecteurs. Chacun d’eux est caractérisé par :

     - Son nom complet (en une seule chaîne)
     - Son nom complet,
     - Son adresse,
     - Un numéro (entier positif attribué de manière unique par les bibliothécaires).

@@ -105,6 +104,7 @@ Un programme principal typique aura l'allure suivante :
    ```



---
## Classe Bibliothèque (75 minutes)

@@ -126,7 +126,6 @@ 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 est déjà présent dans la collection avant de l'ajouter.



---
## Les emprunts (90 minutes)

@@ -206,7 +205,7 @@ Un emprunt sera modélisé par un objet qui associe un lecteur (connu par son id
    
1. Pour simuler le rendu d'un livre par un lecteur à la bibliothèque, implémentez une méthode _retour\_livre(self, numero_lecteur, numero_livre)_. Pour coder cette méthode, on pourra faire appel à une __méthode privée__ appelée _\_\_chercher_emprunt(self, numero_lecteur, numero_livre)_ qui renverra l'instance de l'emprunt s'il fait partie de la liste des emprunts, ou _None_ dans le cas contraire. La méthode _retour\_livre_ affichera un message d'erreur si l'emprunt n'existe pas. Dans le cas contraire, détruisez l'emprunt et pensez à mettre à jour le nombre d’exemplaires du livre ainsi que le nombre d’emprunts du lecteur.

Tester le retour dans votre programme principal grâce au code suivant :
    Testez le retour dans votre programme principal grâce au code suivant :

    ``` python
    if __name__ == '__main__':
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@

Le but de ce BE est d'illustrer le concept d'héritage de la programmation objet, en concevant un module pour manipuler des formes géométriques avec Python. Vous commencerez par définir les classes et leurs attributs, puis implémenterez les méthodes, et les validerez avec des tests.

Pour compléter cet énoncé, la dernière section propose de réfléchir à une schéma UML d'une application décrite par son cahier des charges.

---
## Modélisation avec UML (1h30)
@@ -18,23 +19,17 @@ Les formes géométriques sont représentées par des classes, et l'héritage se

<center><img src="figures/formes.svg" style="width:70%"/></center>

__Exercice 1 -__ Représentez les 3 classes dans un diagramme de classes UML (_voir [diagrams.net](https://app.diagrams.net) pour dessiner en ligne, avec l'onglet UML sur la gauche de l'interface_). Il est recommandé de commencer les noms des classes par une majuscule et les attributs par une minuscule. Durant tout ce BE on considèrera uniquement des attributs privés.


Les attributs `x` et `y` étant partagés par les trois classes et le cercle étant un cas particulier d'ellipse, on introduit l'héritage pour les regrouper. Toutes les formes géométriques hériteront d'une même classe __Forme__, et le cercle héritera de l'ellipse. L'intérêt de ces relations d'héritage 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 à produire (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 (*p. 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 BE.
__Exercice 1 -__ Représentez les 3 classes dans un diagramme de classes UML (_voir [diagrams.net](https://app.diagrams.net) pour dessiner en ligne, avec l'onglet UML sur la gauche de l'interface_). Il est recommandé de commencer les noms des classes par une majuscule et les attributs par une minuscule. Durant tout ce BE on considérera uniquement des attributs privés.

__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 :
__Exercice 3 -__ On vous demande de supporter a minima pour chaque forme les méthodes suivantes :

* `translation(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 telle qu'elle soit incluse dans le rectangle de coins (`x0`, `y0`) et (`x1`, `y1`). Dans le cas du cercle, il faudra également qu'il soit le plus proche du premier coin. Cette méthode est utile par exemple dans [diagrams.net](https://app.diagrams.net) pour le tracé de formes par appui-déplacement de souris.

__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'accès (les fameux _getter_/_setter_) et d'affichage (méthode `__str__`).
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'accès (les fameux _getter_/_setter_) et d'affichage (méthode `__str__`).

__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é).

@@ -90,7 +85,7 @@ La vérification de cette condition est faite une fois au moment de son exécuti

__Exercice 5 -__ Implémentez les méthodes d'affichage (`__str__`) de chacune des classes dans _formes.py_. Vous pourrez vérifier leur bon fonctionnement en exécutant _formes.py_ (bouton `Run File - F5`), puis par exemple avec une commande `print(Rectangle(0, 0, 10, 10))` dans la console _IPython_.

__Exercice 6 -__ Implémentez les méthodes d'accès (_getter_/_setter_) pour les champs privés de chacune des classes. Pour vérifier que les champs sont bien privés, le code suivant __doit__ échouer avec une erreur `AttributeError` :
__Exercice 6 -__ Implémentez les méthodes d'accès (_getter_/_setter_) pour les champs privés de chacune des classes. Pour vérifier que les champs sont bien privés, le code suivant __doit__ échouer avec une erreur de type `AttributeError` :

```python
r = Rectangle(0, 0, 10, 10)
@@ -102,49 +97,23 @@ __Exercice 7 -__ Implémentez les méthodes `contient_point` des deux sous-class
__Exercice 8 -__ Implémentez les méthodes `redimension_par_points` de chacune des sous-classes. Le fichier _test_formes.py_ doit à présent s'exécuter sans problème.


---
## Tests unitaires (bonus)
__Exercice 9 -__ Exécutez ce test sur votre code, et corrigez les éventuels bugs. Représentez ensuite, dans un logiciel de dessin (ex. [diagrams.net](https://app.diagrams.net)), le rectangle et les positions des points qui sont testés. Quels bugs sont visés par chacun de ces tests ?

Une fois développées, vos classes vont être utilisées pour des besoins que vous n'aviez pas forcément anticipés. Elles vont évoluer également pour acquérir de nouvelles fonctionnalités, et vont gagner en complexité. Dans ces conditions, il est courant de voir apparaître des bugs. Une pratique répandue pour améliorer la qualité logicielle est de définir des _tests unitaires_, c'est-à-dire de créer des situations extrêmes et vérifier que vos fonctions donnent toujours de bons résultats. Les tests unitaires serviront à documenter les cas d'utilisation supportés, et également à vous assurer qu'une modification de votre code n'a pas introduit un bug (une _régression_).

Voici une liste de tests relativement exhaustive pour la classe __Rectangle__
__Exercice 10 -__ Dessinez une ellipse dans votre logiciel de dessin, et représentez tous les points qu'il convient de tester avec `contient_point`. Pour chaque point (ou groupe de points), indiquez le type de bug qu'il vise en particulier. Implémentez ces tests dans _test_formes.py_.

```python
def test_Rectangle():
    r = Rectangle(-20, -10, 40, 20)
    assert r.contient_point(0, 0)
    assert r.contient_point(-20, 0)
    assert r.contient_point(0, -10)
    assert r.contient_point(20, 0)
    assert r.contient_point(0, 10)
    assert not r.contient_point(-40, 0)
    assert not r.contient_point(0, -20)
    assert not r.contient_point(40, 0)
    assert not r.contient_point(0, 20)
    assert not r.contient_point(-40, -20)
    assert not r.contient_point(40, -20)
    assert not r.contient_point(40, 20)
    assert not r.contient_point(-40, 20)
    reference = str(r)
    r.redimension_par_points(-20, 10, 20, -10)
    assert str(r) == reference
    r.redimension_par_points(20, 10, -20, -10)
    assert str(r) == reference
    r.redimension_par_points(20, -10, -20, 10)
    assert str(r) == reference
    r.redimension_par_points(-20, -10, 20, 10)
    assert str(r) == reference
```
__Exercice 11 -__ Dans le cas du cercle, la différence principale avec l'ellipse est la méthode `redimension_par_points` qui nécessite de placer le centre du cercle au plus près du premier point. Proposez des tests qui permettent de vérifier que la méthode positionne toujours correctement le cercle dans la boîte englobante d'entrée.

__Exercice 9 -__ Exécutez ce test sur votre code, et corrigez les éventuels bugs. Représentez ensuite, dans un logiciel de dessin (ex. [diagrams.net](https://app.diagrams.net)), le rectangle et les positions des points qui sont testés. Quels bugs sont visés par chacun de ces tests ?

La rédaction de tests unitaires consiste souvent à anticiper les bugs courants, pour améliorer la qualité du logiciel dès sa conception. On cherche donc délibérément à provoquer des situations difficiles à gérer (ex. points _sur_ le bord du rectangle). De telles situations sont par exemple :
---
## Schéma UML

* le choix de `<` ou `<=` dans le code;
* le traitement de valeurs négatives;
* les erreurs d'arrondis dans les opérations avec `float`;
* la gestion de valeurs nulles (ex. largeur ou hauteur).
Cet exercice a été proposé lors de l'examen S6, année 2020-2021.

__Exercice 10 -__ Dessinez une ellipse dans votre logiciel de dessin, et représentez tous les points qu'il convient de tester avec `contient_point`. Pour chaque point (ou groupe de points), indiquez le type de bug qu'il vise en particulier. Implémentez ces tests dans _test_formes.py_.
> La société « L’atelier des chefs » propose des cours de cuisine. Un cours réunit pendant 2h un chef et 2 à 5 apprentis. Pendant un cours, le chef propose une recette du catalogue (Moussaka, Fish and Ships, Osso buco, Tajine marocain, Soupe chinoise…) et aide les apprentis à réaliser cette recette dans le temps imparti. Dans un esprit de convivialité, tout le monde s’appelle par son prénom.
> Ils réalisent ensemble une recette composée d’ingrédients :
> -   une seule viande (parmi porc, veau, poulet) ;
> -   un ou plusieurs légumes (parmi carotte, choux, potiron) ;
> -   une ou plusieurs épices (parmi sel, poivre, curcuma).

__Exercice 11 -__ Dans le cas du cercle, la différence principale avec l'ellipse est la méthode `redimension_par_points` qui nécessite de placer le centre du cercle au plus près du premier point. Proposez des tests qui permettent de vérifier que la méthode positionne toujours correctement le cercle dans la boîte englobante d'entrée.
> Dégager les éléments principaux de cet énoncé et réaliser un diagramme de classes UML permettant de modéliser un cours de cuisine. Il n’est pas nécessaire de préciser les attributs, mais préciser les cardinalités s’il y a lieu.
Original line number Diff line number Diff line
### Consignes pour le rendu (BE #3 - INF-TC2)

Ce BE est le premier devoir à rendre concernant INF-TC2. Le compte-rendu (CR) de ce travail devra être déposé sur ``Pedagogie1``, sur l'espace de dépôt spécifique à votre groupe. Et cela dans un **délai de deux semaines après la séance** (délai de rigueur, aucun travail accepté au delà de cette date).
Ce BE est le premier devoir à rendre concernant INF-TC2. Le compte-rendu (CR) de votre travail devra être déposé sur _Pedagogie1_, sur l'espace de dépôt spécifique à votre groupe. Et cela dans un **délai d'une semaine après la dernière séance consacrée à ce BE** (délai de rigueur, aucun travail accepté au delà de cette date). Cette semaine de délai ne tient pas compte d'éventuelles vacances. Si vous avez un doute, le plus simple est de contrôler la date pour votre groupe sur _Pedagogie1_.

**Consignes:**

 - Le travail peut être individuel ou en binôme. Si vous travaillez en binôme, **un seul dépôt suffit !**.    
 - Le dépôt consistera en une unique archive (zip, rar) contenant l'ensemble des fichiers suivant :   
     - La base de données *Hotellerie.db*, après exécution de vos requêtes. 
> - Le travail peut être individuel ou en binôme. Si vous travaillez en binôme, **un seul dépôt suffit !**.    
> - Le dépôt consistera en une unique archive (zip, rar ou tgz) contenant l'ensemble des fichiers suivants :   
     - La base de données *Hotellerie.db*, après exécution des requêtes de l'énoncé. 
     - Le fichier _HotelDB.py_, contenant la classe **HotelDB** et un programme principal permettant de rejouer l'ensemble des requêtes de cet énoncé.
     - La dernière base de données de votre choix : si vous choisissez cette option, n'oubliez pas d'inclure la nouvelle bdd dans votre archive (si elle est très volumineuse, donnez uniquement le chemin de téléchargement dans votre rapport), ainsi que le fichier _Python_ qui réalise les requêtes que vous aurez imaginées. 
     - un rapport (format _word_, _pdf_, ou mieux encore _markdown_ !) contenant     
     - La base de données de votre choix pour les 2 requêtes libres (si différentes de *Hotellerie.db*) ; Si elle est très volumineuse, donnez uniquement le chemin de téléchargement dans votre rapport). Ajoutez le fichier _Python_ qui met en œuvre les requêtes que vous aurez imaginées. 
     - Un rapport (format _pdf_ exclusivement) contenant     
         - une en-tête où devront figurer le nom des élèves, leur numéro de groupe, le nom de l'encadrant ainsi que le titre du BE.   
         - des commentaires sur la programmation de chacune des requêtes et les résultats obtenus.    
         - tout diagramme, toute figure ou toute explication que vous jugerez utile, mais dans un **nombre de pages limité à 10** (il n'est pas demandé de rédiger 10 pages, c'est une limite à ne pas dépasser !).

 - L'archive devra nécessairement porter le nom suivant : *nom1-devoir1.zip* ou *nom1-nom2-devoir1.zip* (pour les étourdis, pensez à remplacer *nom1* et *nom2* par vos propres noms :-) )
> - L'archive devra nécessairement porter le nom suivant : *nom1-BE3.zip* ou *nom1-nom2-BE3.zip* (pour les étourdis, pensez à remplacer *nom1* et *nom2* par vos propres noms :-) )

**Critères d'évaluation du travail**

Voici une liste (non exhaustive) de critères qui permettront à vos encadrants d'évaluer vos requêtes :

> - **Qualité du rapport** : apparence visuelle globale (lisibilité), orthographe, structure du rapport claire et cohérente. Qualité des représentations graphique (légendes, label sur les axes...).    

> - **Qualité de l'API** : choix des noms et arguments des méthodes, pas de requêtes SQL hors de la classe, code  d'affichage des texte et des graphiques forcément en dehors des méthodes-requêtes.   

> - **Qualité du code** : est-ce qu'il fonctionne sans erreur, le code est-il suffisamment commenté et aéré ? Tests multiples avec des paramètres inattendus ou erronés. Interception des erreurs potentielles par des exceptions.   

> - **Qualité des requêtes** : originalité et justification de l'intérêt, difficulté technique, valorisation dans le rapport.
 
 No newline at end of file
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@

# BE #4 : Application de dessin vectoriel


L'objectif de ce BE est d'apprendre à manipuler quelques composants du module _Python_ _Tkinter_ permettant de créer des interfaces graphiques. Vous allez créer une application simple de dessin vectoriel, qui permettra de tracer à la souris les formes définies dans le BE #2.

---
@@ -12,68 +11,72 @@ L'objectif de ce BE est d'apprendre à manipuler quelques composants du module _

Le module _Tkinter_ (_"Tk interface"_) permet de créer des interfaces graphiques. Il contient de nombreux composants graphiques (ou _widgets_), tels que les boutons (classe __Button__), les cases à cocher (classe __CheckButton__), les étiquettes (classe __Label__), les zones d'entrée de texte (classe __Entry__), les menus (classe __Menu__), ou les zones de dessin (classe __Canvas__).

Durant ce BE, nous vous recommandons de conserver la [documentation de _Tkinter_](http://effbot.org/tkinterbook/) ouverte dans un onglet de votre navigateur. Elle contient des exemples de code qui vous seront utiles pour utiliser chacun des _widgets_.
Durant ce BE, nous vous recommandons de conserver le lien vers une [documentation sur _Tkinter_]( https://python.doctor/page-tkinter-interface-graphique-python-tutoriel) ouverte dans un onglet de votre navigateur. Elle contient des exemples de code qui vous seront utiles pour utiliser chacun des _widgets_.

Voici un premier exemple de code _Tkinter_ :

```python
import random
from tkinter import *
from random import randint

def tirage():
    nb = random.randint(1, 100)
    texteResultat.set('Nombre : ' + str(nb))

if __name__ == '__main__':
class FenPrincipale(Tk):
    def __init__(self):
        Tk.__init__(self)
        
    # création de l'arbre de scène
    racine = Tk() # Appel à une méthode de classe (et non un constructeur, cf slide cours #2)
    racine.title('Tirage aléatoire')
    racine.geometry('300x100+400+400')
        # paramètres de la fenêtre
        self.title('Tirage aléatoire')
        self.geometry('300x100+400+400')
        
    # Les widgets de la scène
    boutonLancer = Button(racine, text='Tirage')
        # constitution de l'arbre de scène
        boutonLancer = Button(self, text='Tirage')
        boutonLancer.pack(side=LEFT, padx=5, pady=5)
    texteResultat = StringVar()
    labelResultat = Label(racine, textvariable=texteResultat)
        self.__texteResultat = StringVar()
        labelResultat = Label(self, textvariable=self.__texteResultat)
        labelResultat.pack(side=LEFT, padx=5, pady=5)
    boutonQuitter = Button(racine, text='Quitter')
        boutonQuitter = Button(self, text='Quitter')
        boutonQuitter.pack(side=LEFT, padx=5, pady=5)
        
    # association des commandes aux widgets
    boutonLancer.config(command=tirage) # appel dit callback (pas de parenthèses)
    boutonQuitter.config(command=racine.quit) # idem
    racine.mainloop() # affichage de l'interface jusqu'à l'appui de Quitter
        # association des widgets aux fonctions
        boutonLancer.config(command=self.tirage) # appel "callback" (pas de parenthèses !)
        boutonQuitter.config(command=self.quit)  # idem
    
    # tire un entier au hasard et l'affiche dans self.__texteResultat
    def tirage(self):
        nb = randint(1, 100)
        self.__texteResultat.set('Nombre : ' + str(nb))


if __name__ == '__main__':
    app = FenPrincipale()
    app.mainloop()
```

*Remarque :* La méthode `pack(...)` est utilisée pour organiser les différents éléments dans la fenêtre.

__Exercice 1 -__ Copiez le code suivant dans un fichier appelé *Exo1.py* et exécutez-le pour observer le résultat. 

__Attention, utilisateurs de Mac__ : l'association _Spyder_+_Tkinter_ ne fonctionne pas bien sous Mac ! Lorsque vous quitterez l'interface (par le biais du bouton _Quitter_), la fenêtre va se bloquer (_freeze_). Deux solutions: 

 - soit vous forcez l'application à sarrêter à chaque fois (utilisez le menu contextuel sur l'icône de l'application concernée dans la barre d'outils);
 - soit vous exécutez votre programme en ligne de commande. Pour cela, ouvrez un terminal dans le répertoire de travail (clic-droit dessus → Nouveau terminal au dossier). Puis lancer la commande : `python3 Exo1.py`. Vous devriez pouvoir quitter l'application sans difficulté. N'oubliez pas de sauvegarder votre fichier sous _Spyder_ avant toute exécution de cette manière !
- soit vous forcez l'application à s'arrêter à chaque fois (utilisez le menu contextuel sur l'icône de l'application concernée dans la barre d'outils);     
- soit vous exécutez votre programme en ligne de commande. Pour cela, ouvrez un `Terminal` dans le répertoire de travail (clic-droit sur le répertoire → Nouveau terminal au dossier). Puis lancez le programme exécutant la commande : `python3 Exo1.py`. Vous devriez pouvoir quitter l'application sans difficulté. N'oubliez pas de sauvegarder votre fichier sous _Spyder_ avant toute exécution de cette manière !

Prenez le temps d'étudier cet exemple, et répondez aux questions suivantes :

* Combien d'éléments contient l'arbre de scène ?
* Que se passe-t-il lorsqu'on clique sur le bouton ?
* Que se passe-t-il lorsqu'on clique sur le bouton `Tirage` ?
* Comment peut-on inverser les positions des deux boutons ?
* Comment peut-on augmenter l'espace à gauche et à droite du label ?
* Comment peut-on colorier le texte du label en rouge ?


---
## Squelette de l'application de dessin (45 min.)
## Squelette de l'application de dessin (60 min.)

On souhaite obtenir l'interface ci-dessous, dans laquelle les utilisateurs sélectionneront le type de forme à dessiner avec les boutons, et créeront une forme en cliquant dans la zone située sous la barre d'outils (_widget_ __Canvas__ de _Tkinter_). On a donné une couleur grise au fond de la fenêtre pour vous aider à déterminer les différents _widgets_ présents.

<center><img src="figures/interface.png" style="width:60%"/></center>

__Exercice 2 -__ Dessinez l'arbre de scène correspondant à cette capture d'écran.


Une pratique courante dans les interfaces graphiques est de créer des classes qui _remplacent_ des nœuds de l'arbre de scène, et d'y mettre le code de l'application. Ces classes héritent des classes de _Tkinter_ (pour pouvoir les remplacer dans l'arbre), et nous leur ajouterons des attributs et méthodes spécifiques à leurs responsabilités dans l'application de dessin. Nous allons ainsi introduire deux classes :
Une pratique courante dans les interfaces graphiques est d'intégrer le code de l'application dans l'arbre de scène, en créant des classes qui s'y intégreront comme des nœuds. Ces classes héritent des classes de _Tkinter_ (pour être autorisées à les remplacer dans l'arbre), et nous leur ajouterons des attributs et méthodes spécifiques à leurs responsabilités dans l'application de dessin. Nous allons ainsi introduire deux classes :

* la classe __ZoneAffichage__, qui hérite de __Canvas__ et gère toutes les opérations de dessin spécifiques à votre application.
* la classe __FenPrincipale__, qui hérite de __Tk__ et gère l'initialisation de l'arbre de scène et des _callbacks_ des _widgets_.
@@ -82,7 +85,12 @@ Voici le diagramme UML correspondant :

<center><img src="figures/Fenetre_ZoneAffichage_1.svg" style="width:50%"/></center>

__Exercice 3 -__ Complétez le code ci-dessous avec l'initialisation de votre arbre de scène. Vous utiliserez une instance de __ZoneAffichage__ à la place de __Canvas__. À ce stade, on ne vous demande pas de programmer les actions, uniquement de mettre en place le design de l'interface. Vous trouverez des exemples d'utilisation de chacun des _widgets_ dans la documentation référencée plus haut.
En rouge figure les classes de la librairie _Tkinter_, et en jaune vos propres classes.

__Exercice 2 -__ Dessinez l'arbre de scène correspondant à la capture d'écran. Pour chaque nœud vous indiquerez la classe et, s'il y a lieu, sa classe parente également.


__Exercice 3 -__ Complétez le code ci-dessous avec l'initialisation de votre arbre de scène. Vous utiliserez une instance de __ZoneAffichage__ pour implémenter le canevas. À ce stade, on ne vous demande pas de programmer les actions associées aux boutons, mais uniquement de mettre en place le design de l'interface. Vous trouverez des exemples d'utilisation de chacun des _widgets_ dans la documentation référencée plus haut.

```python
from tkinter import *
@@ -94,6 +102,7 @@ class ZoneAffichage(Canvas):
class FenPrincipale(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.configure(bg="grey")
        # L'initialisation de l'arbre de scène se fait ici

if __name__ == "__main__":
@@ -101,36 +110,36 @@ if __name__ == "__main__":
    fen.mainloop()
```


---
## Dessin de formes dans le canevas (60 min.)
## Dessin de formes dans le canevas (75 min.)

Vous trouverez dans le dossier de ce BE le fichier [formes.py](formes.py) développé durant le BE #2. Nous avons agrémenté les classes __Rectangle__ et __Ellipse__ pour qu'elles reçoivent un canevas en argument et se dessinent dessus lors de leur initialisation. Téléchargez ce fichier dans votre répertoire de travail.
Vous trouverez dans le dossier de ce BE le fichier [formes.py](formes.py) développé durant le BE #2. Nous avons agrémenté les classes __Rectangle__ et __Ellipse__ pour qu'elles reçoivent un canevas en argument et se dessinent dessus lors de leur initialisation. La classe __Forme__ est maintenant dotée d'une méthode `effacer()` qui supprimera la forme du canevas.

Les classes seront intégrées selon le diagramme UML suivant :
Copiez ce fichier dans votre répertoire de travail.

Ces classes seront intégrées selon le diagramme UML suivant :

<center><img src="figures/Fenetre_ZoneAffichage_2.svg" style="width:90%"/></center>

__Exercice 4 -__ Créez une méthode `ajout_forme(..., x, y)` dans __ZoneAffichage__ qui crée un __Rectangle__ dont le centre sera donné par les 2 arguments _x_ et _y_, de largeur 10 et de hauteur 20. N'oubliez pas de stocker ce rectangle dans __ZoneAffichage__ !
__Exercice 4 -__ À l'aide de la méthode `bind` vue en cours, reliez les clics de la souris dans le canevas (événements `<ButtonRelease-1>`) à une nouvelle méthode de __ZoneAffichage__ qui imprime les coordonnées de chaque clic avec `print`.

__Exercice 5 -__ À l'aide de la méthode `bind` vue en cours, reliez les clics de souris sur le canevas (évènements `<ButtonRelease-1>`) à la méthode `ajout_forme`. Attention, pour utiliser une méthode comme fonction de _callback_, il faut la précéder de `self.`.
__Exercice 5 -__ Modifiez cette méthode pour créer un nouveau __Rectangle__ centré sur la souris chaque fois que la méthode est exécutée (à ce stade choisissez des dimensions arbitraires). N'oubliez pas de stocker ce rectangle dans __ZoneAffichage__ !

__Exercice 6 -__ Ajoutez un attribut à __ZoneAffichage__ qui stocke le type de forme actuellement sélectionné, et associez les boutons Rectangle/Ellipse au type de forme qui est dessiné lorsqu'on clique dans le canevas.
__Exercice 6 -__ Lorsqu'on clique sur le bouton `Ellipse`, l'outil "Ellipse" est sélectionné et tous les futurs clics dans le canevas doivent créer une nouvelle __Ellipse__ (de dimension fixe quelconque). Lorsqu'on clique ensuite sur le bouton `Rectangle`, les clics suivants créeront un __Rectangle__. L'outil sélectionné par défaut est "Rectangle". Modifiez votre code pour implémenter ce comportement.


---
## Quelques opérations de dessin supplémentaires (90 min.)

Nous allons à présent intégrer quelques commandes simples dans l'application de dessin :
## Opérations de dessin supplémentaires (60 min.)

* Lorsqu'on clique sur une forme en maintenant la touche CTRL enfoncée, elle doit être effacée du canevas.
* Lorsqu'on déplace la souris avec le bouton enfoncé sur une forme, on déplace la forme en même temps que la souris.
* Lorsqu'on clique sur le bouton _Couleur_, un sélecteur de couleur apparaît pour choisir la couleur de l'outil de dessin.
Nous allons à présent intégrer deux commandes simples dans l'application de dessin :

__Exercice 7 -__ Implémentez l'effacement des formes avec CTRL-clic (événement `<Control-ButtonRelease-1>`). Vous pourrez faire appel aux méthodes `contient_point(...)` des classes __Rectangle__ et __Ellipse__ pour déterminer si la position de la souris au moment de l’événement est dans le périmètre d'une forme donnée, ainsi qu'à la méthode `effacer(...)` de la classe __Forme__.
* Lorsqu'on clique sur une forme en maintenant la touche CTRL enfoncée, elle doit s'effacer du canevas.
* Lorsqu'on clique sur le bouton _Couleur_, un sélecteur de couleurs apparaît pour choisir la couleur de l'outil de dessin.

__Exercice 8 -__ À l'aide du module _colorchooser_ de _Tkinter_ (```from tkinter import colorchooser```), liez les clics sur le bouton Couleur à l'affichage d'un sélecteur de couleur, et utilisez la couleur renvoyée pour tous les ajouts de formes suivants.
__Exercice 7 -__ Implémentez l'effacement des formes avec CTRL-clic (événement `<Control-ButtonRelease-1>`). Vous pourrez faire appel aux méthodes `contient_point(...)` des classes __Rectangle__ et __Ellipse__ pour déterminer si la position de la souris au moment de l'événement est dans le périmètre d'une forme donnée, ainsi qu'à la méthode `effacer(...)` de la classe __Forme__.

__Exercice 9 -__ À l'aide des types d’événements `<Button-1>`, `<B1-Motion>` et `<ButtonRelease-1>`, implémentez la translation des formes lors des actions d'appui-déplacement de la souris. Comment faire pour qu'elles n'interfèrent pas avec la création de nouvelles formes ?
__Exercice 8 -__ À l'aide du module _colorchooser_ de _Tkinter_ (```from tkinter import colorchooser```), liez les clics sur le bouton _Couleur_ à l'affichage d'un sélecteur de couleur, et utilisez la couleur renvoyée pour tous les ajouts de formes suivants.


---
@@ -138,8 +147,8 @@ __Exercice 9 -__ À l'aide des types d’événements `<Button-1>`, `<B1-Motion>

Il n'y a pas d'ordre prédéfini pour ces trois exercices supplémentaires, choisissez celui dont la fonctionnalité vous semble la plus intéressante.

__Bonus 1 -__ Durant le BE #2 vous avez conçu un troisième type de forme. Il est temps de l'intégrer à votre application de dessin ! Inspirez-vous du code du fichier _formes.py_ de ce BE pour adapter la classe que vous aviez développée. Vous trouverez également les instructions de dessin dans la documentation de Tkinter sur __Canvas__.
__Bonus 1 -__ Dans tout programme de dessin respectable, on doit pouvoir dessiner des formes de tailles arbitraires (pas prédéfinies comme précédemment). À l'aide des types d'événements `<Button-1>`, `<B1-Motion>` et `<ButtonRelease-1>`, faites qu'un mouvement de souris avec le bouton enfoncé dessine une forme en tirant ses coins (lorsqu'il ne déplace pas une forme existante). Vous pourrez utiliser les méthodes `redimension_par_points(...)` des classes __Rectangle__ et __Ellipse__.
  
__Bonus 2 -__ Maintenant que votre programme de dessin vectoriel est fonctionnel, il devrait être possible d'exporter chaque image produite dans un fichier. On utilise pour cela le format SVG, qui est un fichier texte contenant des instructions de dessin. Il suffit d'écrire `<svg width=600 height=400 xmlns=http://www.w3.org/2000/svg>` au début du fichier, `</svg>` à la fin, et d'insérer des balises [`rect`](https://developer.mozilla.org/fr/docs/Web/SVG/Element/rect) et [`ellipse`](https://developer.mozilla.org/fr/docs/Web/SVG/Element/ellipse) entre les deux. C'est à vous de jouer !
__Bonus 2 -__ Il serait aussi pratique de pouvoir déplacer les formes présentes sur le canevas. À l'aide des types d'événements `<Button-1>`, `<B1-Motion>` et `<ButtonRelease-1>`, implémentez la translation des formes lors des actions d'appui-déplacement de la souris. Comment faire pour qu'elles n'interfèrent pas avec la création de nouvelles formes ?

__Bonus 3 -__ Dans tout programme de dessin respectable, on doit pouvoir dessiner des formes de tailles arbitraires (pas prédéfinies). À l'aide des types d’événements `<Button-1>`, `<B1-Motion>` et `<ButtonRelease-1>`, faites qu'un mouvement de souris avec le bouton enfoncé dessine une forme en tirant ses coins (lorsqu'il ne déplace pas une forme existante). Vous pourrez utiliser les méthodes `redimension_par_points` des classes __Rectangle__ et __Ellipse__.
__Bonus 3 -__ Maintenant que votre programme de dessin vectoriel est fonctionnel, on doit pouvoir exporter chaque image produite dans un fichier. On utilise pour cela le format SVG, qui est un fichier texte contenant des instructions de dessin. Il suffit d'écrire `<svg viewBox="0 0 600 400" xmlns="http://www.w3.org/2000/svg">` au début du fichier, `</svg>` à la fin, et d'insérer des balises [`rect`](https://developer.mozilla.org/fr/docs/Web/SVG/Element/rect) et [`ellipse`](https://developer.mozilla.org/fr/docs/Web/SVG/Element/ellipse) entre les deux. Pour obtenir un dessin coloré, vous pouvez insérer à l'intérieur des 2 balises, la chaîne `style="fill: brown"` et remplacer `brown` par la couleur de votre forme. C'est maintenant à vous de jouer !
Original line number Diff line number Diff line
### Consignes pour le rendu (BE #5 - INF-TC2)

Ce BE est le second devoir à rendre concernant INF-TC2. Le compte-rendu (CR) de ce travail devra être déposé sur `Pedagogie1`, sur l'espace de dépôt spécifique à votre groupe. Et cela dans un **délai de deux semaines après la dernière séance consacrée** (délai de rigueur, aucun travail accepté au delà de cette date). Ces 2 semaines ne tiennent pas compte d'éventuelles vacances.
Ce BE est le second devoir à rendre concernant INF-TC2. Le compte-rendu (CR) de votre travail devra être déposé sur `Pedagogie1`, sur l'espace de dépôt spécifique à votre groupe. Et cela dans un **délai d'une (1) semaines après la dernière séance consacrée** (délai de rigueur, aucun travail accepté au delà de cette date). Cette semaine ne tient pas compte d'éventuelles vacances. Si vous avez un doute, le plus simple est de contrôler la date pour votre groupe sur `Pedagogie1`.

**Consignes:**

@@ -8,9 +8,18 @@ Ce BE est le second devoir à rendre concernant INF-TC2. Le compte-rendu (CR) de
  - Le dépôt consistera en une unique archive (zip, rar) contenant l'ensemble des fichiers suivants :     
     - Le fichier _Python_, appelé *Pendu.py*, contenant toutes les classes (**FenPrincipale**, **ZoneAffichage** et **MonBoutonLettre**), et un programme principal permettant de lancer l'application.
     - Le fichier *mots.txt* et la classe *formes.py* (même s'ils n'ont pas été modifiés). 
     - un rapport (format _word_, _pdf_, ou miex encore _markdown_ !) contenant      
         - une en-tête où devront figurer le nom des élèves, leur numéro de groupe, le nom de l'encadrant ainsi que le titre du BE.   
         - un diagramme de classes UML complet de votre application (pensez à utiliser [diagrams](https://app.diagrams.net) !), avec les liens entre les classes, les cardinalités, les attributs (privés ou publics), et les méthodes (elles-mêmes publiques ou privées).  
     - un rapport (format _word_, _pdf_, ou mieux encore _markdown_ !) contenant     
         - Une en-tête où devront figurer le nom des élèves, leur numéro de groupe, le nom de l'encadrant ainsi que le titre du BE.   
         - Un diagramme de classes UML complet de votre application (pensez à utiliser [diagrams](https://app.diagrams.net) !), avec les liens entre les classes, les cardinalités, les attributs (privés ou publics), et les méthodes (elles-mêmes publiques ou privées).  
         - Une présentation du code de la DERNIÈRE PARTIE UNIQUEMENT de votre travail (partie intitulée _Améliorations du jeu_). Vous pouvez utilisez des explications textuelles, des diagrammes, des copies d'écran...

  - L'archive devra nécessairement porter le nom suivant : *nom1-BE5.zip* ou *nom1-nom2-BE5.zip* (pour les étourdis, pensez à remplacer *nom1* et *nom2* par vos propres noms :-) )

**Critères d'évaluation du travail**

Voici une liste (non exhaustive) de critères qui permettront à vos encadrants d'évaluer vos requêtes :

  - **Qualité du rapport** : apparence visuelle globale, orthographe, structure du rapport claire et cohérente. Présence et complétude du diagramme de classes. Qualité des représentations graphiques.       
  - **Qualité du code** : est-ce qu'il fonctionne sans erreur, le code est-il suffisamment commenté et aéré ? Tests multiples avec des paramètres inattendus ou erronés. Interception des erreurs par des exceptions.   
  - **Qualité de l'interface** : aspect visuel de l'interface graphique.
 
 No newline at end of file
Original line number Diff line number Diff line
<mxfile host="Electron" modified="2020-10-07T05:23:43.840Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.7.3 Chrome/85.0.4183.98 Electron/10.1.2 Safari/537.36" etag="rDyIsUkNxe0FlCVNYQt9" version="13.7.3" type="device"><diagram id="uKeeR9P6dBSU_i-VrJ_J" name="Page-1">7Zpbl5owEIB/jY/dQxKuj9W9dNttz7b2nO72LUIEukhsDF766xskgIArispq65PJZHKbfCQziR3UG83vGB57n6lDgg5UnHkHXXcgBEDRxU8sWSQS0wSJwGW+I5VyQd//Q6RQkdLId8ikoMgpDbg/LgptGobE5gUZZozOimpDGhR7HWOXVAR9GwdV6Q/f4Z6cBTRy+Qfiu17aM9CtpGSEU2U5k4mHHTpbEaGbDuoxSnmSGs17JIiNl9olqXf7Smk2MEZCvk2F+08fo6l6P3W+uebjg92fLVz3nWxlwhfphBmNQofEdZQO6lLGPerSEAcPlI6FEAjhL8L5Qi4VjjgVIo+PAllK5j5/ktXj9POK/Hq+UnC9SDMhZ4unVC3OPK+W5JWWubTWhDP6ki2KMGe3apF0ejRiNtlgBijJwswlfIMeSvSIU4BG2vuO0BERIxQKjASY+9MiQ1ii6GZ6+WqJhFywHRZPjnqKg0j21IF6IMbfHYiEGycYtv2QZGKWylPJkApTxV9PQNmyCf13RBMFpCjGcDhcFSV1v7+ktcWokwaKjVa7EYqDXLaRuJnnc9If4+V6zcSmUqQLB74birQt1piwtRgM/SDoZRNCYg7QtjPNlRJHH+iavgmcKWGczDcutSxFSH7m6T4ns7N80zCkyFvZL1TlSGygejbElslJSCJ2WDxuGR6RMyOE6K8QYlgDRTkMIQAUCcmOuLdCRK1H5AuNpqIlksyd+wfeSboR5zQ8K1YcjZiOuo4VEw6QfqjdpIgKglVUgNImK1o9K18jn8dGPCwh9ILIK9uJUc9Iq9uJXrFz7Cb1ZTakwg0R/si+3mXV+pm/eQW13V1O5Urbxels7mJaW7qY6alwOB9TVn2k/vL7k/yosMSPUgIjGamsVWIjG0ZzXIw3c1B6OJyKSZ7TltKOhwL1E/NQzHpGRpQflo4HPIivMM4IjnbOG007MTisS4RzYvsHsk4MkbT/TYy8v4Q07YQ0oN5fNVuFA9TD8fMCRytwqPqpwbHubrUc3oTO+/iFIY9uHDzxlksBNgUtqtR8xHG8HC51oLLxArs2GFixk7bGTqls35hBMYrLVLZ/EgVVYoZqQ2pNQ0cOPgCq+Y72efdoIw59i8cPY0sW94QMlrwIoDWEDBjwSis6JLBlzNRjYmb8m5hZ7WCW3XekmOlNMTMrmKGWMdOOhxlowNipE2a2RFjJ481ubHcmzKoQ1vZ5Wb3c/X/PS7QlZmpLmJUucoHZEDPhg5YxKx+9x8bMuJyXO2OmtYRZ6U0SWE0xAxXMykfvsTEzL5jt/i61bSh6YPcflt+l9nD/ywdwY85ENv/jXqKe//0R3fwF</diagram></mxfile>
 No newline at end of file
Original line number Diff line number Diff line
<?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="592px" height="282px" viewBox="-0.5 -0.5 592 282" content="&lt;mxfile host=&quot;Electron&quot; modified=&quot;2020-10-23T14:24:20.314Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.7.9 Chrome/85.0.4183.121 Electron/10.1.3 Safari/537.36&quot; etag=&quot;j2wcMG27qSD1AfmOCcUu&quot; version=&quot;13.7.9&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;uKeeR9P6dBSU_i-VrJ_J&quot; name=&quot;Page-1&quot;&gt;7Zpbl5owEIB/jY/dQxKuj9W9dNttz7b2nO72LUIEukhsDF766xskgIArispq65PJZHKbfCQziR3UG83vGB57n6lDgg5UnHkHXXcgBEDRxU8sWSQSU7ESgct8Ryrlgr7/h0ihIqWR75BJQZFTGnB/XBTaNAyJzQsyzBidFdWGNCj2OsYuqQj6Ng6q0h++wz05C2jk8g/Ed720Z6DL+Y1wqixnMvGwQ2crInTTQT1GKU9So3mPBLHxUrsk9W5fKc0GxkjIt6lw/+ljNFXvp84313x8sPuzheu+k61M+CKdMKNR6JC4jtJBXcq4R10a4uCB0rEQAiH8RThfyKXCEadC5PFRIEvJ3OdPsnqcfl6RX89XCq4XaSbkbPGUqsWZ59WSvNIyl9aacEZfskUR5uxWLZJOj0bMJhvMACVZmLmEb9BDiR5xCtBIe98ROiJihEKBkQBzf1pkCEsU3UwvXy2RkAu2w+LJUU9xEMmeOlAPxPi7A5Fw4wTDth+STMxSeSoZUmGq+OsJKFs2of+OaKKAFMUYDoeroqTu95e0thh10kCx0Wo3QnGQyzYSN/N8TvpjvFyvmdhUinThwHdDkbbFGhO2FoOhHwS9bEJIzAHadqa5UuLoA13TN4EzJYyT+callqUIyc882+eS7CzfNAwp8lb2C1U5Ehuong2xZXISkogdFo9bhkfkzAgh+iuEGNZAUQ5DCABFQrIj7q0QUesR+UKjqWiJJHPn/oF3km7EOQ3PihVHI6ajrmPFhAOkH2o3KaKCYBUVoLTJilbPytfI57ERD0sIvSDyynZi1DPS6naiV+wcu0l9mQ2pcEOEP7Kvd1m1fuZvXkFtd5dTudJ2cTqbu5jWli5meioczseUVR+pv/z+JD8qLPGjlMBIRiprldjIhtEcF+PNHJQeDqdikue0pbTjoUD9xDwUs56REeWHpeMBD+IrjDOCo53zRtNODA7rEuGc2P6BrBNDJO1/EyPvLyFNOyENqPdXzVbhAPVw/LzA0Qocqn5qcKy7Wy2HN6HzPn5hyKMbB0+85VKATUGLKjUfcRwvh0sdqGy8wK4NBlbspK2xUyrbN2ZQjOIyle2fREGVmKHakFrT0JGDD4BqvqN93j3aiEPf4vHD2JLFPSGDJS8CaA0hAwa80ooOCWwZM/WYmBn/JmZWO5hl9x0pZnpTzMwKZqhlzLTjYQYaMHbqhJktEVbyeLMb250JsyqEtX1eVi93/9/zEm2JmdoSZqWLXGA2xEz4oGXMykfvsTEzLuflzphpLWFWepMEVlPMQAWz8tF7bMzMC2a7v0ttG4oe2P2H5XepPdz/8gHcmDORzf+4l6jnf39EN38B&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><path d="M 301 41 L 158.06 126.76" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 152.92 129.85 L 157.72 122.3 L 158.06 126.76 L 161.84 129.16 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><rect x="301" y="1" width="70" height="40" fill="#fff2cc" stroke="#d6b656" stroke-width="2" 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: 68px; height: 1px; padding-top: 21px; margin-left: 302px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b>racine<br /><font color="#007fff">Tk</font><br /></b></div></div></div></foreignObject><text x="336" y="25" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">racine...</text></switch></g><rect x="81" y="131" width="70" height="40" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" 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: 68px; height: 1px; padding-top: 151px; margin-left: 82px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b>conteneur<br /><font color="#007fff">Frame</font><br /></b></div></div></div></foreignObject><text x="116" y="155" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">conteneur...</text></switch></g><rect x="1" y="241" width="100" height="40" fill="#d5e8d4" stroke="#82b366" stroke-width="2" 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: 98px; height: 1px; padding-top: 261px; margin-left: 2px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b>Nouvelle partie<br /><font color="#007fff">Button</font><br /></b></div></div></div></foreignObject><text x="51" y="265" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Nouvelle partie...</text></switch></g><rect x="141" y="241" width="70" height="40" fill="#d5e8d4" stroke="#82b366" stroke-width="2" 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: 68px; height: 1px; padding-top: 261px; margin-left: 142px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b>Quitter<br /><font color="#007fff">Boutton</font><br /></b></div></div></div></foreignObject><text x="176" y="265" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Quitter...</text></switch></g><path d="M 378.5 171 L 326.23 234.64" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 322.42 239.27 L 324.41 230.55 L 326.23 234.64 L 330.59 235.63 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><rect x="231" y="131" width="70" height="40" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" 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: 68px; height: 1px; padding-top: 151px; margin-left: 232px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b>conteneur<br /><font color="#007fff">Canvas</font><br /></b></div></div></div></foreignObject><text x="266" y="155" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">conteneur...</text></switch></g><rect x="521" y="131" width="70" height="40" fill="#d5e8d4" stroke="#82b366" stroke-width="2" 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: 68px; height: 1px; padding-top: 151px; margin-left: 522px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b>mot<br /><font color="#007fff">Label</font><br /></b></div></div></div></foreignObject><text x="556" y="155" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">mot...</text></switch></g><rect x="361" y="131" width="70" height="40" fill="#ffe6cc" stroke="#d79b00" stroke-width="2" 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: 68px; height: 1px; padding-top: 151px; margin-left: 362px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b>conteneur<br /><font color="#007fff">Frame</font><br /></b></div></div></div></foreignObject><text x="396" y="155" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">conteneur...</text></switch></g><rect x="281" y="241" width="80" height="40" fill="#d5e8d4" stroke="#82b366" stroke-width="2" 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: 78px; height: 1px; padding-top: 261px; margin-left: 282px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b>A<br /><font color="#007fff">Button</font><br /></b></div></div></div></foreignObject><text x="321" y="265" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">A...</text></switch></g><rect x="431" y="241" width="80" height="40" fill="#d5e8d4" stroke="#82b366" stroke-width="2" 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: 78px; height: 1px; padding-top: 261px; margin-left: 432px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: #000000; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b>Z<br /><font color="#007fff">Button</font><br /></b></div></div></div></foreignObject><text x="471" y="265" fill="#000000" font-family="Helvetica" font-size="12px" text-anchor="middle">Z...</text></switch></g><path d="M 378 261 L 418 261" fill="none" stroke="#000000" stroke-width="4" stroke-miterlimit="10" stroke-dasharray="4 8" pointer-events="stroke"/><path d="M 318.5 41 L 270.15 123.89" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 267.13 129.07 L 267.7 120.14 L 270.15 123.89 L 274.61 124.17 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><path d="M 353.5 41 L 392.48 123.55" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 395.05 128.98 L 388.01 123.45 L 392.48 123.55 L 395.25 120.04 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><path d="M 371 41 L 513.94 126.76" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 519.08 129.85 L 510.16 129.16 L 513.94 126.76 L 514.28 122.3 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><path d="M 98.5 171 L 55.62 234.18" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 52.26 239.15 L 53.44 230.28 L 55.62 234.18 L 60.06 234.78 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><path d="M 133.5 171 L 171.73 233.96" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 174.84 239.09 L 167.27 234.33 L 171.73 233.96 L 174.11 230.17 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><path d="M 413.5 171 L 465.77 234.64" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 469.58 239.27 L 461.41 235.63 L 465.77 234.64 L 467.59 230.55 Z" fill="#000000" stroke="#000000" stroke-width="2" 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
Original line number Diff line number Diff line
@@ -13,13 +13,10 @@ class Forme:
        self.x += dx
        self.y += dy

    def setState(self, s):
        self.__canevas.itemconfig(self._item, state=s)

class Rectangle(Forme):
    def __init__(self, canevas, x, y, l, h, couleur):
        Forme.__init__(self, canevas, x, y)
        self._item = canevas.create_rectangle(x, y, x+l, y+h, fill=couleur, state="hidden")
        self._item = canevas.create_rectangle(x, y, x+l, y+h, fill=couleur)
        self.__l = l
        self.__h = h
    
@@ -46,7 +43,7 @@ class Rectangle(Forme):
class Ellipse(Forme):
    def __init__(self, canevas, x, y, rx, ry, couleur):
        Forme.__init__(self, canevas, x, y)
        self._item = canevas.create_oval(x-rx, y-ry, x+rx, y+ry, fill=couleur, state="hidden")
        self._item = canevas.create_oval(x-rx, y-ry, x+rx, y+ry, fill=couleur)
        self.__rx = rx
        self.__ry = ry

Original line number Diff line number Diff line
@@ -4,8 +4,7 @@

# BE #5 : Le jeu du Pendu


L'objectif de ce BE est de réaliser le `jeu du Pendu`. Pour rappel, ce jeu consiste à essayer de découvrir un mot qui est affiché de manière masquée (chacune de ses lettres est remplacée par le caractère _'*'_). Pour cela, le joueur sélectionne une lettre sur le clavier virtuel. Si elle fait partie du mot, alors le mot à découvrir est ré-affiché en laissant apparaître cette lettre en clair. Si par contre le mot ne contient pas la lettre sélectionnée, alors le compteur de coups ratés augmente d'un et l'élément suivant du pendu est ajouté au dessin. Le joueur gagne s’il a pu découvrir le mot avant que le pendu ne soit complètement affiché (au delà de 10 coups manqués). La figure ci-dessous présente l'interface que nous allons construire ; oui, les couleurs piquent un peu aux yeux, mais ça pourra vous aider à répondre à la première question !
L'objectif de ce BE est de réaliser le `jeu du Pendu`. Pour rappel, ce jeu consiste à essayer de découvrir un mot qui est affiché de manière masquée (chacune de ses lettres est remplacée par le caractère _'*'_). Pour cela, le joueur sélectionne une lettre sur le clavier virtuel. Si elle fait partie du mot, alors le mot à découvrir est ré-affiché en laissant apparaître cette lettre en clair. Si par contre le mot ne contient pas la lettre sélectionnée, alors le compteur de coups ratés augmente d'un et l'élément suivant du pendu est ajouté au dessin. Le joueur gagne s'il a pu découvrir le mot avant que le pendu ne soit complètement affiché (au delà de 10 coups manqués). La figure ci-dessous présente l'interface que nous allons construire ; oui, les couleurs piquent un peu aux yeux, mais ça vous aidera à répondre à la première question !

<center><img src="figures/pendu0.png" style="width:60%"/></center>

@@ -18,7 +17,7 @@ Ce BE fera l'objet d'un compte-rendu (CR), seul ou en binôme. L'énoncé corres

__Exercice 1 -__ Dessinez l'arbre de scène correspondant à la capture d'écran ci-dessus.    

__Exercice 2 -__ En vous inspirant de l'organisation des classes du BE #4, programmez l'interface statique (_i.e._ sans commande) en distinguant la classe __FenPrincipale__ et la classe __ZoneAffichage__. À ce stade, à la place des 26 boutons du clavier (correspondant aux 26 lettres en majuscule), placez un simple bouton _"A"_  car le dessin du clavier est traité dans l'exercice suivant.
__Exercice 2 -__ En vous inspirant de l'organisation des classes du BE #4, programmez l'interface statique (_i.e._ sans programmer les commandes associées aux boutons) en distinguant la classe __FenPrincipale__ et la classe __ZoneAffichage__. À ce stade, à la place des 26 boutons du clavier (correspondant aux 26 lettres en majuscule), placez un simple bouton _"A"_  car le dessin du clavier est traité dans l'exercice suivant.

Testez votre interface et faites les ajustements nécessaires pour obtenir une apparence proche de celle donnée en exemple (mais sans le clavier, et avec les couleurs qui vous conviennent !). Le programme principal se réduira à ces quelques lignes :
```python
@@ -43,11 +42,11 @@ Pensez à exécuter votre programme pour vérifier le placement du clavier virtu

 Cette partie est destinée à implémenter la logique de jeu, à travers les commandes de l'interface :

  - _Bouton "Quitter"_ (normalement, c'est déjà fait avec l'appel à la méthode _destroy_ !).
  - _Bouton "Quitter"_ (vous l'avez peut être déjà fait, _cf_ remarque ci-dessus).
  - _Bouton "Nouvelle partie"_.
  - _Boutons-lettres "A", ..., "Z"_.

On fait ici abstraction de la représentation graphique du pendu qui sera traitée dans la partie suivante de cet énoncé. Allons-y pas-à-pas...
On fait ici abstraction de la représentation graphique du pendu qui sera traitée dans la partie suivante. Allons-y pas-à-pas...

### Bouton "Nouvelle Partie" (30 min.)

@@ -56,12 +55,12 @@ Une partie ne pourra commencer que si le joueur appuie sur le bouton "Nouvelle p
__Exercice 4 -__ L'appuie sur ce bouton doit provoquer une ré-initialisation de toute l'interface : 

  - Tirer un nouveau mot au hasard dans le fichier [mots.txt](./mots.txt) (à votre disposition à côté de cet énoncé) et réinitialiser le mot à découvrir;   
  - Dégriser les boutons-lettres (```state=NORMAL```);    
  - Dégriser les boutons-lettres (par la commande suivante ```unBouton.config(state=NORMAL)```);    
  - Effacer le dessin du pendu (question traitée dans la partie suivante de cet énoncé).

_Quelques conseils pour limplémentation_
_Quelques conseils pour l'implémentation_

  - Au chargement de l'application, pensez à griser toutes les lettres du clavier. 
  - Au lancement de l'application, pensez à griser toutes les lettres du clavier (l'utilisateur comprend alors qu'il doit appuyer sur le bouton "Nouvelle partie"). 
  - Utilisez la méthode suivante pour charger les mots du fichier _mots.txt_ dans une liste privée appelée _self.\_\_mots_. Cette liste sera chargée une fois pour toute au lancement de l'application, et utilisée à chaque nouvelle partie.   
```python
def chargeMots(self):
@@ -72,13 +71,6 @@ def chargeMots(self):
```   
  - Pour tirer un nouveau mot au hasard, utilisez la fonction _randint(...)_ (```from random import randint```).

<!--
_Tip_ Vous pouvez créer des attributs différents pour sauvegarder 

  - le mot à deviner et     
  - le mot à deviner mais partiellement caché par des étoiles (celui qui sera affiché sur l'interface pour le joueur).
-->

Pensez à vérifier que votre application est bien fonctionnelle à ce stade.


@@ -89,15 +81,15 @@ Le fait d'appuyer sur une lettre du clavier virtuel doit provoquer un certain no
   - griser le bouton-lettre qui vient d'être cliqué (```state=DISABLED```);    
   - faire apparaître autant de fois que nécessaire la lettre cliquée dans le mot à découvrir;  
   - vérifier si la partie est perdue, gagnée, ou si elle se poursuit;      
   - éventuellement, compléter le dessin du pendu si la lettre n'est pas présente dans le mot (question traitée dans la partie suivante de cet énoncé).
   - éventuellement, compléter le dessin du pendu si la lettre n'est pas présente dans le mot (action traitée dans la partie suivante de cet énoncé).

Chaque bouton doit pouvoir être identifié par la fonction de _callback_ appelée ici _cliquer_. Or il n'est pas possible de passer le numéro du bouton-lettre au _callback_ (aucun argument n'est admis). Nous allons procéder en créant notre propre classe de  boutons, héritant de la classe __Button__.
Chaque bouton doit pouvoir être identifié par la fonction de _callback_ appelée ici _cliquer_. Or il n'est pas possible de passer le numéro du bouton-lettre au _callback_ (aucun argument n'est permis). Nous allons procéder en créant notre propre classe de boutons, héritant de la classe __Button__.

__Exercice 5 -__ Suivez les étapes proposées

  1. Créez la classe __MonBoutonLettre__, qui hérite de la classe __Button__, et qui sauvegarde, en tant qu'attribut privé, la lettre correspondant au bouton (ou le numéro du bouton).  Modifiez en conséquence le constructeur de la classe __FenPrincipale__ pour que le clavier virtuel soit composé de 26 instances de la classe __MonBoutonLettre__. 
  1. Créer la fonction de callback _cliquer(self)_ dans la classe __MonBoutonLettre__, qui fera notamment appel à la méthode _traitement(...)_ de la classe __FenPrincipale__.    
  1. Programmez la méthode _traitement(...)_ dont l'objectif est de mettre à jour l'affichage du mot.    
  1. Créer la classe __MonBoutonLettre__, qui hérite de la classe __Button__, et qui sauvegarde, en tant qu'attribut privé, la lettre correspondant au bouton (ou le numéro du bouton).  Modifier en conséquence le constructeur de la classe __FenPrincipale__ pour que le clavier virtuel soit composé de 26 instances de la classe __MonBoutonLettre__. 
  1. Créer la fonction de callback _cliquer(self)_ dans la classe __MonBoutonLettre__, qui fera notamment appel à une méthode _traitement(...)_ de la classe __FenPrincipale__.    
  1. Programmer cette méthode _traitement(...)_ dont l'objectif est de mettre à jour l'affichage du mot.    
    - Si la partie est gagnée, bloquez l'utilisation du clavier, et affichez un texte qui indique au joueur que c'est gagné !  
    - La partie est perdue quand le nombre de coups dépasse 10 (c'est le nombre d'éléments nécessaires pour dessiner entièrement le pendu). Bloquez alors l'utilisation du clavier, et affichez un texte qui indique au joueur que c'est perdu !  

@@ -107,13 +99,25 @@ __Exercice 5 -__ Suivez les étapes proposées
---  
## Partie 3 - Le dessin du pendu (75 min.)

Cet partie est consacrée au dessin progressif du pendu, au fur et à mesure des échecs du joueur. Ce dessin s'appuie sur les connaissances acquises lors du BE #4 et les classes du fichier [formes.py](./formes.py), disponible à côté de cet énoncé (Attention le fichier utilisé ici est très légèrement différent de celui du BE #4, merci de bien télécharger cette version). 
Cette partie est consacrée au dessin progressif du pendu, au fur et à mesure des échecs du joueur. Ce dessin s'appuie sur les connaissances acquises lors du BE #4 et les classes du fichier [formes.py](./formes.py), disponible à côté de cet énoncé pour ceux qui le souhaitent. L'idée est de créer le pendu comme une liste de rectangles et d'ellipses (10 pièces doivent suffire).

Le parti pris ici est de créer et de dessiner les 10 pièces du pendu dans le constructeur de la classe __ZoneAffichage__, mais en leur affectant la propriété `state="hidden"`, de telle sorte qu'elles ne soient pas visibles. Ce n'est qu'au fur et à mesure de l'avancement d'une partie que les pièces apparaissent sur le canevas, en passant du statut `"hidden"` au statut `"normal"`. La réinitialisation liée à une nouvelle partie consistera alors à cacher l'ensemble des pièces. 

*Remarque* : Notez qu'il aurait aussi été possible d'adopter un autre point de vue qui consisterait à créer et dessiner chaque pièce lors de chaque partie.

__Préliminaires sur le fichier [formes.py](./formes.py)__ 

  - Modifier le fichier [formes.py](./formes.py) de telle manière que les rectangles et les ellipses soient cachés lors de leur création.    
  - Il est nécessaire de prévoir une méthode _setState(s)_ qui permette de changer ce statut. La méthode étant identique pour les rectangles et pour les ellipses, il convient de la factoriser dans la classe __Forme__ :
```python
def setState(self, s):
    self.__canevas.itemconfig(self._item, state=s)
```

__Exercice 6 -__
__Exercice 6 -__ Mettez en place la stratégie décrite ci-dessus pour terminer l'application.

Pour cela, l'idée est de créer le pendu comme une liste de rectangles et d'ellipses (10 pièces doivent suffire), dans le constructeur de la classe __ZoneAffichage__. Pour faire disparaître le pendu (au moment de la création des pièces, ou au moment de la réinitialisation d'une partie p. ex.), on affectera aux pièces l'état caché (```state=hidden```). Pour faire apparaître les pièces progressivement (sur ordre de la méthode _traitement(...)_), on leur affectera l'état normal (```state=normal```).
Pour gagner un peu de temps, voici un exemple de jeu de pièces (avec leur position et leurs dimensions) qui permettent de dessiner le pendu de la première figure.

Pour gagner un peu de temps, voici un exemple de coordonnées pour les éléments graphiques :
```python
# Base, Poteau, Traverse, Corde
Rectangle(self, 50,  270, 200,  26, "brown")
@@ -130,21 +134,22 @@ Rectangle(self, 203, 150, 40, 10, "black")
Rectangle(self, 175, 205,  10,  40, "black")
Rectangle(self, 191, 205,  10,  40, "black")
```
Rien ne vous empêche de customiser votre pendu !


---
## Partie 4 - Améliorations du jeu (autonomie)

Voici quelques améliorations possibles pour le jeu, seule la dernière est considérée comme un bonus.
Voici quelques améliorations pour le jeu, à rendre compte dans votre CR. Seule la dernière amélioration est considérée comme un bonus.

__Exercice 7 - Apparence__ Développez le code qui permet au joueur de choisir les couleurs principales de lapplication (par un  menus, par des boutons...).
__Exercice 7 - Apparence__ Développez le code qui permet au joueur de choisir les couleurs principales de l'application (par un  menus, par des boutons...).

__Exercice 8 - Bouton Triche__ Implémentez un bouton "Triche" qui permet de revenir en arrière d'un coup, pendant la partie.
__Exercice 8 - Triche !__ Implémentez une technique "_Undo_" qui permet de revenir de un ou plusieurs coups en arrière, au cours d'une partie.

__Bonus - Score joueur__ Implémentez un système de sauvegarde des parties jouées par un joueur (identifié par un pseudo demandé au joueur). Techniquement, on pourra créer une base de données _SQL_ (_cf_ BE #3), appelée _pendu.db_, qui stockera une table avec les joueurs et une table avec les parties jouées par ces joueurs, selon le schéma suivant :
__Bonus - Score joueur__ Implémentez un système de sauvegarde des échecs et des succès d'un joueur (identifié par un pseudo demandé au joueur en début de partie). Techniquement, on pourra créer une base de données _SQL_ (_cf_ BE #3), appelée _pendu.db_, qui stockera une table avec les joueurs et une table avec les parties jouées par ces joueurs, selon le schéma suivant :

<center><img src="figures/TableSQLJeuPendu.png" style="width:30%"/></center>

Le score pour chaque mot pourra être défini comme le taux de caractères trouvés (ainsi un score de 1.0 désigne un succès).

_Remarque_ : on ne demande pas ici d'afficher un historique ou des statistiques sur un joueur. Pour consulter la base, on pourra simplement utiliser ```DB Browser for SQLite```.
Dans un premier temps, pour vérifier que votre programme fonctionne, vous pouvez consulter la base _pendu.db_ à l'aide de ```DB Browser for SQLite```. Si vous le souhaitez, vous pouvez alors intégrer à votre application un affichage de l'historique des parties du joueur et/ou de ses performances.
+0 −1
Original line number Diff line number Diff line
<mxfile host="Electron" modified="2020-09-17T14:40:55.338Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.6.2 Chrome/83.0.4103.122 Electron/9.2.0 Safari/537.36" etag="ogBcgt9D4lmq_mGiNo-l" version="13.6.2" type="device"><diagram id="p7oPabUjFc-xsDlfVBy0" name="Page-1">7Vpbk9o2FP41zLQPMLbkCzxyWdLMNJ3MbJo2j8IWtnZli8higf76SpZ8N5ANkN2muw+sdaRzJM53vqMjiwGcJ/t3HG3iDyzEdACscD+AiwEAPvTlpxIctMAdO1oQcRJqkV0J7sk/2AgtI92SEGeNgYIxKsimKQxYmuJANGSIc7ZrDlsz2px1gyLcEdwHiHalf5FQxFo6Bn4l/w2TKC5mtr2J7klQMdh8kyxGIdvVRPBuAOecMaGfkv0cU+W7wi9ab3mkt1wYx6n4FoXPgfcAp1b2MHZsHjj43Tr9c2gbM5k4FN8Yh9IBpsm4iFnEUkTvKumMs20aYmXWkq1qzO+MbaTQlsIHLMTBoIm2gklRLBJqejOBuJgqdKQgZSkuZEtCqTGL07AYsaIsePwUk1SLzSBtiLPHEhio+vdE/K1MjIBrml/MYPW82BfmVeNQziX4oa6l2l/qnZVe3ioUtfOUx46CUjiYbXmATyFhghvxCItT46rYkZzDLMFyQVKRY4oEeWouBJnoj8pxpepHRuQSgWWI6kITpgVPJ1bThP4CRqsKM4kROtSGbdSA7Pg8jtc/z/L7xssHvYKiVfNJJcqZ8BxW6CmfEN0WkDHBsYI62yAJI/CoxGi24vIpEnkgGEkhiIigaFWI5SpW1dAW4So6qSjdxUTg+3wWuNjJnNqkzloG/5xRxnNdGLp4HDolE2o9Y7CCnlfO94S5wPvTUdoNqgKEdnBYpr2rUqJd5Lm4lg69VhDV47AG4fMR8l4ibRW5xa4lFmvknkwtzQwFrpszwLfmjAtTxkVQgQ6Z7mWEq5Ig/xjM4WA62ah/M0f0MgsligTpKlP/wq3Umt0NVLhBeFUyrddrEAR9ZAq9ledeiUz2qyOT30GogEFmu7ThX+/rVtUrs0D7ZqqiKFr9YuVwyNmt2tOv6lG5TFZdqRiuUULoQeuUoCoMVfqKMX3CggSo09M0YlaibKSMJ4g2u3fGXarf0WvJO6nkNeZDlbxJGvXqS0DFkMjYSY2+tdk3OwVHabaWWoV+issBO8bDpvm6+goFj1EemcOW44AzLh0GnEn17NbcF5JsQ5FxHUkpqU28pgyJ+oIKhNo7k/JPL5Tar3nOU1bsfOFtK7EQquCeqkADS725jXAwpAeWjtaSrMssxLJcU5xevv9jOfw0B8PZHaxtgHoBzUUpvTzEjmyNyu/naYwoiWRtuAgkdphfh6VjIBN7naaO36UpsN0uTeGtaDp5o+kbTS+l6f6g/n4SksKJdZ6jVs9WejOOlof9V1+Y1s68jSOvfebIe6Oz+5Ur4+L10e2P0xeFS7HMnpOmzCZft/nDlv8ER0bPe+kq1+4eRFpJNyhdUeVVeSiAUJ0z2qnWHkmNJeOPR7Nnf5o8lRKVx+XmSqemIyFhqDMElpkfrXJTimDmLYu0684G7kLZkklB7w656WskV6tZALnQ7iDo9gAIbgYgvCqAQAH4PtnIfCuZztLjL3VeFbKcmeXCxXBiXQnqyaRJ1p4j6eSHQu2+1bpvte7pWjdQne78I2cRR0miSeHOR6OR/HxuSXsmtq4YLWe+VX9Z/krrb8fyW6dk3+3Z5r2eU7J9s9Thv0QF/kNutPz6jVZZ0J+r7v1nlfcvUoNfWIIfudGymxWo264sj9xodQ35rVK2fXrUX/DiqzEXtBY8Pn01dmb8ja7Gjr+F+p4iDKoi7APJ8t1D3QSoDfKBqSPPf60au1Yx5rReaniW87LFGOheh14C+SeOnhCh/xc4Xddv7pA9cF7pGCWb1c9JNOGr3+TAu38B</diagram></mxfile>
 No newline at end of file
+0 −1
Original line number Diff line number Diff line
<mxfile host="Electron" modified="2020-09-20T06:46:37.677Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/13.7.3 Chrome/85.0.4183.98 Electron/10.1.2 Safari/537.36" etag="bEDzdRwK5yAsqx6JgaMz" version="13.7.3" type="device"><diagram id="p7oPabUjFc-xsDlfVBy0" name="Page-1">7Vlbb+I6EP41SLsPIBKTBB4ptN2VzkpHas9lH01iErdOnHVMgfPrzzi2cwXablsqVUVVZY9nxvZcP8wALdLdtcB58oNHhA3ccbQboOXAdYPpDP4rwl4TpoGvCbGgkSY5NeGG/kcMcWyoGxqRosUoOWeS5m1iyLOMhLJFw0LwbZttzVl71xzHpEe4CTHrU/+hkUzMLdygpn8jNE7szo5vLpxiy2xuUiQ44tsGCV0O0EJwLvUo3S0IU7azdtFyV0dWq4MJksmnCPwd+ndoPi7uphNHhBNyvc7+GjpGTSH39sYkAgOYKRcy4THPMLusqReCb7KIKLVjmNU8f3CeA9EB4h2Rcm+8iTeSAymRKTOrhcRCzpV3gJDxjFjaFWXMqCVZZDlWjIf3twnNNNkwaUWC31eOQWp9R+W/SsXI9cz0p2FW4+XOqleTfbWXFPumlJr/bC7WcuXMCvZ9YO3JNyIkpwxvYhmLmMhTfCZ6lFcaOxgXXxOeEjgQMAjCsKQP7bDFJvrjiq8S/ZNTOLM7NonqBmYjk6fObNxWoW9kpOowAx/hfYMtVwzFiX3Gh/e5+j1+GOgT2FnDJjWpzITnZIXe8gGzjfUhl4IoNxQ5Br+6PgOnXawEjGJZBoKhWEJMJcMrS4ZTrGrWTsLV6aSidJtQSW7KXdByCzW1nTprCP4FZ1yUsijyyDSaVJnQWJm6K+T7p2L0gQhJdieDyq52g8M6ZVuXRMfWuaRRDv1OEDXjsOHC53to1vOQNTU4KGvZ1/+1USX2ItS2matciVdf4GTwB7uPG6OvaqhMBo0ik8M1TinbaxlQhNO8XERIWTwh7IFIGuLeSluJOYnSkXGRYtZe3hpzqfWJPku5yKCCEjFU8Uaz+KA8eE8OKcROZuTH+a69KAXOijVIWfmMVAxbLqK2+qb4Cof3cRmZw47h3Mm0Mpg7mdVjr2G+iBY5w8Z0NGO0sfGacSybB7Ie6iaTss9BV2q7lt1FaXHKg3e1JFIqjDBXgeZe6XwckXDI9jwbrSFzr3Z79YEBuJJxsAdggzph9e7tEwFZx9eRVFZGfzyHMaMx9LJlCI4j4pVSFLVTNOhnaFVKmxmK3ipDK9hzVmRh278dl018ZJHAo92/1fydR5r/G6EY92W4YvxuwOJF4WKPc6DnQi35tSkHG/EBmmfVFN+teTroaPc0JTesTFFXVbReI/j0C+33NIdMhRjhWR8YfbEkain5Rp2wqqcV/etxVNWrxofL7qkSq/wFvZrNzUJKo0iXHAKNBK9KVSpjDYAFvd7FwFsqXVBldLMpVQtu7oqWw9nJLwHPiJHJpINyvV6MTM9ZvR3vE2B9AqzTACtUi97iloBvvMVoNIL/HwFJTYKR18pG5B2o2L53znQM3gNMneWZJmg+01TY7DGgFjwLqZ0DTr02mjryHOK1wYTTBQlHnml6ipDTQSXd2NU3fvl7j9858PSR957T/G/03nP8OeF3ANEPWpTFeIEGc9Vv7rgCrk9BRkXyQZDRawEjd+J0gNGsV4qDs36t7b8NviRUbgV+wJQ9JTpCnqZUfsZHOz5mQbuMHYgP/3XiA6b1jzW68tS/eKHL/wE=</diagram></mxfile>
 No newline at end of file
Original line number Diff line number Diff line
Voici une démo des principales commandes de git, à utiliser depuis un terminal. Pour **Windows**, utilisez le terminal appelé ``Git Bash``, qui a été installé en même temps que **git**). 
Voici une démo des principales commandes de git, à utiliser depuis un terminal. Pour **Windows**, utilisez le _Terminal_ appelé ``Windows Powershell``.

Notez que C.E. Bichot a rédigé un tuto sur l'usage de _git_ en mode commande, disponible en suivant [ce lien](https://gitlab.ec-lyon.fr/cbichot/git-intro). 

**Configuration de git** (à faire une fois pour toute)
```bash
Original line number Diff line number Diff line
@@ -10,28 +10,28 @@ Ce document présente un tuto à l'usage de _git_/_gitlab_. Il est consultable s
Comme tout tutoriel, ce document a besoin de vos retours pour s'améliorer! N’hésitez pas à m'envoyez un mail décrivant vos difficultés et, éventuellement, les solutions que vous auriez trouvées pour les contourner.


> *Remarque* : Pour cutiliser _git_, vous devez savoir ouvrir un _Terminal_ sur votre machine, quelque soit le système d'exploitation (_Windows_, _Linux_, ou _Mac OS X_). Sous _Windows X_, vous pourrez utiliser le programme _Windows powershell_ qui est très similaires au _Terminal_ de _Linux_ et de _Mac OS X_. Vous devez aussi savoir naviguer dans vos dossiers à l'aide de la commande ```cd```. Typiquement :
> *Remarque* : Pour utiliser _git_, vous devez savoir ouvrir un _Terminal_ sur votre machine, quelque soit le système d'exploitation (_Windows_, _Linux_, ou _Mac OS X_). Sous _Windows X_, vous pourrez utiliser le programme _Windows powershell_ qui est très similaires au _Terminal_ de _Linux_ et de _Mac OS X_. Vous devez aussi savoir naviguer dans vos dossiers à l'aide de la commande ```cd```. Typiquement :
```shell
cd c:\Users\stephane\TP_Hadoop # Windows
cd ~\TP_Hadoop                 # Mac, linux
```
Si vous souhaitez remonter d'un niveau dans la hiérarchie des dossiers: ```cd ..```. Des tutos vidéo existent pour décoruvrir les comandes de bases (identiques à celles que l'on retrouve sur les systèmes _Linux_).
Si vous souhaitez remonter d'un niveau dans la hiérarchie des dossiers: `cd ..`. Des tutos vidéo existent pour découvrir les commandes de bases (identiques à celles que l'on retrouve sur les systèmes _Linux_).


---
## Installer _git_ pour Windows (si requis) et et *Github Desktop*
## Installer _git_ pour Windows (si requis) et *Github Desktop*

Avant de commencer, il faut vérifier que _git_ (un gestionnaire de version de fichiers) est bien installé sur votre machine. _git_ est normalement disponible par défaut sur les machines *Mac OS X* et *Linux* et *Windows 10*. Pour vérifier, lancez la commande suivante dans un _Terminal_
Avant de commencer, il faut vérifier que _git_ (un gestionnaire de version de fichiers) est bien installé sur votre machine. _git_ est normalement disponible par défaut sur les machines *Mac OS X*, *Linux* et *Windows 10*. Pour vérifier, lancez la commande suivante dans un _Terminal_
```shell
git --version
```
S'il est absent, alors installez-le grâce au lien suivant [git-scm](https://git-scm.com/download/win). Lors de l'installation, validez les choix par défaut qui vous sont proposés.
Si _git_ est absent, alors installez-le grâce au lien suivant [git-scm](https://git-scm.com/download/win). Lors de l'installation, validez les choix par défaut qui vous sont proposés.

L'interface *Github Desktop* que nous allons installer n'est absolument pas nécessaire pour travailler avec _git_. Mais elle évite, dans un premier temps, d'utiliser des commandes manuelles à partir d'un _Terminal_.

 1. Téléchargez, installez et lancez l'application [Github Desktop](https://desktop.github.com/).
 <center><img src="figures/GithubDesktop_vierge.png" style="width:50%"/></center>
 1. Configurer *Github Desktop* (cette étape n'est nécessaire que si vous ne l'avez pas déjà fait lors de l'installation du logiciel) : aller dans le menu ``Préférences / git`` et entrez votre nom et votre adresse émail.
 1. Configurer *Github Desktop* (cette étape n'est nécessaire que si vous ne l'avez pas déjà fait lors de l'installation du logiciel) : aller dans le menu ``Préférences / git`` et entrez votre nom ainsi que votre adresse émail.


---
@@ -39,31 +39,31 @@ L'interface *Github Desktop* que nous allons installer n'est absolument pas néc

 1. Montrer l'interface de _gitlab_    
    - Adresse: https://gitlab.ec-lyon.fr;    
    - Identifiant: ceux de Centrale;     
    - Naviguer dans le projet INF-TC2. Donner quelques explications sur l'interface.
    - Identifiant: ceux de l'ECL;     
    - Naviguer dans le projet INF-TC2;
 1. Créer un nouveau projet    
    - Nom : _HelloWorld_;     
    - Description: Mon premier projet _gitlab_;    
    - Discuter *Public/Internal/Private*;   
    - Sélectionner *Initialize repository with a README*;
    <center><img src="figures/Gitlab_newproject.png" style="width:50%"/></center>
    - Cliquer sur l'icône ``Clone`` et copier le lien ``Clone with HTTPS``, qui ressemble à https://gitlab.ec-lyon.fr/xyyyyy/helloworld.git. 
    - Cliquer sur l'icône `Clone` et copier le lien `Clone with HTTPS`, qui ressemble à `https://gitlab.ec-lyon.fr/xyyyyy/helloworld.git`. 
 1. Basculer sur *Github Desktop*,     
    - Sélectionner l'option ``Clone a Repository from the Internet``, puis l'onglet ``URL`` (ou menu ``File``, ``Clone repository``).
    - Copier l'adresse précédemment mise en mémoire dans l'espace dédié, et choisir dans ``local path`` le répertoire dans lequel votre projet sera copié. Appuyez sur le bouton ``Clone`` de l'interface pour lancer l'importation de votre projet _gitlab_ sur votre machine.
    - Vérifier dans un gestionnaire de fichiers que le *repo* est bien copié localement sur sa machine et qu'il contient un répertoire caché (``.git``) et le fichier *readme.md*.   
    - Basculer sur l'onglet ``history``, et commenter.     
    - Sélectionner l'option `Clone a Repository from the Internet`, puis l'onglet `URL` (ou menu `File > Clone repository`).
    - Recopier l'adresse précédemment mise en mémoire dans l'espace dédié, et choisir dans `local path` le répertoire dans lequel votre projet sera copié. Appuyez sur le bouton `Clone` de l'interface pour lancer l'importation de votre projet _gitlab_ sur votre machine.
    - Vérifier avec un gestionnaire de fichiers que le *repo* est bien copié localement sur sa machine et qu'il contient un répertoire caché (`.git`) ainsi que le fichier *readme.md*.   
    - Basculer sur l'onglet `history`, et commenter.     
 1. Pour éviter que certains fichiers temporaires ne soient suivis par _git_, on va spécifier les fichiers a exclure dans un fichier appelé *.gitignore* (il s'agit d'un fichier caché). Pour cela    
    - Aller dans le menu ``Repository``, sous-menu ``Repository settings``, puis ``Ignored Files``.   
    - Copier le contenu du fichier qui se trouve à l'adresse https://github.com/github/gitignore/blob/master/Python.gitignore dans l'espace réservé, puis ``Save``.    
    - Aller dans le menu `Repository > Repository settings`, puis `Ignored Files`.   
    - Copier le contenu du fichier qui se trouve à l'adresse `https://github.com/github/gitignore/blob/master/Python.gitignore dans l'espace réservé, puis `Save`.    
    <center><img src="figures/gitignore.png" style="width:50%"/></center>      
    - On doit alors *Commiter* les changements (le texte par défaut qui décrit le ``commit`` est OK). Plus de détails sur ces ``commit`` plus loin.      
    - On doit alors *commiter* les changements (le texte par défaut qui décrit le `commit` est OK). Plus de détails sur ces `commits` plus loin.      
 1. Éditer le fichier *readme.md* avec *Sublime Text* (ou tout autre éditeur de texte) et enregistrer les changements localement:
    - Basculer vers *Github Desktop* et discuter les changements qui interviennent sur l'interface.    
    - *Commiter* les changements, et monter l'onglet *History*.    
    - *Pusher* le travail vers gitlab en utilisant l'option *Publish Branch*.
    - *Pusher* le travail vers _gitlab_ en utilisant l'option *Publish Branch*.
    - Basculer vers _gitlab_ et vérifier que les changements ont bien étaient publiés   
 1. Basculer vers *Spyder* pour éditer du code python:   
 1. Basculer vers *Spyder* pour éditer du code _Python_:   
    - Taper un programme *incremente_de_un(x)* et sauvegarder dans votre répertoire local sous le nom de fichier *incremente.py*. 
    - *commiter* les changements dans *Github Desktop*   
    - Refaire la même chose avec un autre fichier (*incremente_de_deux(x)*), à sauvegarder dans un sous répertoire *test*.
@@ -72,28 +72,29 @@ L'interface *Github Desktop* que nous allons installer n'est absolument pas néc

De manière synthétique, une fois le projet créé,

   1. vous modifiez vos code sources, et enregistrez régulièrement vos changements avec un ``commit`` (donc en local). Vous pouvez ``commiter`` des sources même s'ils ne sont pas terminés ou comportent des bugs. À ce stade cela n'a pas d'importance.     
   1. quand vous êtes content de votre travail, et que vous jugez vos algorithmes fonctionnels, vous pouvez alors publier vos précédents ``commit`` sur _gitlab_ avec un ``push``.
   1. vous modifiez vos code sources, et enregistrez régulièrement vos changements avec un `commit` (donc en local). Vous pouvez `commiter` des sources même s'ils ne sont pas terminés ou comportent des bugs. À ce stade cela n'a pas d'importance.     
   1. quand vous êtes content de votre travail, et que vous jugez vos algorithmes fonctionnels, vous pouvez alors publier vos précédents `commit` sur _gitlab_ avec un `push`.

Ce comportement est illustré par le schéma de la figure suivante:
<center><img src="figures/PrincipeGit.png" style="width:50%"/></center>   

-----
Pour détruire ce projet (sans grand interêt), il faut :
Pour détruire ce projet (sans grand intérêt), il faut :

 1. Quitter Spyder pour farmer les fichiers en cours.
 1. Détruire la version locale en utilisant *Github Desktop*: sélectionner l'onglet ``Current Repository``, et le menu contextuel sur le nom de votre projet permet d'accéder à ``Remove``. Penser à cocher la suppression physique des fichiers si vous le souhaiter (sinon seul la gestion du projet par *Github Desktop* sera supprimée, les fichiers seront toujorus présents sur votre disque dur).
 1. Détruire la version distante sur _gitlab_: Dans la barre de menu latérale à gauche de l'interface Web, sélectionnez l'icône représentant une roue crantée correspondant à ``Settings``. Dans le sous-menu ``Général``, appuyez sur le bouton ``Expand`` correspondant à la ligne : *Advanced*. Tout en bas, sélectionner ``Delete Project``, copier la phrase demandée et appuyer sur le bouton pour confirmer.
 1. Quitter Spyder pour fermer les fichiers en cours.
 1. Détruire la version locale en utilisant *Github Desktop*: sélectionner l'onglet `Current Repository`, et le menu contextuel sur le nom de votre projet permet d'accéder à `Remove`. Penser à cocher la suppression physique des fichiers si vous le souhaitez (sinon seul la gestion du projet par *Github Desktop* sera supprimée, les fichiers seront toujours présents sur votre disque dur).
 1. Détruire la version distante sur _gitlab_: Dans la barre de menu latérale à gauche de l'interface Web, sélectionnez l'icône représentant une roue crantée correspondant à `Settings`. Dans le sous-menu `Général`, appuyez sur le bouton `Expand` correspondant à la ligne : *Advanced*. Tout en bas, sélectionner `Delete Project`, copier la phrase demandée et appuyer sur le bouton pour confirmer.


-----
A quoi ça sert d'utiliser _git_ et _gitlab_ ? Les avantages sont nombreux:

 - Avoir un copie de son travail sur un serveur distant.
 - Sauvegarde incrémentale et dun historique des modification (undo infini!)
 - Sauvegarde incrémentale et disposer d'un historique des modifications (undo infini!)
 - Partager son travail avec tout le monde (si votre projet est publique), ou avec des personnes choisies (invitations personnelles).
 - Travailler à plusieurs sur le même projet et en même temps (mais ça, c'est un autre tuto...)   
      - fusion automatique (ou presque) des sources
      - traçage des modification (qui, qoui)
      - fusion automatique (ou presque) des sources,
      - traçage des modification (qui, quoi).
      - ...

**Stéphane Derrode**
 No newline at end of file