Aller au contenu

Ecrire des exercices

Nous verrons ici des exemples d'utilisation de Pyodide et de puzzle.

I. Présentation des exercices avec IDE⚓︎

Vous trouverez dans les paragraphes suivants des modèles de syntaxes à copier. Il s'agit ici de présenter les différentes possibilités.

Un exemple complet:⚓︎

  • Cet exemple a été paramétré pour qu'au bout de 2 essais validés infructueux la réponse s'affiche.
  • Dès que l'élève a réussi (vérification dans le fichier exo_test.py caché), la solution s'affiche, ainsi que les remarques contenues dans le fichier exo_REM.md
Question

La fonction somme prend en paramètre une liste de nombres et renvoie la somme des nombres de cette liste

Compléter le script ci-dessous :

  • ⚠️ N'oubliez surtout pas de valider valider après avoir exécuté play

  • Dans cet exercice, vous avez droit à deux essais validés :
    Si les assert "ne passent pas", vous pouvez cliquer sur ### en haut à droite de la fenêtre avant de valider, pour que l'essai soit décompté. Au bout de deux essais validés, la solution s'affichera.

###
# Testsbksl-nlassert somme([]) == 0bksl-nlassert somme([5, 6, 7]) == 18bksl-nlbksl-nl 2/2
def somme(nombres):bksl-nl ...bksl-nlbksl-nlbksl-nl# Testsbksl-nlassert somme([1, 2, 3]) == 6bksl-nlbksl-nldef somme(nombres):bksl-nl resultat = 0bksl-nl for nbre in nombres:bksl-nl resultat = resultat + nbrebksl-nl return resultatbksl-nlbksl-nl


On aurait pu aussi utiliser la fonction sum

🐍 Script Python
def somme(nombres):
    return sum(nombres)

Les syntaxes (Source Vincent Bouillot)⚓︎

Attention

Les fichiers contenant le sujet, les tests, la correction et les remarques doivent se trouver dans un dossier scripts placé dans le même dossier que votre fichier .md courant.

Les noms des fichiers doivent respecter la normalisation suivante :

👉 Pour un exercice Python dont le code à compléter est dans le fichier mon_exo.py :

  • Le fichier de correction doit être nommé : mon_exo_corr.py
  • Le fichier de tests doit être nommé : mon_exo_test.py
  • Le fichier de remarques (facultatif) doit être nommé : mon_exo_REM.md (Ne pas oublier les majuscules)

Les différentes syntaxes à utiliser sont présentées ci-dessous, dans les différents onglets.

Les syntaxes

Markdown
{{ terminal() }}
Création d'un terminal vide. L'auto-complétion avec Tab et le rappel de l'historique (avec CtrlR ) sont possibles.

Markdown
{{ IDE() }}
Création d'un IDE vide, visuellement proche de Thonny. La zone de saisie se redimensionne automatiquement et autorise l'auto-complétion de type snippet avec AltSpace.

###

Markdown
{{ IDEv() }}
Cette commande crée un IDE vide, avec division verticale.

###

Markdown
{{ IDE('foo/bar/nom_de_fichier', MAX = 8, SANS = 'max,min') }}
  • Le fichier nom_de_fichier.py est chargée dans un IDE. Ce fichier doit être situé impérativement dans docs/scripts/foo/bar/.

  • MAX = 8 : indique le nombre maximal de tentatives de validation que l'élève peut effectuer. MAX = 1000 ou MAX = "+" permet de mettre ce nombre à l'infini. Valeur par défaut : MAX = 5 .

  • SANS = 'max,min' permet d'interdire l'utilisation des fonctions built-ins max et min.

Les IDE sont enregistrés à intervalle de temps régulier. Ils permettent également l'autocomplétion avec la combinaison de touches AltSpace.

###



Markdown
{{ IDEv('foo/bar/nom_de_fichier', MAX = 1000) }}
Cette commande charge le fichier nom_de_fichier dans un IDE avec division verticale. Le fichier doit être dans docs/scripts/foo/bar/.

###



II. A savoir⚓︎

Attention

Un exercice avec IDE doit absolument se trouver dans une admonition ???+ question

Attention

Il ne faut pas, dans la même admonition que celle qui contient un IDE, mettre une autre admonition (ni avant l'IDE, ni après l'IDE). L'IDE ne doit pas non plus se trouver dans une admonition imbriquée.

Cela pertuberait entre autres, l'admonition suivante, et l'affichage des remarques après résolution de l'exercice.

