# Dessine ta rue !

## Introduction

Aujourd'hui, on dessine. Mais pas n'importe comment.

Au minimim :

![rue_balcon.png](img/rue_balcon.png){width=500}

Et si vous êtes ambitieux :

![plusieurs_rues.png](img/plusieurs_rues.png){width=500}

Et vous voulez un peu plus de verdure par exemple :

![rue_arbres.png](img/rue_arbres.png){width=500}

#### Prérequis :

+ la création et l'utilisation des modules
+ un peu de Turle pour le programme 1
+ beaucoup de Python (fonctions, dictionnaires ou objets...) pour le programme 2
+ gestion des fichiers-texte, des strings et des tableaux pour le programme 3
+ les bonnes pratiques de programmation



## 1 - Idée générale

Voici l'idée général du projet :

+ On aura d'abord un premier programme **formes.py** comportant des fonctions capables de dessiner des formes simples. Elles utiliseront le module **Turtle** à l'interne.

```mermaid
graph TD;
  formes-->Turtle;
```

Le résultat possible en image :

![exemple_formes](img/exemple_formes.png){align=right width=300}


+ Un deuxième programme nommé **rue.py** devra être capable de dessiner une rue comportant plusieurs immeubles. Aucune ligne de Turtle à l'intérieur de ce programme, juste des appels aux fonctions du premier programme, **formes.py**.

```mermaid
graph TD;
  rue-->formes;
  formes-->Turtle;
```

Le résultat en image :

![exemple_rue](img/exemple_interpreteur_1.png){align=right width=300}


+ Votre troisième programme **interpreteur** devra lire un fichier-texte contenant une description codifiée de la rue et devra la tracer en utilisant... le programme 2, **rue.py**.

```mermaid
graph TD;
  interpreteur-->rue;
  rue-->formes;
  formes-->Turtle;
```

Imaginons qu'on ai un fichier **exemple1.txt** texte qui contienne ceci :

```
rue
4 immeubles
facade rouge - 2 étages - porte rouge au milieu - toit classique
facade verte - 4 étages - porte verte à droite - toit plat
aléatoire
facade violet - 3 étages - porte bleue au milieu - toit bizarre
```

On pourrait alors imaginer cette fonction présente dans **interpreteur.py** :

```python
>>> interpreter_dessin('exemple1.txt')
```

![exemple_interpreteur_1](img/exemple_interpreteur_1.png){align=right width=300}

Mais on peut aussi imaginer qu'on accepte des descriptions de ce type :

```
rue
4 immeubles
aléatoire
```


Attention, le choix de la syntaxe est totalement libre. C'est une occasion unique de créer votre langage.

Mais d'ailleurs... comment dessine Turtle ? A qui fait-il appel&nbsp;?


## 2 - Cahier des charges

Pour être certain de partir tous dans la même direction au début, et gagner un peu de temps de coordination, voici quelques choix imposés.

On devra pouvoir créer la rue de façon aléatoire. Elle devra alors comporter au minimum 4 immeubles différents.

![exemple_rue](img/exemple_interpreteur_1.png){align=right width=300}


Chaque immeuble aura les caractéristiques suivantes :

+ Des immeubles d'une largeur de 140 pixels,
+ Chaque étage fait 80 pixels,
+ Entre 1 à 5 étages pour un immeuble
+ Chaque fenêtre fait 30 px sur 30 px
+ Une porte unique au rez-de-chaussée de 30 px sur 50px
+ Deux variations du toit
+ Plusieurs couleurs disponibles
+ Il est possible que certaines fenêtres soient des portes-fenêtres de 30 px sur 50 px.

Pour simplifier les explications, je considère que votre projet comporte ces 4 fichiers, placés simplement dans le même répertoire. Bien entendu, vous êtes libres de créer un vrai package.

```
📁 activite_module

  📄 formes.py

  📄 rue.py

  📄 interpreteur.py

  📄 ma_rue.txt
```

