# But du projet

**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

Il faudra créer :

+ un module nommé ici **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é ici **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é ici **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

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)
    :: return (Turtle)      :: renvoie un objet de la classe Turtle

    '''
    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)
    :: return (Turtle)      :: renvoie un objet de la classe Turtle

    '''
    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

Ce module devra permettre de dessiner des immeubles précis ou aléatoires en utilisant le module **formes**.

### Exemples d'utilisation

#### Exemple 1 : Rue aléatoire

Une rue aléatoire :

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


#### Exemple 2 : Dessiner deux immeubles

Si on ne veut tracer que deux immeubles dont on précise les positions :

![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é".

### Exemples

Une manière de formuler parmi tant d'autres :

```
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

![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 :

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



# Quelques Précisions

## Un projet partagé

Ce projet est issu d'une idée originale d'**Adrien Wilm**, en 1er. Il s'agissait initialement de dessiner une rue en utilisant le module Turtle dans la partie "utilisation d'un module" du programme de 1er. Partagée sur la liste NSI, ce projet est arrivé jusqu'à moi et certainement jusqu'à d'autres dans l'assemblée.

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

## Une adaptation personnelle parmi d'autres

J'ai alors adapté le programme pour le réaliser en Terminale, dans le cadre de la partie Module.

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

## D'autres possibilités qui existent peut-être déjà ?

Mais, le projet évolue encore. On pourrait utiliser plusieurs formes du module **formes** : on pourrait par exemple faire tracer les formes via Pillow, non ?

```mermaid
graph TD;
  interpreteur-->rue;
  rue-->formes;
  formes-->Turtle;
  formes-->Pillow;
```
Ou alors créer plusieurs modules spécialisés du type **rue**.

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