III. Exemple 1 avec un IDE, un fichier corr, un fichier test, mais pas de fichier REM⚓︎

Par défaut les élèves peuvent valider leur exercice 5 fois avant que la correction ne s'affiche.

Code à copier
???+ question "Exercice 1"

    Compléter le script ci-dessous (observer les `assert`):

    {{IDE('scripts/bonjour')}}
Exercice 1

Compléter le script ci-dessous (observer les assert):

###
# Testsbksl-nlassert accueil("Alice") == "Bonjour Alice"bksl-nlassert accueil("Bob") == "Bonjour Bob"bksl-nlbksl-nl# Autres testsbksl-nlassert accueil("fegrehjtyjtqfqsgeryryrfg") == "Bonjour fegrehjtyjtqfqsgeryryrfg"bksl-nlbksl-nlbksl-nl 5/5
def accueil(prenom):bksl-nl ...bksl-nlbksl-nl# Testsbksl-nlassert accueil("Alice") == "Bonjour Alice"bksl-nlassert accueil("Bob") == "Bonjour Bob"bksl-nlbksl-nlbksl-nldef accueil(prenom):bksl-nl return "Bonjour " + prenombksl-nlbksl-nlbksl-nl

📋 Texte
__ __

__ __

Fichiers utilisés pour cet exemple

bonjour.py
def accueil(prenom):
    ...

# Tests
assert accueil("Alice") == "Bonjour Alice"
assert accueil("Bob")  == "Bonjour Bob"
bonjour_corr.py
def accueil(prenom):
    return "Bonjour " + prenom
bonjour_test.py
# Tests
assert accueil("Alice") == "Bonjour Alice"
assert accueil("Bob")  == "Bonjour Bob"

# Autres tests
assert accueil("fegrehjtyjtqfqsgeryryrfg") == "Bonjour fegrehjtyjtqfqsgeryryrfg"

IV. Exemple 2 avec un IDE, un fichier corr, un fichier test, mais pas de fichier REM⚓︎

Dans cet exemple le fichier sujet en Python ne contient pas de ligne # Tests. Il n'y a pas d'essais décomptés dans ce cas-là, et l'élève peut ne jamais trouver la solution.

Code à copier
???+ question "Exercice 2"

    Compléter le script ci-dessous :

    {{IDE('scripts/construction')}}
Exercice 2

Compléter le script ci-dessous :

###
# Testsbksl-nlassert cents == [100 for k in range(10)]bksl-nlassert entiers == [k for k in range(1, 11)]bksl-nlbksl-nlbksl-nl 5/5
# un tableau cents en compréhension qui contient 10 entiers 100.bksl-nlcents = ...bksl-nlbksl-nl# un tableau entiers en compréhension qui contient les 10 entiers entre 1 et 10 compris.bksl-nlentiers = ...bksl-nlbksl-nlcents = [100 for k in range(10)]bksl-nlentiers = [k for k in range(1, 11)]bksl-nlbksl-nlbksl-nl

📋 Texte
__ __

__ __

Solution en clair mais repliée

On peut toujours mettre la solution "en clair" si on le désire, mais absolument en dehors de l'admonition ???+ question

Code à copier
??? success "Solution"

    ```python
    # un tableau cents en compréhension qui contient 10 entiers 100.
    cents = [100 for k in range(10)]

    # un tableau entiers en compréhension qui contient les 10 entiers entre 1 et 10 compris.
    entiers = [k for k in range(1, 11)]
    ```
Solution
🐍 Script Python
# un tableau cents en compréhension qui contient 10 entiers 100.
cents = [100 for k in range(10)]

# un tableau entiers en compréhension qui contient les 10 entiers entre 1 et 10 compris.
entiers = [k for k in range(1, 11)]

Fichiers utilisés pour cet exemple

construction.py
# un tableau cents en compréhension qui contient 10 entiers 100.
cents = ...

# un tableau entiers en compréhension qui contient les 10 entiers entre 1 et 10 compris.
entiers = ...
construction_corr.py
cents = [100 for k in range(10)]
entiers = [k for k in range(1, 11)]
construction_test.py
# Tests
assert cents == [100 for k in range(10)]
assert entiers == [k for k in range(1, 11)]

V. Exemple 3 avec un IDE, un fichier corr, un fichier test, et un fichier REM⚓︎

Dans cet exemple on a utilisé la syntaxe : MAX = 2. Les élèves pourront valider leur exercice 2 fois avant que la correction ne s'affiche.