**Le projet que vous rendrez devra donc comporter au moins 4 fichiers**.



## 3 - Les fichiers fournis


Voici le squelette de **formes.py**, le programme 1 : celui qui devra contenir des fonctions permettant de dessiner des formes géométriques basiques : carré, rectangle, disque, cercle, triangle...

```python
'''Ce fichier permet de dessiner deux formes à l'aide des deux fonctions suivantes

+ triangle_equilateral(cote, infos, coordonnees)
+ arc_de_cercle(rayon, angle, infos, coordonnees)

Exemples d'utilisation :
>>> infos_generales = {'écriture':'blue', 'fond':'#FF88FF', 'épaisseur':5}
>>> triangle_equilateral(50, infos_generales, (50,100))
>>> arc_de_cercle(75, 360, infos_generales, (200,-200))

'''

# Importation

import turtle as trt
import random as rd

# Pas de classes

# Déclaration des fonctions privées

def nouveau_stylo(ecriture, fond, largeur):
    '''Renvoie la référence d'un stylo configuré

    :: param ecriture(str)  :: la couleur d'écriture ('red', '#FF0000')
    :: param fond(str)      :: la couleur de fond pour ce stylo
    :: param largeur(int)   :: la largeur du trait
    :: return (Turtle)      :: renvoie un objet de la classe Turtle

    '''
    feutre = trt.Turtle()
    feutre.color(ecriture)
    feutre.fillcolor(fond)
    feutre.pensize(largeur)
    feutre.speed(5)
    return feutre

def deplacer(feutre, x, y):
    '''Lève le feutre, déplace le feutre et abaisse le feutre

    :: param feutre(Turtle) :: la référence de l'objet Turtle
    :: param x(int)         :: coordonnée horizontale (abscisse)
    :: param y(int)         :: coordonnée verticale (ordonnée)
    :: return (None)        :: c'est une fonction sans retour
    .. effet de bord        :: modifie l'état de feutre

    '''
    feutre.penup()       # On lève la pointe
    feutre.goto(x, y)  # On déplace le crayon
    feutre.pendown()     # On abaisse la pointe

def trace_triangle_equilateral(feutre, cote):
    '''Trace un triangle (equilatéral) à l'aide du crayon feutre

    :: param ftr(Turtle)    :: la référence de l'objet Turtle
    :: param cote(int)      :: la valeur en pixel des côtés
    :: return (None)        :: fonction sans retour
    .. effet de bord        :: modifie l'état de feutre

    '''
    feutre.begin_fill()
    for x in range(3):
        feutre.forward(cote)
        feutre.left(120)
    feutre.end_fill()
    feutre.hideturtle()

def trace_arc(feutre, rayon, angle):
    '''Trace un arc de cercle à l'aide du crayon feutre

    :: param ftr(Turtle)    :: la référence de l'objet Turtle
    :: param rayon(int)     :: la valeur en pixel du rayon
    :: param angle(int)     :: l'angle à tracer (360 pour un cercle)
    :: return (None)        :: fonction sans retour
    .. effet de bord        :: modifie l'état de feutre

    '''
    feutre.begin_fill()
    feutre.circle(rayon, angle)
    feutre.end_fill()
    feutre.hideturtle()

# Déclarations des fonctions d'interface (aucun paramètre n'est lié au module Turtle)

def triangle_equilateral(cote, infos, coordonnees):
    '''Trace un triangle (equilatéral) à partir des infos et aux bonnees coordonnées

    :: param cote(int)                     :: la valeur en pixel des côtés
    :: param infos(dict)                   :: un dictionnaire {"écriture":str, "fond":str, "épaisseur":int}    
    :: param coordonnees(tuple (int,int) ) :: un tuple (x,y)

    '''
    ecriture = infos['écriture']
    fond = infos['fond']
    epaisseur = infos['épaisseur']
    x = coordonnees[0]                  # ou x,y = coordonnees
    y = coordonnees[1]

    feutre = nouveau_stylo(ecriture, fond, epaisseur)
    deplacer(feutre, x, y)
    trace_triangle_equilateral(feutre, cote)

    return feutre

def arc_de_cercle(rayon, angle, infos, coordonnees):
    '''Trace un arc de cercle à partir des infos et aux bonnees coordonnées

    :: param rayon(int)                    :: la valeur en pixel du rayon
    :: param angle(int)                    :: la valeur en ° de l'angle
    :: param infos(dict)                   :: un dictionnaire {"écriture":str, "fond":str, "épaisseur":int}    
    :: param coordonnees(tuple (int,int) ) :: un tuple (x,y)

    '''
    ecriture = infos['écriture']
    fond = infos['fond']
    epaisseur = infos['épaisseur']
    x = coordonnees[0]                  # ou x,y = coordonnees
    y = coordonnees[1]

    feutre = nouveau_stylo(ecriture, fond, epaisseur)
    deplacer(feutre, x, y)
    trace_arc(feutre, rayon, angle)

    return feutre

# Corps du programme principal

if __name__ == '__main__':

    infos_generales = {'écriture':'blue', 'fond':'#FF88FF', 'épaisseur':5}
    triangle_equilateral(50, infos_generales, (50,100))
    arc_de_cercle(75, 360, infos_generales, (200,-200))

```