Le code à copier pour cet exemple

😊 Le code à copier n'a pas été oublié. Il se trouve après le rendu de l'exemple

Exercice 3
  • La fonction est_pair prend en paramètre un entier.
  • Elle renvoie True s'il est pair, et False dans le cas contraire.

Compléter le script ci-dessous :

N'oubliez pas de valider après avoir exécuté.

###
# Testsbksl-nlassert estpy-undpair(2)bksl-nlassert estpy-undpair(2000)bksl-nlassert not estpy-undpair(1)bksl-nlassert not estpy-undpair(777)bksl-nlbksl-nl# Autres testsbksl-nlassert estpy-undpair(10py-strpy-str10)bksl-nlassert not estpy-undpair(10py-strpy-str10 + 1)bksl-nlassert estpy-undpair(0)bksl-nlbksl-nl 2/2
def estpy-undpair(nombre):bksl-nl ...bksl-nlbksl-nl# Testsbksl-nlassert estpy-undpair(2)bksl-nlassert estpy-undpair(2000)bksl-nlassert not estpy-undpair(1)bksl-nlassert not estpy-undpair(777)bksl-nlbksl-nlbksl-nldef estpy-undpair(nombre):bksl-nl return nombre % 2 == 0bksl-nlbksl-nlbksl-nl


Expression booléenne

Remarquons que nombre % 2 == 0 est une expression booléenne qui s'évalue à True ou False

Il est très maladroit d'écrire

🐍 Script Python
def est_pair(nombre):
    if nombre % 2 == 0:
        return True
    else:
        return False

Code à copier
???+ question "Exercice 3"

    * La fonction `est_pair` prend en paramètre un entier **différent de 0**. 
    * Elle renvoie `True` s'il est pair, et `False` dans le cas contraire.

    Compléter le script ci-dessous : 

    N'oubliez pas de valider après avoir exécuté.


    {{IDE('scripts/pair', MAX = 2)}}

Fichiers utilisés pour cet exemple

pair.py
def est_pair(nombre):
...

# Tests
assert est_pair(2)
assert est_pair(2000)
assert not est_pair(1)
assert not est_pair(777)
pair_corr.py
def est_pair(nombre):
return nombre % 2 == 0
pair_test.py
# Tests
assert est_pair(2)
assert est_pair(2000)
assert not est_pair(1)
assert not est_pair(777)

# Autres tests
assert est_pair(10**10)
assert not est_pair(10**10 + 1)
pair_REM.md
!!! info "Expression booléenne"

    Remarquons que `nombre % 2 == 0` est une expression booléenne qui s'évalue à `True` ou `False`

Il est **très maladroit** d'écrire

```python
def est_pair(nombre):
    if nombre % 2 == 0:
        return True
    else:
        return False
```

VI. Exemple 4 avec des "interdits" Python⚓︎

SANS

Dans cet exercice, nous allons utiliser la syntaxe SANS = "max, sorted, sort" pour interdire l'utilisation de max, ainsi que de sort ou sorted.

Le code à copier pour cet exemple

😊 Le code à copier n'a pas été oublié. Il se trouve après le rendu de l'exemple

Exercice :⚓︎

Écrire une fonction maximum :

  • prenant en paramètre une liste non vide de nombres : nombres
  • renvoyant le plus grand élément de cette liste.

Chacun des nombres utilisés est de type int ou float.

Contrainte

On interdit ici d'utiliser max, ainsi que sort ou sorted.

Exemples
🐍 Console Python
>>> maximum([98, 12, 104, 23, 131, 9])
131
>>> maximum([-27, 24, -3, 15])
24
Exercice 4

Compléter ci-dessous

###
# Testsbksl-nlassert maximum([98, 12, 104, 23, 131, 9]) == 131bksl-nlassert maximum([-27, 24, -3, 15]) == 24bksl-nlbksl-nl# Tests supplémentairesbksl-nlassert maximum([1, 2, 3, 4, 5]) == 5bksl-nlassert maximum([5, 4, 3, 2, 1]) == 5bksl-nlassert maximum([5, 5, 5]) == 5bksl-nlassert abs(maximum([5.01, 5.02, 5.0]) - 5.02) < 10py-strpy-str-6bksl-nlassert maximum([-5, -4, -3, -8, -6]) == -3bksl-nlassert maximum([1,2]) == 2bksl-nlbksl-nl 5/5
def maximum(nombres):bksl-nl ...bksl-nlbksl-nlbksl-nl# Testsbksl-nlassert maximum([98, 12, 104, 23, 131, 9]) == 131bksl-nlassert maximum([-27, 24, -3, 15]) == 24bksl-nlbksl-nldef maximum(nombres):bksl-nl maxi = nombres[0]bksl-nl for x in nombres:bksl-nl if x > maxi:bksl-nl maxi = xbksl-nl return maxibksl-nlbksl-nlbksl-nlbksl-nl


algorithme classique à connaître

Il s'agit d'une recherche de maximum classique. La liste étant non-vide, on initialise la variable maxi avec la première valeur de la liste.


Code à copier
Écrire une fonction `maximum` :

- prenant en paramètre une liste **non vide** de nombres : `nombres`
- renvoyant le plus grand élément de cette liste.

Chacun des nombres utilisés est de type `int` ou `float`.

!!! danger "Contrainte"

    On interdit ici d'utiliser `max`, ainsi que `sort` ou `sorted`.

???+ example "Exemples"

    ```pycon
    >>> maximum([98, 12, 104, 23, 131, 9])
    131
    >>> maximum([-27, 24, -3, 15])
    24
    ```
???+ question "Exercice 4"

    Compléter ci-dessous 


    {{ IDE('scripts/maximum', SANS = "max, sorted, sort") }}

Fichiers utilisés pour cet exemple

maximum.py
def maximum(nombres):
...

# Tests
assert maximum([98, 12, 104, 23, 131, 9]) == 131
assert maximum([-27, 24, -3, 15]) == 24
maximum_corr.py
def maximum(nombres):
    maxi = nombres[0]
    for x in nombres:
        if x > maxi:
            maxi = x
    return maxi
maximum_test.py
# Tests
assert maximum([98, 12, 104, 23, 131, 9]) == 131
assert maximum([-27, 24, -3, 15]) == 24

# Tests supplémentaires
assert maximum([1, 2, 3, 4, 5]) == 5
assert maximum([5, 4, 3, 2, 1]) == 5
assert maximum([5, 5, 5]) == 5
assert abs(maximum([5.01, 5.02, 5.0]) - 5.02) < 10**-6
assert maximum([-5, -4, -3, -8, -6]) == -3
assert maximum([1,2]) == 2
maximum_REM.md
!!! info "algorithme classique à connaître"

    Il s'agit d'une recherche de maximum classique. La liste étant non-vide, on initialise la variable `maxi` avec la première valeur de la liste.

VII. Exemple 5 avec du code caché dans le sujet en Python⚓︎

Code caché

Dans cet exemple le fichier sujet en Python contient une partie qui n'est pas visible par l'élève.

Ces lignes de codes sont située entre #--- HDR ---# et #--- HDR ---#.

Voir plus bas les fichiers utilisés dans cet exemple

Code à copier
???+ question "Exercice 5"

    Vous ignorez le rôle de la fonction `mystere`, et vous ne voyez pas son code.

    Vous allez donc utiliser la fonction `help` native en Python.

    Exécuter ci-dessous :


    {{IDE('scripts/mystere_code_cache')}}
Exercice 5

Vous ignorez le rôle de la fonction mystere, et vous ne voyez pas son code.

Vous allez donc utiliser la fonction help native en Python.

Exécuter ci-dessous :

###
#--- HDR ---#bksl-nlbksl-nldef mystere(nbre):bksl-nl """bksl-nl La fonction prend en paramètre un nombre entier.bksl-nl Elle renvoie True si ce nombre est un multiple de 7, False sinonbksl-nlbksl-nl >>> mystere(21)bksl-nl Truebksl-nl >>> mystere(22)bksl-nl Falsebksl-nlbksl-nl """bksl-nl return nbre % 7 == 0bksl-nlbksl-nl#--- HDR ---#bksl-nlbksl-nlhelp(mystere)bksl-nlbksl-nlbksl-nl



Fichiers utilisés pour cet exemple

mystere_code_cache.py
#--- HDR ---#

def mystere(nbre):
    """
    La fonction prend en paramètre un nombre entier.
    Elle renvoie True si ce nombre est un multiple de 7, False sinon

    >>> mystere(21)
    True
    >>> mystere(22)
    False

    """
    return nbre % 7 == 0

#--- HDR ---#

help(mystere)

Variante de cet exercice en utilisant la console⚓︎