Le squelette de **rue.py**, le programme qui devra contenir les fonctions permettant de dessiner des immeubles. Attention, beaucoup de choses à rajouter dans celui-ci. Pour l'instant, il trace notamment les 4 "immeubles" au même endroit et les immeubles ne ressemblent pas trop à des immeubles.

```python
# Importation

from formes import triangle_equilateral

# Fonction gestion des données

def determiner_immeuble(numero:int) -> dict:
    caracteristiques = {}
    caracteristiques['couleur_facade'] = 'red'
    caracteristiques['numero'] = numero
    return caracteristiques

# Fonctions d'interface graphique

def dessiner_facade(informations:dict):
    facade = {}  # pour faire la "traduction" entre les clés de ce module et les clés du module formes
    facade['écriture'] = 'blue'
    facade['fond'] = informations['couleur_facade']
    facade['épaisseur'] = 5 * informations['numero']
    triangle_equilateral(50, facade, (0,0))

def dessiner_porte(informations:dict):
    pass

def dessiner_immeuble(informations:dict):
    dessiner_facade(informations)
    dessiner_porte(informations)
    # à compléter avec d'autres fonctions pour le reste : toit, fenêtres...

# Programme principal

if __name__ == '__main__':

    for x in range(4):
        infos_immeuble = determiner_immeuble(x)
        dessiner_immeuble(infos_immeuble)
```

L'intérêt du dictionnaire est évident ici : on pourra envoyer autant de caractéristiques qu'on veut. Au début il n'y aura que le numéro dans la rue, le nombre d'étages et la couleur de la façade par exemple.



## 4 - Organisation du travail

Voici une proposition d'organisation pour le début du projet mais attention, le déroulé n'est pas vraiment linéaire : à vous de vous repartir le travail :


#### Etape 1

S'approprier **formes.py** (programme incomplet pour le moment) :

+ Parvenir individuellement à tracer les triangles et les cercles où vous voulez
+ Réfléchir ensemble aux formes générales qui vont être utiles pour faire des dessins quelconques.
+ Définir ensemble les prototypes de ces fonctions : noms, paramètres nécessaires...
+ L'un d'entre vous peut alors être chargé d'implémenter réellement ces fonctions.


#### Etape 2

S'approprier **rue.py** (programme non fonctionnel pour le moment)

+ Comprendre où se détermine les caractéristiques de l'immeuble
+ Comprendre pourquoi le programme affiche juste des triangles pour le moment
+ Réfléchir ensemble aux caractéristiques essentielles à connaître sur un immeuble pour parvenir à le dessiner à l'écran.
+ L'un d'entre vous peut alors modifier la création des caractéristiques pour qu'elles soient aléatoires en partie.
+ L'un d'entre vous peut modifier le programme pour que les coordonnées de l'immeuble soient dépendantes du numéro de l'immeuble.
+ L'un d'entre vous peut utiliser les fonctions de dessin pour commencer à tracer une vraie façade et pas juste un triangle
    ...

#### Etape 3

Réaliser entièrement le programme **interpreteur.py** qui doit lire un fichier-texte (en suivant une syntaxe qu'il vous faudra inventer au préalable) pour parvenir à retrouver les caractéristiques voulues pour la rue (nombre d'immeubles, caractéristiques de chaque immeuble...). Il ne restera ensuite qu'à faire appel aux fonctions du module **rue.py** pour tracer votre rue.



#### Comment avancer ensuite ?

Déjà en réalisant rapidement un prototype d'immeuble : cela permettra de valider la communication entre les modules **rue** et **formes**.

Une fois le prototype réalisé, il suffira de rajouter les options à travers de nouvelles fonctions ?:

+ une fonction pour tracer une porte ?
+ une fonction pour tracer une fenêtre ?
+ une fonction pour tracer les fenêtres ?
+ une fonction pour tracer le toit ?
+ une fonction pour tracer une antenne ou un pigeon ?
+ ...

Vous êtes plusieurs, il faudra **vous répartir les fonctions à réaliser**. Sinon, c'est une perte de temps. Pensez à utiliser les quelques techniques de coopération que nous avons abordé en cours.

Pour vous coordonner, il est évident qu'il faut par contre vraiment avoir défini les noms et les paramètres des fonctions avant de vraiment les réaliser.




## 5 - Notation

4 critères de réussite sur 5 par exemple.

On attribue **une note de 0 à 5** aux critères.

+ 5 si Bien
+ 4 si Assez bien
+ 3 si Moyen
+ 2 si Léger
+ 1 si Insuffisant
+ 0 si Rien

On fait la **somme des critères**.

Attention : aucun critère ne peut avoir plus que (le plus petit + 2).

#### Critère 1 - Réalisation pratique du projet

+ Général : Toutes les fonctionnalités sont présentes
+ Général : Respect scrupuleux du cahier des charges
+ Spécifique à ce projet : Respect de l'encapsulation et de la modularité : les différentes parties du projet sont-elles réutilisables ?

#### Critère 2-  Bonnes pratiques de programmation, notamment :

+ Noms explicites
+ Utilisation limitée et raisonnée des variables globales
+ Fonctions courtes et décomposition en sous-étapes
+ Séparation entre fonctions gérant les données et l'interface graphique.
+ Présence de jeux de tests pour les fonctions gérant les données

#### Critère 3 - Communication (à l'écrit et à l'oral)

+ Documentation des fonctions et des modules
+ Qualité de l'interaction avec l'enseignant
+ Qualité de l'interaction avec les autres membres de l'équipe

#### Critère 4 - Qualité de la revue de projet

+ régularité des informations notées
+ description de qui a fait quoi
+ prototypes des fonctions avant implémentation
+ tests permettant de valider la solution avant implémentation si possible, après coup sinon











**Proposer une activité élève** dont le but est de réaliser un **ensemble de modules** permettant au final d'interpréter une description textuelle d'une rue et de la représenter graphiquement à l'écran.

![rue_arbres.png](img/rue_arbres.png){width=500}


# Structure imposée pour uniformiser un peu les propositions

Il faudra créer :

+ un module nommé **formes** qui doit contenir des fonctions d'interface permettant de dessiner des formes simples. Ce module devra utiliser à l'interne le module **Turtle** par exemple.

```mermaid
graph TD;
  formes-->Turtle;
```

+ un module nommé **rue** qui doit contenir des fonctions d'interface permettant de dessiner un immeuble, et donc une rue comportant plusieurs immeubles. Ce module devra utiliser à l'interne le module **formes**.