Code à copier
???+ question "Exercice 5"

    Vous ignorez le rôle de la fonction `mystere`, et vous ne voyez pas son code.

    Vous allez donc utiliser la fonction `help` native en Python.

    Exécuter ci-dessous, puis dans la console qui apparaît (il s'affiche : %Script exécuté), recopier, puis ensuite cliquer sur la touche entrer pour exécuter :

    ```python
    help
    ```


    {{IDE('scripts/mystere_code_cache_bis')}}
Exercice 5

Vous ignorez le rôle de la fonction mystere, et vous ne voyez pas son code.

Vous allez donc utiliser la fonction help native en Python.

Exécuter ci-dessous, puis dans la console qui apparaît (il s'affiche : %Script exécuté), recopier, puis ensuite cliquer sur la touche entrer pour exécuter :

🐍 Script Python
help(mystere)

###
#--- HDR ---#bksl-nlbksl-nldef mystere(nbre):bksl-nl """bksl-nl La fonction prend en paramètre un nombre entier.bksl-nl Elle renvoie True si ce nombre est un multiple de 7, False sinonbksl-nlbksl-nl >>> mystere(21)bksl-nl Truebksl-nl >>> mystere(22)bksl-nl Falsebksl-nlbksl-nl """bksl-nl return nbre % 7 == 0bksl-nlbksl-nl#--- HDR ---#bksl-nlbksl-nl# La fonction mystere est cachée.bksl-nl# A vous d'en découvrir les spécificationsbksl-nlbksl-nlbksl-nlbksl-nl



Fichiers utilisés pour cet exemple

mystere_code_cache_bis.py
#--- HDR ---#

def mystere(nbre):
    """
    La fonction prend en paramètre un nombre entier.
    Elle renvoie True si ce nombre est un multiple de 7, False sinon

    >>> mystere(21)
    True
    >>> mystere(22)
    False

    """
    return nbre % 7 == 0

#--- HDR ---#

# La fonction mystere est cachée.
# A vous d'en découvrir les spécifications

VIII. Exemple 6 avec une plus grande fenêtre pour l'IDE⚓︎

Modifier la taille de l'IDE

Parfois on voudrait que l'IDE affiche un plus grand nombre de lignes.

Il suffit d'utiliser la syntaxe (pour 55 lignes par exemple) IDE('exo', SIZE=55)

Code à copier
???+ question "Exercice"

    Compléter le script ci-dessous :

    {{IDE('scripts/grand_IDE', SIZE=55)}}
Exercice

Compléter le script ci-dessous :

###
# Mon code avec plein de lignes devant être visiblesbksl-nlbksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nl# Ligne suivantebksl-nlbksl-nlbksl-nlbksl-nl

📋 Texte
__ __

__ __

IX. Les fichiers REM⚓︎

A savoir

Il ne faut pas mettre de titres #, ni ##, ni ###, ni #### dans un fichier REM. (Le fichier de remarque serait cliquable dans la barre de menu, avec potentiellement les explications en clair)

On peut séparer les différents paragraphes en les mettant dans des admonitions distinctes.

Affichage du fichier REM

  • Si le fichier de remarque s'affiche en dessous de l'exercice dès le début, c'est que l'IDE n'est pas dans une admoniton :
    ???+ question

  • Si le fichier de remarque ne s'affiche pas, c'est qu'il y a peut-être une autre admonition après l'IDE (par exemple une admonition ??? success "Solution") Il faudrait la sortir de l'admonition de l'exercice (supprimer l'indentation).

X. Exercice avec la réponse à chercher soi-même (avec un lien interne)⚓︎

La réponse est à chercher en suivant un lien

Code à copier
???+ question 

    Comment fait-on une admonition "note pliée" ?

    ??? success "Solution"

        Vous pouvez trouver la réponse ici : [admonitions](../2_basique/2_page_basique.md)

        On indique juste le nom du fichier s'il est dans le même dossier.
Question

Comment fait-on une admonition "note pliée" ?

Solution

Vous pouvez trouver la réponse ici : admonitions

On indique juste le nom du fichier s'il est dans le même dossier.

XI. Site de référence pour toutes les syntaxes⚓︎

Site de Vincent Bouillot

XII. Exemple de puzzle⚓︎

Site pour créer les puzzles : Création de puzzles

Cliquer sur le menu en haut à droite (plier/déplier) pour recopier le code à insérer.

Rendu :

La réponse attendue est cinq = [5 for k in range(20)]

Question