```mermaid
graph TD;
  rue-->formes;
  formes-->Turtle;
```

+ un module nommé **interpreteur** qui doit contenir une fonction capable de lire un fichier-texte contenant une description codifiée de la rue qu'on veut dessiner.

```mermaid
graph TD;
  interpreteur-->rue;
  rue-->formes;
  formes-->Turtle;
```


Avec le module **interpreteur**, un enfant devra être capable de simplement modifier le fichier-texte et il pourra alors voir sa rue sans qu'il ai besoin de taper la moindre ligne de Python.


# Premier module : formes


### Généralités

Le module **formes** doit permettre de tracer des **formes géométriques basiques** : des cercles, des rectangles, des triangles...

Il faudra impérativement qu'**aucune connaissance de l'interface graphique utilisée pour tracer les formes ne soit nécessaire à l'utilisateur du module**.

+ L'utilisateur transmet juste les informations nécessaires pour décrire la forme qu'il veut tracer.
+ La fonction d'interface gère à l'interne la communication avec l'interface graphique.
+ L'interface graphique trace la forme voulue


### Exemple possible de fonctionnement

```python
from formes import triangle_equilateral
from formes import arc_de_cercle

infos = {'écriture':'blue', 'fond':'#FF88FF', 'épaisseur':5}
triangle_equilateral(50, infos, (0, 100))

infos = {'écriture':'red', 'fond':'#FF8833', 'épaisseur':10}
arc_de_cercle(75, 180, infos, (-200, 0))
```

Le résultat possible en image :

![exemple_formes](img/exemple_formes.png){align=right width=300}


### Ebauche possible du fichier formes.py

Pour gagner un peu de temps, voici une ébauche possible de **formes.py**. Non finalisée, elle permet juste de tracer un triangle et un arc de cercle à l'aide deux fonctions d'interface `triangle_equilateral()` et `arc_de_cercle()` :


```python
'''Module basé sur le module Turtle.
Il permet de dessiner des formes simples à l'aide de 2 fonctions d'interface suivantes :

Fonctions d'interface dessinant une forme
-----------------------------------------

+ triange_equilateral(cote:int, infos:dict, coordonnees:tuple)
+ arc_de_cercle(rayon:int, angle:int, infos:dict, coordonnees:tuple)


Exemples d'utilisation
----------------------
>>> infos = {'écriture':'blue', 'fond':'#FF88FF', 'épaisseur':5}
>>> triangle_equilateral(50, infos, (50,100))
>>> infos = {'écriture':'red', 'fond':'#FF8833', 'épaisseur':10}
>>> arc_de_cercle(75, 90, infos, (200,-200))

'''

# Importation

import turtle as trt


# Déclaration des fonctions qui ne sont pas dans l'interface-programmation

def nouveau_stylo(ecriture, fond, largeur):
    '''Renvoie la référence d'un stylo configuré

    :: param ecriture(str)  :: la couleur d'écriture ('red', '#FF0000')
    :: param fond(str)      :: la couleur de fond pour ce stylo
    :: param largeur(int)   :: la largeur du trait
    :: return (Turtle)      :: renvoie un objet de la classe Turtle

    '''
    feutre = trt.Turtle()
    feutre.color(ecriture)
    feutre.fillcolor(fond)
    feutre.pensize(largeur)
    feutre.speed(0)

    return feutre

def deplacer(feutre, x, y):
    '''Lève le feutre, déplace le feutre et abaisse le feutre

    :: param feutre(Turtle)  :: la référence du crayon
    :: param x(int,flt)      :: coordonnée horizontale (abscisse)
    :: param y(int,flt)      :: coordonnée verticale (ordonnée)
    :: return (None)         :: c'est une fonction sans retour
    .. effet de bord         :: modifie l'état de feutre

    '''
    feutre. penup()      # On lève la pointe
    feutre.goto(x, y)    # On déplace le crayon
    feutre.pendown()     # On abaisse la pointe

def trace_arc_de_cercle(feutre, rayon, angle=360):
    '''Trace un arc de cercle à l'aide du crayon feutre

    :: param ftr(Turtle)    :: la référence de l'objet Turtle
    :: param rayon(int)     :: la valeur en pixel du rayon
    :: param angle(int)     :: l'angle à tracer (360 pour un cercle)
    :: return (None)        :: fonction sans retour
    .. effet de bord        :: modifie l'état de feutre

    '''
    feutre.begin_fill()
    feutre.circle(rayon, angle)
    feutre.end_fill()
    feutre.hideturtle()

def trace_triangle_equilateral(feutre, cote) :
    '''Trace un triangle équilatéral à l'aide du crayon feutre

    :: param feutre(Turtle)   :: la référence du crayon
    :: param cote(int)        :: la valeur en pixel du côté
    :: return (None)          :: une fonction sans retour
    .. effet de bord          :: modifie l'état de ftr

    '''
    feutre.begin_fill()
    for x in range(3):
        feutre.forward(cote)
        feutre.left(120)        
    feutre.end_fill()
    feutre.hideturtle()



# Déclarations des fonctions d'interface du module

def triangle_equilateral(cote, infos, coordonnees):
    '''Trace un triangle equilateral à partir des infos et aux bonnees coordonnées

    :: param cote(int)                     :: la valeur en pixel du côté
    :: param infos(dict)                   :: un dictionnaire {"écriture":str, "fond":str, "épaisseur":int}    
    :: param coordonnees(tuple (int,int) ) :: les coordonnées (x,y)

    '''
    ecriture = infos['écriture']
    fond = infos['fond']
    epaisseur = infos['épaisseur']
    x = coordonnees[0]
    y = coordonnees[1]

    feutre = nouveau_stylo(ecriture, fond, epaisseur)
    deplacer(feutre, x, y)
    trace_triangle_equilateral(feutre, cote)

    return feutre

def arc_de_cercle(rayon, angle, infos, coordonnees):
    '''Trace un arc de cercle selon un certain rayon et coordonnées

    :: param rayon(int)                     :: le rayon du cercle
    :: param angle(int)                     :: l'angle de cet arc de cercle
    :: param infos(dict)                    :: un dictionnaire{"écriture":str, "fond":str, "épaisseur":int}
    :: param coordonnees(tuple (int,int) )  :: un tuple (x,y)

    '''
    ecriture = infos['écriture']
    fond = infos['fond']
    epaisseur = infos['épaisseur']
    x = coordonnees[0]
    y = coordonnees[1]

    feutre = nouveau_stylo(ecriture, fond, epaisseur)
    deplacer(feutre, x, y)
    trace_arc_de_cercle(feutre, rayon, angle)

    return feutre


# Exemples de fonctionnement

def exemples_formes():
    infos = {'écriture':'blue', 'fond':'#FF88FF', 'épaisseur':5}
    triangle_equilateral(50, infos, (50,100))
    infos = {'écriture':'red', 'fond':'#FF8833', 'épaisseur':10}
    arc_de_cercle(75, 180, infos, (200,-200))

if __name__ == '__main__':        
    exemples_formes()
```


# Deuxième module : rue


### Généralités

Le module **rue** devra contenir au moins 4 fonctions d'interface :

+ `nouvel_immeuble()` doit renvoyer une structure de données contenant les caractéristiques par défaut d'un immeuble "standard" (à vous de décider de ce que cela veut dire : quelle couleur, quel numéro, quel toit...). Aucune structure de données n'est imposée pour stocker ces caractéristiques.

+ `determiner_immeuble()` doit renvoyer une structure de données contenant les caractéristiques d'un immeuble aléatoire à partir son numéro dans la rue. L'immeuble 1 sera plus à gauche que l'immeuble 2 par exemple.

+ `dessiner_immeuble()` doit permettre de tracer un **immeuble** dont on transmet les caractéristiques **via un paramètre**.

+ `dessiner_rue()` doit permettre de tracer une rue de 4 immeubles dont les caractéristiques sont définies aléatoirement.


Voici les prototypes :

```python
def nouvel_immeuble() -> 'Immeuble':
    pass

def determiner_immeuble(numero:int) -> 'Immeuble':
    pass

def dessiner_immeuble(immeuble:'Immeuble'):
    pass

def dessiner_rue():
    pass
```

### Exemples d'utilisation

#### Exemple 1 : Rue aléatoire

Voici comme on désire réaliser une rue aléatoire :

```python
>>> from rue import dessiner_rue
>>> dessiner_rue()
```

Le résultat en image :

![exemple_rue](img/exemple_interpreteur_1.png){align=right width=300}


#### Exemple 2 : Dessiner deux immeubles

Si on ne veut tracer que deux immeubles, au numéro 0 et 3 :

```python
>>> from rue import determiner_immeuble
>>> from rue import dessiner_immeuble
>>> im1 = determiner_immeuble(0)
>>> im2 = determiner_immeuble(3)
>>> dessiner_immeuble(im1)
>>> dessiner_immeuble(im2)
```

On obtiendra juste deux immeubles :

![exemple_determiner_immeuble](img/exemple_determiner_immeuble.png){align=right width=300}


# Troisième module : interpreteur

### Généralités

Ce module **interpreteur** devra être capable de lire et d'interpréter un fichier-texte __bien formulé__ (et c'est à vous de créer le format et de définir ce qu'est un texte interprétable).

+ le module **interpreteur** lit le fichier qu'on lui indique
+ le module **interpreteur** interprète et stocke les informations lues dans une structure de données de votre choix.
+ le module **interpreteur** structure les informations précédentes pour les rendre compatible avec le module **rue**. Remarque : avoir, dans le module **rue**, des fonctions d'interface permettant d'affecter certaines caractéristiques précises à une structure Immeuble serait bien pratique.
+ le module **interpreteur** fait appel à la fonction d'interface **dessiner_immeuble()** du module **rue** pour tracer les immeubles de la rue.

### Exemples

Imaginons qu'on ai un fichier **exemple1.txt** texte qui contienne ceci :

```
rue
4 immeubles
facade rouge - 2 étages - porte rouge au milieu - toit classique
facade verte - 4 étages - porte verte à droite - toit plat
aléatoire
facade violet - 3 étages - porte bleue au milieu - toit bizarre
```

#### Exemple ; premier appel

```python
>>> interpreter_dessin('exemple1.txt')
```

![exemple_interpreteur_1](img/exemple_interpreteur_1.png){align=right width=300}

#### Exemple ; deuxième appel

Si on lance un deuxième appel sur le même texte, seul l'immeuble 3 doit être différent :

```python
>>> interpreter_dessin('exemple1.txt')
```

![exemple_interpreteur_2](img/exemple_interpreteur_2.png){align=right width=300}


# Cahier des charges

On impose d'avoir **4 fichiers différents** au moins :

+ **formes.py** qui trace les formes simples.
+ **rue.py** qui trace des immeubles en utilisant le module **formes.py**.
+ **interpreteur.py** qui lit un fichier-texte et trace des immeubles en utilisant le module **rue.py**.
+ un **fichier-texte** interprétable par **interpreteur.py**.

La documentation des modules devra **préciser clairement quelles sont les fonctions d'interface** disponibles dans chaque module.

Les immeubles auront les **caractéristiques imposées** suivantes :

+ largeur de **140** pixels,
+ chaque étage fait **80** pixels,
+ entre **1 à 5 étages** pour un immeuble,
+ chaque fenêtre fait **30 px sur 30 px**,
+ une porte unique au rez-de-chaussée de **30 px sur 50px**
+ trois positions possibles pour la porte
+ deux variations du toit au moins
+ au moins 4 couleurs de façade disponibles
