CONCEPTION ET ANALYSE D'UNE ACTIVITÉ INSTRUMENTÉE POUR LA DÉCOUVERTE DE LA NOTION DE PILE EN SPÉCIALITÉ NSI EN TERMINALE

Christophe Declercq, Sébastien Hoarau, Sophie Chane-Lune, Fabrice Nativel, Siméon Schroeder

► To cite this version:

Christophe Declercq, Sébastien Hoarau, Sophie Chane-Lune, Fabrice Nativel, Siméon Schroeder.
CONCEPTION ET ANALYSE D'UNE ACTIVITÉ INSTRUMENTÉE POUR LA DÉCOUVERTE
DE LA NOTION DE PILE EN SPÉCIALITÉ NSI EN TERMINALE. radix, 2024, 1. hal-04542331

HAL Id: hal-04542331

https://hal.science/hal-04542331

Submitted on 11 Apr 2024

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

<figure><img src="image_1.png" /></figure>

Distributed under a Creative Commons Attribution - ShareAlike 4.0 International License
DECLERCQ Christophe<fnref n="1" />

INSPE de l'académie de la Réunion, LIM, IREMI

HOARAU Sébastien<fnref n="2" />

UFR Sciences et Technologies, Université de la Réunion, LIM, IREMI

CHANE-LUNE Sophie<fnref n="3" />

Lycée Mémona Hintermann-Afféjee, IREMI de la Réunion

NATIVEL Fabrice<fnref n="4" />

Lycée Leconte de Lisle, IREMI de la Réunion

SCHROEDER Siméon<fnref n="5" />

Lycée Lislet Geoffroy, IREMI de la Réunion

**Résumé.** Nous proposons une activité instrumentée pour faire découvrir aux élèves la nécessité et le fonctionnement de la pile en spécialité NSI de la classe de terminale. Cette structure de données a de nombreux usages dont le plus caractéristique est la fonction *undo* telle qu'elle est mise en œuvre dans les logiciels d'édition de textes ou d'images. Nous proposons un jeu de recherche à résoudre en solitaire : le jeu de saute-mouton. Ce jeu a des règles de déplacements très simples, mais son déroulement amène à des situations de blocage où le joueur souhaiterait revenir en arrière pour tester un autre déplacement. Une mise en œuvre instrumentée permet d'effectuer l'activité en ligne à l'aide d'un navigateur, tout en recueillant les données d'apprentissage des élèves. Nous présentons tout d'abord une rapide analyse épistémologique et curriculaire, l'activité proposée, puis le cadre théorique de cette recherche, ses hypothèses et les expérimentations menées dans trois lycées de l'académie de La Réunion. Nous discutons ensuite les hypothèses à la lumière des expérimentations menées.

**Mots-clés.** Numérique et science informatique, analyse de traces, pile, ingénierie didactique.

**Abstract.** We provide a hands-on activity designed to familiarize students with the use-cases and operations of the stack data structure within the NSI specialty in 13th grade (classe terminale in France). The stack data structure serves various purposes, one of its most notable applications being the implementation of the undo function in text or image editing software. Our scientific experiment consist of a solitaire research game known as the leapfrog game. This game features straightforward movement rules, however its progression often leads to situations where players are facing obstacles, during which the players want to backtrack in order to test other movement. An instrumented implementation enables the activity to be conducted online via a browser, facilitating the collection of valuable student learning data. Our presentation begins with a brief epistemological and curricular analysis, followed by an exploration of the proposed activity, the theoretical framework underpinning this research, its hypotheses, and the experiments conducted in three high schools within the Réunion academy. In conclusion, we engage in a discussion evaluating the hypotheses in light of the experiments conducted.

**Keywords.** Computer science, high school, stack data structure, learning analytics.

<footnote n="1">¹ christophe.declercq@univ-reunion.fr</footnote>

<footnote n="2">² seb.hoarau@univ-reunion.fr</footnote>

<footnote n="3">³ Sophie.Chane-Lune@ac-reunion.fr</footnote>

<footnote n="4">⁴ Fabrice-Bernard.Nativel@ac-reunion.fr</footnote>

<footnote n="5">⁵ Simeon.Schroeder@ac-reunion.fr</footnote>
DECLERCQ Christophe<fnref n="1" />

INSPE de l'académie de la Réunion, LIM, IREMI

HOARAU Sébastien<fnref n="2" />

UFR Sciences et Technologies, Université de la Réunion, LIM, IREMI

CHANE-LUNE Sophie<fnref n="3" />

Lycée Mémona Hintermann-Afféjee, IREMI de la Réunion

NATIVEL Fabrice<fnref n="4" />

Lycée Leconte de Lisle, IREMI de la Réunion

SCHROEDER Siméon<fnref n="5" />

Lycée Lislet Geoffroy, IREMI de la Réunion

**Résumé.** Nous proposons une activité instrumentée pour faire découvrir aux élèves la nécessité et le fonctionnement de la pile en spécialité NSI de la classe de terminale. Cette structure de données a de nombreux usages dont le plus caractéristique est la fonction *undo* telle qu'elle est mise en œuvre dans les logiciels d'édition de textes ou d'images. Nous proposons un jeu de recherche à résoudre en solitaire : le jeu de saute-mouton. Ce jeu a des règles de déplacements très simples, mais son déroulement amène à des situations de blocage où le joueur souhaiterait revenir en arrière pour tester un autre déplacement. Une mise en œuvre instrumentée permet d'effectuer l'activité en ligne à l'aide d'un navigateur, tout en recueillant les données d'apprentissage des élèves. Nous présentons tout d'abord une rapide analyse épistémologique et curriculaire, l'activité proposée, puis le cadre théorique de cette recherche, ses hypothèses et les expérimentations menées dans trois lycées de l'académie de La Réunion. Nous discutons ensuite les hypothèses à la lumière des expérimentations menées.

**Mots-clés.** Numérique et science informatique, analyse de traces, pile, ingénierie didactique.

**Abstract.** We provide a hands-on activity designed to familiarize students with the use-cases and operations of the stack data structure within the NSI specialty in 13th grade (classe terminale in France). The stack data structure serves various purposes, one of its most notable applications being the implementation of the undo function in text or image editing software. Our scientific experiment consist of a solitaire research game known as the leapfrog game. This game features straightforward movement rules, however its progression often leads to situations where players are facing obstacles, during which the players want to backtrack in order to test other movement. An instrumented implementation enables the activity to be conducted online via a browser, facilitating the collection of valuable student learning data. Our presentation begins with a brief epistemological and curricular analysis, followed by an exploration of the proposed activity, the theoretical framework underpinning this research, its hypotheses, and the experiments conducted in three high schools within the Réunion academy. In conclusion, we engage in a discussion evaluating the hypotheses in light of the experiments conducted.

**Keywords.** Computer science, high school, stack data structure, learning analytics.

<footnote n="1">¹ christophe.declercq@univ-reunion.fr</footnote>

<footnote n="2">² seb.hoarau@univ-reunion.fr</footnote>

<footnote n="3">³ Sophie.Chane-Lune@ac-reunion.fr</footnote>

<footnote n="4">⁴ Fabrice-Bernard.Nativel@ac-reunion.fr</footnote>

<footnote n="5">⁵ Simeon.Schroeder@ac-reunion.fr</footnote>
# Introduction

La manipulation de structures de données - dont la pile - est un point difficile du programme de la spécialité Numérique et Science Informatique (NSI) en terminale (MENJ, 2019). L'idée initiale de ce travail a été de proposer une situation ludique, où la nécessité de gérer un historique des positions de jeu vient de la difficulté à résoudre le jeu de manière directe.

Une première expérimentation auprès de 14 élèves a permis d'obtenir de premiers résultats mais aussi de montrer quelques faiblesses de l'activité et de l'outil d'analyse des traces d'activité des élèves. Une deuxième version plus robuste a été construite à partir des observations précédentes, puis a été de nouveau expérimentée dans deux lycées auprès de 38 élèves de classe de terminale. Nous présentons d'abord une analyse des notions en jeu dans la littérature et dans les programmes scolaires, nos choix de mise en œuvre puis l'expérimentation et ses résultats.

L'activité est disponible en ligne à l'adresse :

https://iremi974.gitlab.io/python-de-la-fournaise/sautemouton.html

# Analyse épistémologique et curriculaire

La partie « Structures de données » du programme de terminale de la spécialité NSI comprend les contenus suivants, concernant la pile en tant que structure de données (extrait).

<table><thead><tr><td>Contenus</td><td>Capacités attendues</td><td>Commentaires</td></tr></thead><tbody><tr><td>Structures de données, interface et implémentation.</td><td>Spécifier une structure de données par son interface.<br/>Distinguer interface et implémentation.<br/>Écrire plusieurs implémentation d'une même structure de données.</td><td>L'abstraction des structures de données est introduite après plusieurs implémentation d'une structure simple comme la file (avec un tableau ou avec deux piles).</td></tr><tr><td>Listes, piles, files : structures linéaires.</td><td>Distinguer des structures par le jeu des méthodes qui les caractérisent.<br/>Choisir une structure de données adaptée à la situation à modéliser.</td><td>On distingue les modes FIFO (first in first out) et LIFO (last in first out) des piles et des files.</td></tr></tbody></table>

Il est à noter qu'il n'est pas fait référence au concept de « type abstrait de données » enseigné au niveau universitaire, ce que nous interprétons comme une nécessité de « transposition didactique » du savoir savant (Chevallard, 1991).

Le savoir savant concernant la pile en tant que type abstrait de données, tel qu'il est enseigné au niveau universitaire, figure par exemple à la page 74 de l'ouvrage (Froidevaux et al., 1990)

sorte Pile

utilise Booléen, Elément

opérations :

* pile-vide : → Pile

* empiler : Pile × Elément → Pile

* dépile : Pile → Pile

* sommet : Pile → Elément

* est-vide : Pile → Booléen
# Introduction

La manipulation de structures de données - dont la pile - est un point difficile du programme de la spécialité Numérique et Science Informatique (NSI) en terminale (MENJ, 2019). L'idée initiale de ce travail a été de proposer une situation ludique, où la nécessité de gérer un historique des positions de jeu vient de la difficulté à résoudre le jeu de manière directe.

Une première expérimentation auprès de 14 élèves a permis d'obtenir de premiers résultats mais aussi de montrer quelques faiblesses de l'activité et de l'outil d'analyse des traces d'activité des élèves. Une deuxième version plus robuste a été construite à partir des observations précédentes, puis a été de nouveau expérimentée dans deux lycées auprès de 38 élèves de classe de terminale. Nous présentons d'abord une analyse des notions en jeu dans la littérature et dans les programmes scolaires, nos choix de mise en œuvre puis l'expérimentation et ses résultats.

L'activité est disponible en ligne à l'adresse :

https://iremi974.gitlab.io/python-de-la-fournaise/sautemouton.html

# Analyse épistémologique et curriculaire

La partie « Structures de données » du programme de terminale de la spécialité NSI comprend les contenus suivants, concernant la pile en tant que structure de données (extrait).

<table><thead><tr><td>Contenus</td><td>Capacités attendues</td><td>Commentaires</td></tr></thead><tbody><tr><td>Structures de données, interface et implémentation.</td><td>Spécifier une structure de données par son interface.<br/>Distinguer interface et implémentation.<br/>Écrire plusieurs implémentation d'une même structure de données.</td><td>L'abstraction des structures de données est introduite après plusieurs implémentation d'une structure simple comme la file (avec un tableau ou avec deux piles).</td></tr><tr><td>Listes, piles, files : structures linéaires.</td><td>Distinguer des structures par le jeu des méthodes qui les caractérisent.<br/>Choisir une structure de données adaptée à la situation à modéliser.</td><td>On distingue les modes FIFO (first in first out) et LIFO (last in first out) des piles et des files.</td></tr></tbody></table>

Il est à noter qu'il n'est pas fait référence au concept de « type abstrait de données » enseigné au niveau universitaire, ce que nous interprétons comme une nécessité de « transposition didactique » du savoir savant (Chevallard, 1991).

Le savoir savant concernant la pile en tant que type abstrait de données, tel qu'il est enseigné au niveau universitaire, figure par exemple à la page 74 de l'ouvrage (Froidevaux et al., 1990)

sorte Pile

utilise Booléen, Elément

opérations :

pile-vide : → Pile

empiler : Pile × Elément → Pile

dépiler : Pile → Pile

sommet : Pile → Elément

est-vide : Pile → Booléen
Sachant qu'au niveau terminale, il est attendu seulement de distinguer interface et implémentation et de spécifier une structure de données par son interface, nous spécifions l'interface d'une pile par les fonctions suivantes :

`pile_vide()` : renvoie une pile vide

`empiler`(element, pile) : modifie pile en ajoutant element à son sommet

`depiler`(pile) : modifie pile en enlevant son sommet et renvoie cet élément

`est_vide`(pile) : renvoie True si et seulement si pile est vide.

Nous choisissons de spécifier les interfaces en Python, car aucun autre formalisme ni théorie de types n'est au programme du lycée. Nous choisissons aussi de donner des spécifications pour le paradigme impératif (ou objet), car les implémentations sont suggérées dans ces paradigmes : « Le paradigme de la programmation objet peut être utilisé pour réaliser des implémentations effectives des structures de données, même si ce n'est pas la seule façon de procéder. »

Avec le paradigme objet, nous donnons la spécification suivante d'une classe `Pile` :

`Pile()` : crée et renvoie une pile vide

`pile.empiler`(element) : modifie pile en ajoutant element à son sommet

`pile.depile`(pile) : modifie pile en enlevant son sommet et renvoie cet élément

`pile.est_vide()` : renvoie True si et seulement si pile est vide.

Sachant que la structure de données ne doit être introduite qu'après « plusieurs implémentation d'une structure simple », la première activité peut consister à découvrir l'idée de pile à partir de sa politique d'accès spécifique : dernier entré – premier sorti.

Nous avons choisi de faire implémenter aux élèves une pile, sans la nommer au préalable, et donc sans nommer ses méthodes, à partir des notions disponibles pour eux, à savoir les tableaux Python vus en première, complétés par les méthodes permettant de les revoir comme des listes en début de terminale.

L'activité de découverte que nous présentons et analysons dans cet article se situe au tout début de la progression suivante :

* Découverte de la notion de pile à partir d'une situation de type `UNDO`.

* Découverte de la notion de pile à partir d'une autre situation (évaluer une expression en notation polonaise inverse, vérifier le bon parenthésage...).

* Institutionnalisation de la notion de pile, par la spécification de son interface.

* Implémentation de la structure de données avec des listes Python.

* Implémentation de la structure de données en programmation objet.

Nous ne décrivons dans la suite que la première activité pour laquelle nous avons proposé une instrumentation spécifique.

Nous avons proposé par ailleurs une autre activité instrumentée pour permettre aux élèves de réutiliser une classe `Pile` fournie, pour concevoir et programmer un algorithme de construction de l'labrinthe, nécessitant de mémoriser le chemin parcouru via une pile.

Cette dernière activité est disponible à l'adresse :

https://iremi974.gitlab.io/python-de-la-fournaise/labyrinth.html
Sachant qu'au niveau terminale, il est attendu seulement de distinguer interface et implémentation et de spécifier une structure de données par son interface, nous spécifions l'interface d'une pile par les fonctions suivantes :

`pile_vide()` : renvoie une pile vide

`empiler`(element, pile) : modifie pile en ajoutant element à son sommet

`depiler`(pile) : modifie pile en enlevant son sommet et renvoie cet élément

`est_vide`(pile) : renvoie True si et seulement si pile est vide.

Nous choisissons de spécifier les interfaces en Python, car aucun autre formalisme ni théorie de types n'est au programme du lycée. Nous choisissons aussi de donner des spécifications pour le paradigme impératif (ou objet), car les implémentations sont suggérées dans ces paradigmes : « Le paradigme de la programmation objet peut être utilisé pour réaliser des implémentations effectives des structures de données, même si ce n'est pas la seule façon de procéder. »

Avec le paradigme objet, nous donnons la spécification suivante d'une classe `Pile` :

`Pile()` : crée et renvoie une pile vide

`pile.empiler`(element) : modifie pile en ajoutant element à son sommet

`pile.depiler()` : modifie pile en enlevant son sommet et renvoie cet élément

`pile.est_vide()` : renvoie True si et seulement si pile est vide.

Sachant que la structure de données ne doit être introduite qu'après « plusieurs implémentation d'une structure simple », la première activité peut consister à découvrir l'idée de pile à partir de sa politique d'accès spécifique : dernier entré – premier sorti.

Nous avons choisi de faire implémenter aux élèves une pile, sans la nommer au préalable, et donc sans nommer ses méthodes, à partir des notions disponibles pour eux, à savoir les tableaux Python vus en première, complétés par les méthodes permettant de les revoir comme des listes en début de terminale.

L'activité de découverte que nous présentons et analysons dans cet article se situe au tout début de la progression suivante :

* Découverte de la notion de pile à partir d'une situation de type UNDO.

* Découverte de la notion de pile à partir d'une autre situation (évaluer une expression en notation polonaise inverse, vérifier le bon parenthésage...).

* Institutionnalisation de la notion de pile, par la spécification de son interface.

* Implémentation de la structure de données avec des listes Python.

* Implémentation de la structure de données en programmation objet.

Nous ne décrivons dans la suite que la première activité pour laquelle nous avons proposé une instrumentation spécifique.

Nous avons proposé par ailleurs une autre activité instrumentée pour permettre aux élèves de réutiliser une classe `Pile` fournie, pour concevoir et programmer un algorithme de construction de l'labrinthe, nécessitant de mémoriser le chemin parcouru via une pile.

Cette dernière activité est disponible à l'adresse :

https://iremi974.gitlab.io/python-de-la-fournaise/labyrinth.html
# L'activité initiale

## Règles et déroulement du jeu de saute-mouton

Le jeu comporte sept cases alignées numérotées de 0 à 6, trois jetons moutons blancs et trois jetons moutons noirs. Les moutons blancs (resp. noirs) peuvent se déplacer vers la droite (resp. gauche) vers une case vide ou en sautant par dessus un mouton noir (resp. blanc). L'objectif est d'inverser les moutons blancs et les moutons noirs (voir figure 1).

## Activité : Jeu de saute-mouton

### Règle du jeu :

Les moutons blancs peuvent se déplacer vers la droite vers une case vide ou en sautant par dessus un mouton noir.

Les moutons noirs peuvent se déplacer vers la gauche vers une case vide ou en sautant par dessus un mouton blanc.

Emmène tous les moutons blancs à droite et tous les moutons noirs à gauche.

Si tu es bloqué, essaie le bouton **UNDO** ! Si son fonctionnement ne te convient pas, modifie le programme pour que le bouton **UNDO** permette de revenir à la configuration précédente.

```python
jeu = ['blanc', 'blanc', 'blanc', 'vide', 'noir', 'noir', 'noir']
historique = []
```

```python
def saute(i):
    if jeu[i] == 'blanc' and i<6 and jeu[i+1] == 'vide':
        jeu[i], jeu[i+1] = 'vide', 'blanc'
    elif jeu[i] == 'blanc' and i<5 and jeu[i+1] == 'noir' and jeu[i+2] == 'vide':
        jeu[i], jeu[i+2] = 'vide', 'blanc'
    elif jeu[i] == 'noir' and i>0 and jeu[i-1] == 'vide':
        jeu[i], jeu[i-1] = 'vide', 'noir'
    elif jeu[i] == 'noir' and i>1 and jeu[i-1] == 'blanc' and jeu[i-2] == 'vide':
        jeu[i], jeu[i-2] = 'vide', 'noir'

def undo():
    global jeu
    jeu = ['blanc', 'blanc', 'blanc', 'vide', 'noir', 'noir', 'noir']
```

<figure><img src="image_1.png" /><figcaption>**Figure 1 :** Interface initiale du jeu de saute-mouton.</figcaption></figure>

L'interface proposée montre un code d'initialisation non modifiable (variables jeu et historique) et le code modifiable de deux fonctions. La fonction saute est appelée à chaque clic sur une case du jeu et permet de déplacer le mouton qui se trouve sur cette case si le déplacement est autorisé. La fonction undo est appelée à chaque clic sur le bouton UNDO et est programmée de manière naïve en ramenant directement à la position initiale.

Notons que l'ensemble du code peut aussi être recopié dans un éditeur de programme et testé simplement avec la console python, par exemple avec la suite d'appels suivante :
# L'activité initiale

## Règles et déroulement du jeu de saute-mouton

Le jeu comporte sept cases alignées numérotées de 0 à 6, trois jetons moutons blancs et trois jetons moutons noirs. Les moutons blancs (resp. noirs) peuvent se déplacer vers la droite (resp. gauche) vers une case vide ou en sautant par dessus un mouton noir (resp. blanc). L'objectif est d'inverser les moutons blancs et les moutons noirs (voir figure 1).

## Activité : Jeu de saute-mouton

### Règle du jeu :

Les moutons blancs peuvent se déplacer vers la droite vers une case vide ou en sautant par dessus un mouton noir.

Les moutons noirs peuvent se déplacer vers la gauche vers une case vide ou en sautant par dessus un mouton blanc.

Emmène tous les moutons blancs à droite et tous les moutons noirs à gauche.

Si tu es bloqué, essaie le bouton **UNDO** ! Si son fonctionnement ne te convient pas, modifie le programme pour que le bouton **UNDO** permette de revenir à la configuration précédente.

```
jeu = ['blanc', 'blanc', 'blanc', 'vide', 'noir', 'noir', 'noir']
historique = []
```

```python
def saute(i):
    if jeu[i] == 'blanc' and i<6 and jeu[i+1] == 'vide':
        jeu[i], jeu[i+1] = 'vide', 'blanc'
    elif jeu[i] == 'blanc' and i<5 and jeu[i+1] == 'noir' and jeu[i+2] == 'vide':
        jeu[i], jeu[i+2] = 'vide', 'blanc'
    elif jeu[i] == 'noir' and i>0 and jeu[i-1] == 'vide':
        jeu[i], jeu[i-1] = 'vide', 'noir'
    elif jeu[i] == 'noir' and i>1 and jeu[i-1] == 'blanc' and jeu[i-2] == 'vide':
        jeu[i], jeu[i-2] = 'vide', 'noir'

def undo():
    global jeu
    jeu = ['blanc', 'blanc', 'blanc', 'vide', 'noir', 'noir', 'noir']
```

<figure><img src="image_2.png" /><figcaption>**Figure 1 :** Interface initiale du jeu de saute-mouton.</figcaption></figure>

L'interface proposée montre un code d'initialisation non modifiable (variables jeu et historique) et le code modifiable de deux fonctions. La fonction saute est appelée à chaque clic sur une case du jeu et permet de déplacer le mouton qui se trouve sur cette case si le déplacement est autorisé. La fonction undo est appelée à chaque clic sur le bouton UNDO et est programmée de manière naïve en ramenant directement à la position initiale.

Notons que l'ensemble du code peut aussi être recopié dans un éditeur de programme et testé simplement avec la console python, par exemple avec la suite d'appels suivante :
saute(2)
saute(4)
saute(3)
saute(1)
jeu
undo()

À l'issue des quatre premiers mouvements, nous arrivons à une situation de blocage caractéristique avec la variable jeu à ['blanc', 'vide', 'noir', 'blanc', 'blanc', 'noir', 'noir'] où deux moutons blancs font face à deux moutons noirs sans qu'aucun ne puisse plus avancer.

C'est la situation déclenchante qui va permettre de réfléchir à la nécessité d'un retour arrière avec la fonction undo. L'interface et les parties de code qui ne sont pas montrées à l'élève ne sont utiles que pour fournir un retour instrumental plus élaboré. Après chaque mouvement, la visualisation graphique est recalculée à partir des nouvelles valeurs contenues dans le tableau jeu.

## Analyse a priori de l'activité

Le bouton UNDO, tel qu'il est programmé initialement, a un comportement trop radical puisqu'il ramène à la configuration initiale. La réflexion sur le besoin de revenir seulement à la configuration précédente devrait amener les élèves à construire la nécessité d'une variable mémorisant cette configuration précédente.

Dans un premier temps, une variable peut effectivement suffire, reste à savoir quand l'initialiser - avant de jouer un coup - et quand utiliser la valeur mémorisée - au clic sur le bouton UNDO - pour remettre dans le tableau jeu, la configuration mémorisée.

Cette première étape peut être utile dans la résolution du problème initial et amènera alors à un obstacle quand, lors d'une partie de jeu, le joueur s'apercevra qu'il a besoin de revenir en arrière de plus d'un mouvement.

Se pose alors inductivement la question de la mémorisation de deux, trois puis de tous les mouvements depuis le début du jeu. C'est là que les élèves ont besoin de réfléchir sur le moment où ils risquent d'avoir besoin des valeurs mémorisées. Le premier appel de la fonction undo a besoin de la dernière valeur mémorisée, le second de la précédente...

La présence dans le programme fourni, de la variable historique, initialisée en tant que liste vide, est prévue pour inciter à l'usage de cette liste pour y mémoriser les configurations successives du jeu. Il ne reste plus qu'à fournir aux élèves les méthodes d'accès pour ajouter en fin de liste append, et retirer un élément à cette même fin de liste pop, pour leur permettre de réussir l'activité.

L'institutionnalisation prendra soin de préciser qu'on appelle « pile » cette manière particulière de mémoriser une série de données, lorsque la dernière à ajouter - à empiler - doit être la première à retirer - à dépile.

Plusieurs solutions peuvent être imaginées pour enregistrer l'historique, l'historique des coups joués - [2, 4, 3, 1] dans notre exemple - ou l'historique des configurations du jeu. Chaque solution a ses avantages et ses inconvénients : l'historique des coups est une structure de données plus élémentaire mais nécessite le calcul des configurations ; l'historique des configurations est une liste (pile) de tableaux, ce qui nécessite en Python des précautions pour éviter les alias.

Une aide peut être fournie en précisant qu'il convient de faire une copie dans l'historique, de la configuration de jeu actuelle, pour éviter que cette mémorisation ne soit modifiée lors de la suite du déroulement du jeu.
saute(2)
saute(4)
saute(3)
saute(1)
jeu
undo()

À l'issue des quatre premiers mouvements, nous arrivons à une situation de blocage caractéristique avec la variable jeu à ['blanc', 'vide', 'noir', 'blanc', 'blanc', 'noir', 'noir'] où deux moutons blancs font face à deux moutons noirs sans qu'aucun ne puisse plus avancer.

C'est la situation déclenchante qui va permettre de réfléchir à la nécessité d'un retour arrière avec la fonction undo. L'interface et les parties de code qui ne sont pas montrées à l'élève ne sont utiles que pour fournir un retour instrumental plus élaboré. Après chaque mouvement, la visualisation graphique est recalculée à partir des nouvelles valeurs contenues dans le tableau jeu.

## Analyse a priori de l'activité

Le bouton UNDO, tel qu'il est programmé initialement, a un comportement trop radical puisqu'il ramène à la configuration initiale. La réflexion sur le besoin de revenir seulement à la configuration précédente devrait amener les élèves à construire la nécessité d'une variable mémorisant cette configuration précédente.

Dans un premier temps, une variable peut effectivement suffire, reste à savoir quand l'initialiser - avant de jouer un coup - et quand utiliser la valeur mémorisée - au clic sur le bouton UNDO - pour remettre dans le tableau jeu, la configuration mémorisée.

Cette première étape peut être utile dans la résolution du problème initial et amènera alors à un obstacle quand, lors d'une partie de jeu, le joueur s'apercevra qu'il a besoin de revenir en arrière de plus d'un mouvement.

Se pose alors inductivement la question de la mémorisation de deux, trois puis de tous les mouvements depuis le début du jeu. C'est là que les élèves ont besoin de réfléchir sur le moment où ils risquent d'avoir besoin des valeurs mémorisées. Le premier appel de la fonction undo a besoin de la dernière valeur mémorisée, le second de la précédente...

La présence dans le programme fourni, de la variable historique, initialisée en tant que liste vide, est prévue pour inciter à l'usage de cette liste pour y mémoriser les configurations successives du jeu. Il ne reste plus qu'à fournir aux élèves les méthodes d'accès pour ajouter en fin de liste append, et retirer un élément à cette même fin de liste pop, pour leur permettre de réussir l'activité.

L'institutionnalisation prendra soin de préciser qu'on appelle « pile » cette manière particulière de mémoriser une série de données, lorsque la dernière à ajouter - à empiler - doit être la première à retirer - à dépile.

Plusieurs solutions peuvent être imaginées pour enregistrer l'historique, l'historique des coups joués - [2, 4, 3, 1] dans notre exemple - ou l'historique des configurations du jeu. Chaque solution a ses avantages et ses inconvénients : l'historique des coups est une structure de données plus élémentaire mais nécessite le calcul des configurations ; l'historique des configurations est une liste (pile) de tableaux, ce qui nécessite en Python des précautions pour éviter les alias.

Une aide peut être fournie en précisant qu'il convient de faire une copie dans l'historique, de la configuration de jeu actuelle, pour éviter que cette mémorisation ne soit modifiée lors de la suite du déroulement du jeu.
## Correction de l'activité

Parmi les solutions possibles, nous proposons la suivante, en tant que corrigé :

```python
def saute(i):
    historique.append(jeu.copy())
    if jeu[i] == 'blanc' and i<6 and jeu[i+1] == 'vide':
        jeu[i], jeu[i+1] = 'vide', 'blanc'
    elif jeu[i] == 'blanc' and i<5 and jeu[i+1] == 'noir' and jeu[i+2] == 'vide':
        jeu[i], jeu[i+2] = 'vide', 'blanc'
    elif jeu[i] == 'noir' and i>0 and jeu[i-1] == 'vide':
        jeu[i], jeu[i-1] = 'vide', 'noir'
    elif jeu[i] == 'noir' and i>1 and jeu[i-1] == 'blanc' and jeu[i-2] == 'vide':
        jeu[i], jeu[i-2] = 'vide', 'noir'
    else:
        historique.pop()

def undo():
    global jeu
    jeu = historique.pop()
```

Nous avons choisi ici de mémoriser les configurations et de réaliser la pile par les méthodes append et pop des listes. Le choix d'empiler systématiquement la configuration précédente, avant de tester si le coup est jouable, peut amener à empiler une configuration identique à la précédente. C'est la raison de la correction proposée ici, consistant à dépiler dans le *else* une configuration empilée inutilement. Une solution plus élémentaire consisterait à empiler uniquement dans les alternatives quand le coup est jouable. Cette réflexion est marginale et n'est bien sûr pas exigible des élèves. Si on omet le *else*, l'historique sera seulement un peu plus long (avec des configurations répétées) de même que la suite des appels à la fonction undo.

L'essentiel réside dans la compréhension du mécanisme : si la mémorisation de l'historique a bien été effectuée lors du jeu, la fonction undo consiste à dépiler la dernière configuration mémorisée pour la remettre en jeu.

## Remarque sur l'utilisation de variables globales et sur les données mutables

L'indication de variable globale pour jeu est fournie pour éviter un problème dû à la spécificité des variables mutables en Python associée à la déclaration automatique des variables à leur première affectation. Si on l'omet, en particulier dans la fonction undo, c'est une nouvelle variable locale qui est créée sans rapport avec la variable globale définie à l'initialisation et utilisée dans la fonction saute. Cette organisation logicielle est aussi adaptée aux paradigmes de programmation choisi. Dans l'environnement logiciel en ligne proposé, les fonctions saute et undo, sont utilisées en programmation événementielle, chacune étant associée à un bouton ou à un objet (case avec un mouton) de l'interface. La programmation événementielle incite à la manipulation d'objets globaux via les éléments de l'interface. Ces mêmes fonctions peuvent aussi être utilisées en programmation impérative directement depuis une console Python.

Le choix d'utiliser des variables globales, dans la partie de code fournie par l'enseignant, en exception aux consignes données habituellement aux élèves, est volontaire pour éviter d'aborder deux difficultés simultanément, la découverte d'une nouvelle structure de données et le passage de paramètres avec des structures de données mutables en Python. Ce dernier problème n'a en effet rien à voir avec la notion de pile et peut être abordé séparément. Le problème de l'aliasing peut survenir lors de la construction de listes de listes. Pour l'éviter, l'aide fournie recommande de recopier le jeu avant de le placer dans l'historique. En cas d'oubli de recopie, le retour instrumental fourni lors de la seconde expérimentation, permet de visualiser le caractère erroné des informations mémorisées.
## Correction de l'activité

Parmi les solutions possibles, nous proposons la suivante, en tant que corrigé :

```python
def saute(i):
    historique.append(jeu.copy())
    if jeu[i] == 'blanc' and i<6 and jeu[i+1] == 'vide':
        jeu[i], jeu[i+1] = 'vide', 'blanc'
    elif jeu[i] == 'blanc' and i<5 and jeu[i+1] == 'noir' and jeu[i+2] == 'vide':
        jeu[i], jeu[i+2] = 'vide', 'blanc'
    elif jeu[i] == 'noir' and i>0 and jeu[i-1] == 'vide':
        jeu[i], jeu[i-1] = 'vide', 'noir'
    elif jeu[i] == 'noir' and i>1 and jeu[i-1] == 'blanc' and jeu[i-2] == 'vide':
        jeu[i], jeu[i-2] = 'vide', 'noir'
    else:
        historique.pop()

def undo():
    global jeu
    jeu = historique.pop()
```

Nous avons choisi ici de mémoriser les configurations et de réaliser la pile par les méthodes append et pop des listes. Le choix d'empiler systématiquement la configuration précédente, avant de tester si le coup est jouable, peut amener à empiler une configuration identique à la précédente. C'est la raison de la correction proposée ici, consistant à dépiler dans le *else* une configuration empilée inutilement. Une solution plus élémentaire consisterait à empiler uniquement dans les alternatives quand le coup est jouable. Cette réflexion est marginale et n'est bien sûr pas exigible des élèves. Si on omet le *else*, l'historique sera seulement un peu plus long (avec des configurations répétées) de même que la suite des appels à la fonction undo.

L'essentiel réside dans la compréhension du mécanisme : si la mémorisation de l'historique a bien été effectuée lors du jeu, la fonction undo consiste à dépiler la dernière configuration mémorisée pour la remettre en jeu.

## Remarque sur l'utilisation de variables globales et sur les données mutables

L'indication de variable globale pour jeu est fournie pour éviter un problème dû à la spécificité des variables mutables en Python associée à la déclaration automatique des variables à leur première affectation. Si on l'omet, en particulier dans la fonction undo, c'est une nouvelle variable locale qui est créée sans rapport avec la variable globale définie à l'initialisation et utilisée dans la fonction saute. Cette organisation logicielle est aussi adaptée aux paradigmes de programmation choisi. Dans l'environnement logiciel en ligne proposé, les fonctions saute et undo, sont utilisées en programmation événementielle, chacune étant associée à un bouton ou à un objet (case avec un mouton) de l'interface. La programmation événementielle incite à la manipulation d'objets globaux via les éléments de l'interface. Ces mêmes fonctions peuvent aussi être utilisées en programmation impérative directement depuis une console Python.

Le choix d'utiliser des variables globales, dans la partie de code fournie par l'enseignant, en exception aux consignes données habituellement aux élèves, est volontaire pour éviter d'aborder deux difficultés simultanément, la découverte d'une nouvelle structure de données et le passage de paramètres avec des structures de données mutables en Python. Ce dernier problème n'a en effet rien à voir avec la notion de pile et peut être abordé séparément. Le problème de l'aliasing peut survenir lors de la construction de listes de listes. Pour l'éviter, l'aide fournie recommande de recopier le jeu avant de le placer dans l'historique. En cas d'oubli de recopie, le retour instrumental fourni lors de la seconde expérimentation, permet de visualiser le caractère erroné des informations mémorisées.
# Protocole de recherche et résultats de la première expérimentation

## Problématique de recherche

Nous nous situons dans le double cadre de la théorie des situations didactiques (Brousseau, 1998) et de l'approche instrumentale (Rabardel, 1995) (Nijimbere, 2013) pour analyser la situation et l'activité des élèves. Par rapport à l'utilisation de jeux pour l'apprentissage, il convient de se positionner par rapport au risque de « détruire le ludique au profit du sérieux éducatif » (Brougère, 2018). Dans le domaine de l'apprentissage de l'informatique, une posture spécifique est possible, qui consiste non pas à « ludifier » un apprentissage, mais à prendre un jeu en tant qu'objet d'étude et à étudier ses propriétés intrinsèques pour en programmer une version informatique ou une stratégie gagnante. C'est dans cette perspective que notre travail se situe dans la lignée de celui de Meyer et Modeste (Meyer & Modeste, 2020) (Meyer & Modeste, 2022), avec comme principale différence que nous proposons une situation instrumentée.

Notre approche se veut aussi résolument constructiviste. Il n'est pas question pour nous de révéler d'emblée le savoir savant concernant un type abstrait pile, mais de faire découvrir aux élèves l'essence de cette structure de données à partir de sa politique d'accès spécifique : dernier entré – premier sorti, dans une situation porteuse de sens.

Nos hypothèses de recherche sont les suivantes :

* Une situation ludique, de type jeu de solitaire, est de nature à engager les élèves dans l'activité.

* La difficulté de trouver directement la solution encourage à améliorer le jeu en programmant le bouton UNDO.

* La situation est signifiante par rapport à l'usage de la pile et est candidate pour être considérée comme une situation fondamentale.

## Recueil des traces d'exécution

Pour pouvoir mesurer, les temps de jeu et les temps de programmation, enregistrer les réussites des élèves par rapport au jeu et par rapport à la programmation et tenter de comprendre a posteriori leur cheminement, nous avons décidé d'enregistrer toutes les interactions de l'élève avec l'activité proposée.

Les logs d'activité consistent en un horodatage de toutes les actions sur l'interface du jeu (voir un exemple en annexe 2). Les actions comprennent d'abord les déplacements de moutons qui sont notées coup 0 à coup 6 et les actions sur le bouton UNDO. À chaque action est mémorisée son heure, la configuration du jeu, la valeur de la variable historique et si le programme a été modifié depuis la dernière action, le texte du programme. Pour pouvoir mesurer le temps de jeu et le temps de programmation, nous considérons comme temps de programmation, tous les temps précédant un moment où le programme a été modifié. À la lecture des logs, nous constatons en effet pendant les phases de jeu, des actions très rapprochées, puis des longues périodes sans interaction avant modification du programme que nous assimilons à des temps de réflexion et de programmation.

## Analyse de la première expérimentation et préconisations

L'activité a été testée pour la première fois avec une classe de spécialité NSI de terminale du lycée Lislet Geoffroy au mois de mai 2022. Le groupe comportait 14 élèves.

L'activité s'est déroulée selon le protocole décrit en annexe 1. L'enseignant a laissé les élèves en autonomie et a récolté les logs d'activité à l'issue de la séance qui a duré environ 50mn. Les résultats bruts de l'analyse des logs figurent en annexe 3.
# Protocole de recherche et résultats de la première expérimentation

## Problématique de recherche

Nous nous situons dans le double cadre de la théorie des situations didactiques (Brousseau, 1998) et de l'approche instrumentale (Rabardel, 1995) (Nijimbere, 2013) pour analyser la situation et l'activité des élèves. Par rapport à l'utilisation de jeux pour l'apprentissage, il convient de se positionner par rapport au risque de « détruire le ludique au profit du sérieux éducatif » (Brougère, 2018). Dans le domaine de l'apprentissage de l'informatique, une posture spécifique est possible, qui consiste non pas à « ludifier » un apprentissage, mais à prendre un jeu en tant qu'objet d'étude et à étudier ses propriétés intrinsèques pour en programmer une version informatique ou une stratégie gagnante. C'est dans cette perspective que notre travail se situe dans la lignée de celui de Meyer et Modeste (Meyer & Modeste, 2020) (Meyer & Modeste, 2022), avec comme principale différence que nous proposons une situation instrumentée.

Notre approche se veut aussi résolument constructiviste. Il n'est pas question pour nous de révéler d'emblée le savoir savant concernant un type abstrait pile, mais de faire découvrir aux élèves l'essence de cette structure de données à partir de sa politique d'accès spécifique : dernier entré – premier sorti, dans une situation porteuse de sens.

Nos hypothèses de recherche sont les suivantes :

* Une situation ludique, de type jeu de solitaire, est de nature à engager les élèves dans l'activité.

* La difficulté de trouver directement la solution encourage à améliorer le jeu en programmant le bouton UNDO.

* La situation est signifiante par rapport à l'usage de la pile et est candidate pour être considérée comme une situation fondamentale.

## Recueil des traces d'exécution

Pour pouvoir mesurer, les temps de jeu et les temps de programmation, enregistrer les réussites des élèves par rapport au jeu et par rapport à la programmation et tenter de comprendre a posteriori leur cheminement, nous avons décidé d'enregistrer toutes les interactions de l'élève avec l'activité proposée.

Les logs d'activité consistent en un horodatage de toutes les actions sur l'interface du jeu (voir un exemple en annexe 2). Les actions comprennent d'abord les déplacements de moutons qui sont notées coup 0 à coup 6 et les actions sur le bouton UNDO. À chaque action est mémorisée son heure, la configuration du jeu, la valeur de la variable historique et si le programme a été modifié depuis la dernière action, le texte du programme. Pour pouvoir mesurer le temps de jeu et le temps de programmation, nous considérons comme temps de programmation, tous les temps précédant un moment où le programme a été modifié. À la lecture des logs, nous constatons en effet pendant les phases de jeu, des actions très rapprochées, puis des longues périodes sans interaction avant modification du programme que nous assimilons à des temps de réflexion et de programmation.

## Analyse de la première expérimentation et préconisations

L'activité a été testée pour la première fois avec une classe de spécialité NSI de terminale du lycée Lislet Geoffroy au mois de mai 2022. Le groupe comportait 14 élèves.

L'activité s'est déroulée selon le protocole décrit en annexe 1. L'enseignant a laissé les élèves en autonomie et a récolté les logs d'activité à l'issue de la séance qui a duré environ 50mn. Les résultats bruts de l'analyse des logs figurent en annexe 3.
Nous constatons que les temps d'activité des élèves varient entre 31 mn et 55 mn. Les temps les plus courts correspondent à une mise en route tardive, les plus longs à des débordements sur la pause inter-cours. Nous excluons ici de l'analyse l'élève LLG006 dont une partie de la session n'a pas été enregistrée suite à un arrêt de l'ordinateur.

Nous relevons une variation importante des temps de jeu et de programmation. Le temps de jeu varie de 5 mn pour l'élève LLG002 à 40 mn pour l'élève LLG007. Le temps de programmation varie de 3 mn pour l'élève LLG007 à 46 mn pour l'élève LLG101.

9 élèves sur 14 ont réussi le jeu en un temps variant entre 1 mn et 17 mn. Les 5 qui ont arrêté de jouer avant de gagner, figurent aussi parmi ceux qui ont passé le plus de temps à programmer. Nous pouvons supposer que pour eux la difficulté du jeu ait constitué une motivation pour programmer la fonction undo. Ceci est cependant contredit par le témoignage d'un élève (ayant réussi) : « le jeu est trop facile, pas besoin de programmer ».

L'engagement des élèves dans l'activité peut être évalué par le nombre d'interactions avec le système qui varie de 167 coups joués à 510.

## Analyse de la partie programmation

Concernant la programmation, nous avons analysé principalement le dernier programme réalisé par chacun et codifié en 5 catégories :

- pas de programmation (pas de différence notable avec le programme donné) : 5 élèves

- programmation incohérente (impossibilité de comprendre l'intention du programmeur) : 4 élèves

- historique un coup (enregistrement du seul coup précédent) : 2 élèves

- historique sans copie du jeu (enregistrement de l'historique avec append mais sans copie du jeu ce qui, avec les alias, donne un historique comportant n fois le même jeu) : 2 élèves

- réussite : 1 élève.

Ce résultat plutôt décevant – 1 seule réussite et 4 réussites partielles – nous a amené à revoir certaines caractéristiques de l'activité. En particulier pour les 4 ayant seulement réussi partiellement, l'analyse détaillée des logs montre un début de construction de l'historique comportant des erreurs dues à l'absence de copie ou à un mauvais choix de l'information à mémoriser. Le problème est que ces élèves n'ont pas « vu » leurs erreurs, ce qui peut expliquer qu'ils ne les aient pas corrigées. Cette absence de « retour instrumental » est préjudiciable aux apprentissages, car l'élève ne peut pas apprendre de ses erreurs. Nous en déduisons que l'activité devrait visualiser en permanence la valeur de la variable historique, ce qui a été fait dans la version suivante. Nous notons aussi, en particulier dans les productions jugées incohérentes, un usage hasardeux des listes et des méthodes qui s'y appliquent. Nous proposons de fournir une aide comportant des explications sur les méthodes pouvant être utilisées.

## Analyse de l'ergonomie de l'interface et du recueil de données

Au début du jeu, la fonction undo ramène à la position initiale, ce qui a été largement utilisé en particulier par les joueurs les plus téméraires. Mais dès que la fonction undo est modifiée, il n'y a plus d'autre moyen pour revenir à la situation initiale que de recharger la page. Cette possibilité a été utilisée et entraîne une réinitialisation du programme de l'élève à sa valeur par défaut.

Ceci constitue un défaut de l'interface, qui a fait perdre du temps aux élèves qui ont testé leur programme en cours de modification et se sont ensuite retrouvés bloqués.

Ceci entraîne de plus une difficulté supplémentaire pour l'analyse de l'activité à partir des logs, car ce qui se passe en dehors du navigateur – copie et modification du programme dans un éditeur – ne peut être capturé par les logs.
Nous constatons que les temps d'activité des élèves varient entre 31 mn et 55 mn. Les temps les plus courts correspondent à une mise en route tardive, les plus longs à des débordements sur la pause inter-cours. Nous excluons ici de l'analyse l'élève LLG006 dont une partie de la session n'a pas été enregistrée suite à un arrêt de l'ordinateur.

Nous relevons une variation importante des temps de jeu et de programmation. Le temps de jeu varie de 5 mn pour l'élève LLG002 à 40 mn pour l'élève LLG007. Le temps de programmation varie de 3 mn pour l'élève LLG007 à 46 mn pour l'élève LLG101.

9 élèves sur 14 ont réussi le jeu en un temps variant entre 1 mn et 17 mn. Les 5 qui ont arrêté de jouer avant de gagner, figurent aussi parmi ceux qui ont passé le plus de temps à programmer. Nous pouvons supposer que pour eux la difficulté du jeu ait constitué une motivation pour programmer la fonction undo. Ceci est cependant contredit par le témoignage d'un élève (ayant réussi) : « le jeu est trop facile, pas besoin de programmer ».

L'engagement des élèves dans l'activité peut être évalué par le nombre d'interactions avec le système qui varie de 167 coups joués à 510.

## Analyse de la partie programmation

Concernant la programmation, nous avons analysé principalement le dernier programme réalisé par chacun et codifié en 5 catégories :

- pas de programmation (pas de différence notable avec le programme donné) : 5 élèves

- programmation incohérente (impossibilité de comprendre l'intention du programmeur) : 4 élèves

- historique un coup (enregistrement du seul coup précédent) : 2 élèves

- historique sans copie du jeu (enregistrement de l'historique avec append mais sans copie du jeu ce qui, avec les alias, donne un historique comportant n fois le même jeu) : 2 élèves

- réussite : 1 élève.

Ce résultat plutôt décevant – 1 seule réussite et 4 réussites partielles – nous a amené à revoir certaines caractéristiques de l'activité. En particulier pour les 4 ayant seulement réussi partiellement, l'analyse détaillée des logs montre un début de construction de l'historique comportant des erreurs dues à l'absence de copie ou à un mauvais choix de l'information à mémoriser. Le problème est que ces élèves n'ont pas « vu » leurs erreurs, ce qui peut expliquer qu'ils ne les aient pas corrigées. Cette absence de « retour instrumental » est préjudiciable aux apprentissages, car l'élève ne peut pas apprendre de ses erreurs. Nous en déduisons que l'activité devrait visualiser en permanence la valeur de la variable historique, ce qui a été fait dans la version suivante. Nous notons aussi, en particulier dans les productions jugées incohérentes, un usage hasardeux des listes et des méthodes qui s'y appliquent. Nous proposons de fournir une aide comportant des explications sur les méthodes pouvant être utilisées.

## Analyse de l'ergonomie de l'interface et du recueil de données

Au début du jeu, la fonction undo ramène à la position initiale, ce qui a été largement utilisé en particulier par les joueurs les plus téméraires. Mais dès que la fonction undo est modifiée, il n'y a plus d'autre moyen pour revenir à la situation initiale que de recharger la page. Cette possibilité a été utilisée et entraîne une réinitialisation du programme de l'élève à sa valeur par défaut.

Ceci constitue un défaut de l'interface, qui a fait perdre du temps aux élèves qui ont testé leur programme en cours de modification et se sont ensuite retrouvés bloqués.

Ceci entraîne de plus une difficulté supplémentaire pour l'analyse de l'activité à partir des logs, car ce qui se passe en dehors du navigateur – copie et modification du programme dans un éditeur – ne peut être capturé par les logs.
# Seconde campagne d'expérimentations

## Une nouvelle situation améliorée

Pour répondre aux difficultés rencontrées par les élèves lors de cette première expérimentation, nous avons décidé d'améliorer le retour instrumental en affichant en permanence l'historique (pour suggérer l'idée de la pile, nous avons choisi de la figurer de bas en haut en notant en marge les indices), et de fournir une aide spécifique sur les méthodes applicables aux listes avec un avertissement concernant la copie (voir annexe 4).

## Activité : Jeu de saute-mouton

**Joue** : Emmène tous les moutons blancs à droite et tous les moutons noirs à gauche ! Les moutons blancs peuvent se déplacer vers la droite vers une case vide ou en sautant par dessus un mouton noir. Les moutons noirs peuvent se déplacer vers la gauche vers une case vide ou en sautant par dessus un mouton blanc.

**Programme** : Le fonctionnement du bouton **UNDO** n'est pas satisfaisant. Modifie le programme pour qu'il permette de revenir à la configuration précédente.

**Enregistre** : A la fin de la session, enregistre ton activité.

jeu = ["B", "B", "B", "O", "N", "N", "N"]
historique = []

def saute(case):
    """ Fait sauter le mouton présent dans la case en modifiant
    le jeu et l'historique, enregistrés en variables globales
    """
    global jeu, historique
    historique.append(jeu.copy())
    if jeu[case] == "B" and case < 6 and jeu[case + 1] == "O":
        jeu[case], jeu[case + 1] = "O", "B"
        elif jeu[case] == "B" and case < 5 and jeu[case + 1] == "N" and jeu[case + 2] == "O":
            jeu[case], jeu[case + 2] = "O", "B"
        elif jeu[case] == "N" and case > 0 and jeu[case - 1] == "O":
            jeu[case], jeu[case - 1] = "O", "N"
        elif jeu[case] == "N" and case > 1 and jeu[case - 1] == "B" and jeu[case - 2] == "O":
            jeu[case], jeu[case - 2] = "O", "N"
    else :
        historique.pop()

def undo():
    """ Remet la variable globale jeu à la dernière position enregistrée
    en utilisant la variable globale historique
    """

6 ['B', 'B', 'N', 'N', 'O', 'N', 'B']

5 ['B', 'B', 'N', 'N', 'B', 'N', 'O']

4 ['B', 'B', 'N', 'N', 'B', 'O', 'N']

3 ['B', 'B', 'N', 'O', 'B', 'N', 'N']

2 ['B', 'B', 'N', 'B', 'O', 'N', 'N']

1 ['B', 'B', 'O', 'B', 'N', 'N', 'N']

0 ['B', 'B', 'B', 'O', 'N', 'N', 'N']

<figure><img src="image_2.png" /></figure>

### Historique

Aide pour gérer l'historique

IREMI - LIM - INSPE de l'académie de la Réunion - 2022

<caption>**Figure 2** : Interface du jeu de saute-mouton avec visualisation de l'historique</caption>

Concernant l'ergonomie, nous avons ajouté un bouton **RESET** dont l'effet - non modifiable par l'utilisateur - est au début identique à celui du bouton **UNDO**, à savoir remettre le jeu dans sa position initiale et vider l'historique, sans modifier le programme de l'élève.

Pour mieux comprendre l'activité des élèves, nous avons aussi ajouté l'enregistrement des rechargements de la page (action **LOAD**) ainsi que des réinitialisations (action **RESET**). Nous obtenons ainsi des logs horodatant toutes les actions réalisées sur l'interface : coup 0, ... coup 6, **LOAD**, **RESET**, **UNDO**.

La visualisation de l'historique en partie droite de la page permet à l'élève de repérer toute construction erronée qui ne permettrait pas à la fonction undo de faire son travail. Nous avons aussi modifié l'encodage du jeu, remplaçant respectivement blanc, vide et noir par B, O et N, afin d'alléger la visualisation de l'historique.
# Seconde campagne d'expérimentations

## Une nouvelle situation améliorée

Pour répondre aux difficultés rencontrées par les élèves lors de cette première expérimentation, nous avons décidé d'améliorer le retour instrumental en affichant en permanence l'historique (pour suggérer l'idée de la pile, nous avons choisi de la figurer de bas en haut en notant en marge les indices), et de fournir une aide spécifique sur les méthodes applicables aux listes avec un avertissement concernant la copie (voir annexe 4).

## Activité : Jeu de saute-mouton

**Joue** : Emmène tous les moutons blancs à droite et tous les moutons noirs à gauche ! Les moutons blancs peuvent se déplacer vers la droite vers une case vide ou en sautant par dessus un mouton noir. Les moutons noirs peuvent se déplacer vers la gauche vers une case vide ou en sautant par dessus un mouton blanc.

**Programme** : Le fonctionnement du bouton **UNDO** n'est pas satisfaisant. Modifie le programme pour qu'il permette de revenir à la configuration précédente.

**Enregistre** : A la fin de la session, enregistre ton activité.

jeu = ["B", "B", "B", "O", "N", "N", "N"]
historique = []

def saute(case):
    """ Fait sauter le mouton présent dans la case en modifiant
    le jeu et l'historique, enregistrés en variables globales
    """
    global jeu, historique
    historique.append(jeu.copy())
    if jeu[case] == "B" and case < 6 and jeu[case + 1] == "O":
        jeu[case], jeu[case + 1] = "O", "B"
    elif jeu[case] == "B" and case < 5 and jeu[case + 1] == "N" and jeu[case + 2] == "O":
        jeu[case], jeu[case + 2] = "O", "B"
    elif jeu[case] == "N" and case > 0 and jeu[case - 1] == "O":
        jeu[case], jeu[case - 1] = "O", "N"
    elif jeu[case] == "N" and case > 1 and jeu[case - 1] == "B" and jeu[case - 2] == "O":
        jeu[case], jeu[case - 2] = "O", "N"
    else :
        historique.pop()

def undo():
    """ Remet la variable globale jeu à la dernière position enregistrée
    en utilisant la variable globale historique
    """

6 ['B', 'B', 'N', 'N', 'O', 'N', 'B']

5 ['B', 'B', 'N', 'N', 'B', 'N', 'O']

4 ['B', 'B', 'N', 'N', 'B', 'O', 'N']

3 ['B', 'B', 'N', 'O', 'B', 'N', 'N']

2 ['B', 'B', 'N', 'B', 'O', 'N', 'N']

1 ['B', 'B', 'O', 'B', 'N', 'N', 'N']

0 ['B', 'B', 'B', 'O', 'N', 'N', 'N']

### Historique

Aide pour gérer l'historique

<figure><img src="image_3.png" /></figure>

IREMI - LIM - INSPE de l'académie de la Réunion - 2022

<caption>**Figure 2** : Interface du jeu de saute-mouton avec visualisation de l'historique</caption>

Concernant l'ergonomie, nous avons ajouté un bouton **RESET** dont l'effet - non modifiable par l'utilisateur - est au début identique à celui du bouton **UNDO**, à savoir remettre le jeu dans sa position initiale et vider l'historique, sans modifier le programme de l'élève.

Pour mieux comprendre l'activité des élèves, nous avons aussi ajouté l'enregistrement des rechargements de la page (action **LOAD**) ainsi que des réinitialisations (action **RESET**). Nous obtenons ainsi des logs horodatant toutes les actions réalisées sur l'interface : coup 0, ... coup 6, **LOAD**, **RESET**, **UNDO**.

La visualisation de l'historique en partie droite de la page permet à l'élève de repérer toute construction erronée qui ne permettrait pas à la fonction undo de faire son travail. Nous avons aussi modifié l'encodage du jeu, remplaçant respectivement blanc, vide et noir par B, O et N, afin d'alléger la visualisation de l'historique.
# Expérimentation

La nouvelle situation a été expérimentée dans deux lycées de l'académie, le lycée Mémona Hintermann (LMH) et le lycée Le Verger (LLV) le 20 septembre 2022. Les expérimentations ont été menées par les enseignant.e.s titulaires de leur classe et co-auteurs de l'article, avec l'observation d'un chercheur pour le lycée Mémona Hintermann, où l'activité a été menée successivement avec les deux demi-groupes de la classe comptant respectivement 13 et 10 élèves. Pour le lycée Le Verger, l'activité a concerné les 15 élèves de la classe. L'ensemble des logs d'activité ont pu être enregistrés à l'issue des séances. Les résultats bruts de l'analyse des logs figurent en annexe 5. Par rapport à la première expérimentation, plusieurs informations supplémentaires ont pu être calculées :

- Les comptages des nombres d'actions LOAD, RESET et UNDO au total (variables nl, nr et nu) et avant de gagner le jeu (variables nlg, nrg et nug).

- Le temps passé avant de débuter la programmation (variable debprog).

Le codage de la qualité de la programmation (variable code) a été réalisé lors d'une séance collective d'analyse des résultats regroupant enseignants et chercheurs. Pour chaque élève a tout d'abord été noté une appréciation sur la gestion de l'historique, une appréciation sur la programmation de la fonction undo et une appréciation globale sur la programmation. Nous avons ensuite repris l'encodage 0 à 4 de la partie 2 pour résumer ces appréciations.

# Analyse des résultats

## Analyse quantitative

### Engagement des élèves dans l'activité

Pour tenter de répondre à la première hypothèse sur l'engagement des élèves dans l'activité par le jeu, nous examinons d'abord les différentes métriques nous permettant de mesurer les temps et les nombres d'actions.

<figure><img src="image_3.png" /><figcaption>Figure 3 - Analyse des temps d'activité</figcaption></figure>

Le temps d'activité moyen est de 46 mn (53 mn pour le lycée Le Verger et 41 mn pour le lycée Mémona Hintermann) et correspond aux durées des séances prévues par les enseignants. Les deux seuls élèves ayant passé un temps d'activité beaucoup plus faible sont les élèves LLV05 ayant cessé toute activité au bout de 11 mn et l'élève LMH202 ayant réussi la tâche de programmation au bout de 10 mn.
## Expérimentation

La nouvelle situation a été expérimentée dans deux lycées de l'académie, le lycée Mémona Hintermann (LMH) et le lycée Le Verger (LLV) le 20 septembre 2022. Les expérimentations ont été menées par les enseignant.e.s titulaires de leur classe et co-auteurs de l'article, avec l'observation d'un chercheur pour le lycée Mémona Hintermann, où l'activité a été menée successivement avec les deux demi-groupes de la classe comptant respectivement 13 et 10 élèves. Pour le lycée Le Verger, l'activité a concerné les 15 élèves de la classe. L'ensemble des logs d'activité ont pu être enregistrés à l'issue des séances. Les résultats bruts de l'analyse des logs figurent en annexe 5. Par rapport à la première expérimentation, plusieurs informations supplémentaires ont pu être calculées :

- Les comptages des nombres d'actions LOAD, RESET et UNDO au total (variables nl, nr et nu) et avant de gagner le jeu (variables nlg, nrg et nug).

- Le temps passé avant de débuter la programmation (variable debander).

Le codage de la qualité de la programmation (variable code) a été réalisé lors d'une séance collective d'analyse des résultats regroupant enseignants et chercheurs. Pour chaque élève a tout d'abord été noté une appréciation sur la gestion de l'historique, une appréciation sur la programmation de la fonction undo et une appréciation globale sur la programmation. Nous avons ensuite repris l'encodage 0 à 4 de la partie 2 pour résumer ces appréciations.

## Analyse des résultats

### Analyse quantitative

#### Engagement des élèves dans l'activité

Pour tenter de répondre à la première hypothèse sur l'engagement des élèves dans l'activité par le jeu, nous examinons d'abord les différentes métriques nous permettant de mesurer les temps et les nombres d'actions.

<figure><img src="image_4.png" /><figcaption>Figure 3 - Analyse des temps d'activité</figcaption></figure>

Le temps d'activité moyen est de 46 mn (53 mn pour le lycée Le Verger et 41 mn pour le lycée Mémona Hintermann) et correspond aux durées des séances prévues par les enseignants. Les deux seuls élèves ayant passé un temps d'activité beaucoup plus faible sont les élèves LLV05 ayant cessé toute activité au bout de 11 mn et l'élève LMH202 ayant réussi la tâche de programmation au bout de 10 mn.
Concernant le rapport entre temps de jeu et temps de programmation, les valeurs moyennes sont très proches – 22 mn de jeu et 24 mn de programmation – mais cachent de fortes disparités.

Le graphique de la figure 3 représente les élèves en fonction de leur temps de jeu (en abcisse) et de leur temps de programmation (en ordonnée). Nous repérons les deux élèves déjà cités en bas à gauche. Seuls 4 élèves n'ont pas programmé. La corrélation linéaire ne fait qu'exprimer que la somme des temps de jeu et de programmation, correspond au temps total d'activité. Ceux qui ont joué plus longtemps (4 élèves ont joué plus de 45 mn) ont moins programmé et réciproquement. La tendance centrale correspond au groupe d'élèves qui a joué entre 15 et 25 mn et programmé entre 20 et 30 mn. Seuls 10 élèves sur 38 ont passé plus de 2/3 de leur temps à jouer. Donc presque les 3/4 des élèves ont consacré plus d'un tiers du temps d'activité à la programmation.

Le graphique de la figure 4 représente le nombre d'interactions de chaque élève avec le jeu en distinguant les coups correspondant à un déplacement d'un mouton et les actions LOAD, RESET ou UNDO.

<figure><img src="image_4.png" /><figcaption>Figure 4 – Analyse des interactions des élèves</figcaption></figure>

En moyenne, les élèves ont eu en peu plus de 300 interactions avec le jeu. Le plus acharné (élève LMH204) en a eu plus de 800 en 23 mn de jeu.

Ces deux types de mesures – temps et interactions – nous permettent d'attester d'un engagement fort des élèves dans l'activité et d'un partage du temps variable entre jeu et programmation.

## Réussite du jeu

31 élèves sur 38 ont réussi le jeu en un temps moyen de 12 mn. Le plus rapide (élève LMH112) a gagné en 39 s après 23 coups et 1 RESET, ce qui est remarquable sachant que le jeu nécessite 15 coups pour gagner. Les élèves les plus patients LMH108 et LMH210 n'ont pas hésité à réinitialiser le jeu 57 fois avant de gagner en respectivement 26 mn et 404 coups et 24 mn et 443 coups.

Nous notons l'élève LLV07 qui a utilisé 46 fois le bouton UNDO et a fini par gagner le jeu après l'avoir correctement programmé au bout de 33 mn.

## Nécessité de la programmation

Pour tenter d'approcher la nécessité ressentie ou non par les élèves de programmer, nous avons compté le nombre d'élèves ayant commencé à programmer avant la réussite du jeu. 8 élèves ont commencé à programmer au moment de leur réussite au jeu. 12 élèves ont commencé à programmer avant d'avoir gagné puis ont gagné par la suite. Il y a donc un nombre
Concernant le rapport entre temps de jeu et temps de programmation, les valeurs moyennes sont très proches – 22 mn de jeu et 24 mn de programmation – mais cachent de fortes disparités.

Le graphique de la figure 3 représente les élèves en fonction de leur temps de jeu (en abcisse) et de leur temps de programmation (en ordonnée). Nous repérons les deux élèves déjà cités en bas à gauche. Seuls 4 élèves n'ont pas programmé. La corrélation linéaire ne fait qu'exprimer que la somme des temps de jeu et de programmation, correspond au temps total d'activité. Ceux qui ont joué plus longtemps (4 élèves ont joué plus de 45 mn) ont moins programmé et réciproquement. La tendance centrale correspond au groupe d'élèves qui a joué entre 15 et 25 mn et programmé entre 20 et 30 mn. Seuls 10 élèves sur 38 ont passé plus de 2/3 de leur temps à jouer. Donc presque les 3/4 des élèves ont consacré plus d'un tiers du temps d'activité à la programmation.

Le graphique de la figure 4 représente le nombre d'interactions de chaque élève avec le jeu en distinguant les coups correspondant à un déplacement d'un mouton et les actions LOAD, RESET ou UNDO.

<figure><img src="image_5.png" /><figcaption>Figure 4 – Analyse des interactions des élèves</figcaption></figure>

En moyenne, les élèves ont eu en peu plus de 300 interactions avec le jeu. Le plus acharné (élève LMH204) en a eu plus de 800 en 23 mn de jeu.

Ces deux types de mesures – temps et interactions – nous permettent d'attester d'un engagement fort des élèves dans l'activité et d'un partage du temps variable entre jeu et programmation.

## Réussite du jeu

31 élèves sur 38 ont réussi le jeu en un temps moyen de 12 mn. Le plus rapide (élève LMH112) a gagné en 39 s après 23 coups et 1 RESET, ce qui est remarquable sachant que le jeu nécessite 15 coups pour gagner. Les élèves les plus patients LMH108 et LMH210 n'ont pas hésité à réinitialiser le jeu 57 fois avant de gagner en respectivement 26 mn et 404 coups et 24 mn et 443 coups.

Nous notons l'élève LLV07 qui a utilisé 46 fois le bouton UNDO et a fini par gagner le jeu après l'avoir correctement programmé au bout de 33 mn.

## Nécessité de la programmation

Pour tenter d'approcher la nécessité ressentie ou non par les élèves de programmer, nous avons compté le nombre d'élèves ayant commencé à programmer avant la réussite du jeu. 8 élèves ont commencé à programmer au moment de leur réussite au jeu. 12 élèves ont commencé à programmer avant d'avoir gagné puis ont gagné par la suite. Il y a donc un nombre
significatif d'élèves qui ont ressenti cette nécessité avant d'avoir réussi le jeu.

## Réussite de la programmation

Sur les 38 élèves, 4 n'ont pas fait de programmation, 13 ont fait des tentatives infructueuses ou dont l'intention n'a pas été comprise, 11 ont programmé l'historique plus ou moins correctement mais pas la fonction undo et 10 élèves ont réussi l'activité de programmation de la fonction undo.

Nous notons en particulier qu'aucun élève n'a programmé un historique à un coup, comme cela avait été observé lors de la première expérimentation.

## Analyse qualitative

Les verbatims relevés par les enseignant.e.s au cours des séances ou après permettent de compléter et d'interpréter l'analyse. L'engagement de presque tous les élèves au-delà de leur participation habituelle à des activités de programmation a été relevée par les deux enseignants, ce qui semble confirmer notre hypothèse sur l'intérêt du jeu.

Lors de la séance d'institutionnalisation sur la pile qui a suivi cette activité au lycée Le Verger, un élève s'est exclamé : « en fait, le undo du saute-mouton, c'est comme le CTRL-Z », montrant qu'il avait compris cet usage fondamental de la pile.

La maîtrise des concepts de programmation permettant ou non de réaliser cette activité doit aussi nous interroger. Au bout de 30 mn d'activité, l'élève LMH112 s'est exprimé : « Ah, on peut mettre des listes dans des listes ! » et a réussi la programmation 5 mn après, son intervention montrant ainsi l'obstacle qu'il avait dû dépasser pour réussir.

L'analyse des programmes des élèves montre que la quasi-totalité ont choisi d'empiler dans l'historique les positions de jeu, à l'instar de l'élève LMH210 qui déclare après 30 mn d'activité : « je vais enregistrer dans l'historique la version précédente du jeu ».

Seul un élève (LMH202 déjà signalé pour sa réussite rapide à l'activité de programmation) s'est distingué en enregistrant sous forme de chaîne, le code python permettant d'inverser le dernier mouvement puis en l'utilisant via la fonction exec lors de l'appel à la fonction undo.

## Analyse de la nouvelle interface de jeu

Parmi les 38 élèves, seuls 2 ont été amenés à recharger une fois la page (action LOAD) au cours de l'activité, alors que ces rechargements intempestifs avaient été nombreux lors de la première expérimentation. Nous en déduisons qu'il était pertinent d'ajouter le bouton RESET qui a été largement utilisé pour réinitialiser le jeu sans perdre son programme.

L'intérêt de l'ajout de la visualisation de l'historique est confirmé par les résultats obtenus. En effet, plus aucun élève ne s'est contenté d'un historique à une position (code 2). Nous en déduisons que c'est le retour instrumental qui a permis aux élèves de voir leurs erreurs lors de la construction de l'historique, et aussi de corriger un historique où toutes les positions de jeu sont les mêmes à cause de l'absence de copie.

## Une variable didactique à étudier

Concernant l'impact de la difficulté du jeu sur la nécessité de la programmation de la fonction undo, il est difficile de conclure définitivement, sachant que les logs d'activité montrent un aller-retour entre jeu et programmation. L'engagement des élèves dans la programmation montre au moins qu'ils ont compris l'intérêt de programmer cette fonctionnalité. Une variable didactique de la situation aurait pu être utilisée pour forcer cette nécessité. La variation de la taille du jeu – passer de 3 à 4 ou 5 moutons de chaque couleur – permet de faire varier la difficulté. Une autre manière consiste à passer à la version à 2 dimensions, où 2 groupes de 8 moutons doivent se croiser via une case centrale unique, les moutons blancs allant vers le bas ou vers la droite et les
significatif d'élèves qui ont ressenti cette nécessité avant d'avoir réussi le jeu.

## Réussite de la programmation

Sur les 38 élèves, 4 n'ont pas fait de programmation, 13 ont fait des tentatives infructueuses ou dont l'intention n'a pas été comprise, 11 ont programmé l'historique plus ou moins correctement mais pas la fonction undo et 10 élèves ont réussi l'activité de programmation de la fonction undo.

Nous notons en particulier qu'aucun élève n'a programmé un historique à un coup, comme cela avait été observé lors de la première expérimentation.

## Analyse qualitative

Les verbatims relevés par les enseignant.e.s au cours des séances ou après permettent de compléter et d'interpréter l'analyse. L'engagement de presque tous les élèves au-delà de leur participation habituelle à des activités de programmation a été relevée par les deux enseignants, ce qui semble confirmer notre hypothèse sur l'intérêt du jeu.

Lors de la séance d'institutionnalisation sur la pile qui a suivi cette activité au lycée Le Verger, un élève s'est exclamé : « en fait, le undo du saute-mouton, c'est comme le CTRL-Z », montrant qu'il avait compris cet usage fondamental de la pile.

La maîtrise des concepts de programmation permettant ou non de réaliser cette activité doit aussi nous interroger. Au bout de 30 mn d'activité, l'élève LMH112 s'est exprimé : « Ah, on peut mettre des listes dans des listes ! » et a réussi la programmation 5 mn après, son intervention montrant ainsi l'obstacle qu'il avait dû dépasser pour réussir.

L'analyse des programmes des élèves montre que la quasi-totalité ont choisi d'empiler dans l'historique les positions de jeu, à l'instar de l'élève LMH210 qui déclare après 30 mn d'activité : « je vais enregistrer dans l'historique la version précédente du jeu ».

Seul un élève (LMH202 déjà signalé pour sa réussite rapide à l'activité de programmation) s'est distingué en enregistrant sous forme de chaîne, le code python permettant d'inverser le dernier mouvement puis en l'utilisant via la fonction exec lors de l'appel à la fonction undo.

## Analyse de la nouvelle interface de jeu

Parmi les 38 élèves, seuls 2 ont été amenés à recharger une fois la page (action LOAD) au cours de l'activité, alors que ces rechargements intempestifs avaient été nombreux lors de la première expérimentation. Nous en déduisons qu'il était pertinent d'ajouter le bouton RESET qui a été largement utilisé pour réinitialiser le jeu sans perdre son programme.

L'intérêt de l'ajout de la visualisation de l'historique est confirmé par les résultats obtenus. En effet, plus aucun élève ne s'est contenté d'un historique à une position (code 2). Nous en déduisons que c'est le retour instrumental qui a permis aux élèves de voir leurs erreurs lors de la construction de l'historique, et aussi de corriger un historique où toutes les positions de jeu sont les mêmes à cause de l'absence de copie.

## Une variable didactique à étudier

Concernant l'impact de la difficulté du jeu sur la nécessité de la programmation de la fonction undo, il est difficile de conclure définitivement, sachant que les logs d'activité montrent un aller-retour entre jeu et programmation. L'engagement des élèves dans la programmation montre au moins qu'ils ont compris l'intérêt de programmer cette fonctionnalité. Une variable didactique de la situation aurait pu être utilisée pour forcer cette nécessité. La variation de la taille du jeu – passer de 3 à 4 ou 5 moutons de chaque couleur – permet de faire varier la difficulté. Une autre manière consiste à passer à la version à 2 dimensions, où 2 groupes de 8 moutons doivent se croiser via une case centrale unique, les moutons blancs allant vers le bas ou vers la droite et les
moutons noirs vers le haut ou vers la gauche. Cette dernière version a été programmée mais n'a
pas encore été expérimentée. Elle est disponible à l'adresse :

<https://iremi974.gitlab.io/python-de-la-fournaise/sautemouton2d.html>

Conclusion et perspectives

Nous avons proposé une activité ludique – le jeu de saute-mouton – pour faire découvrir aux élèves la pile en tant que structure de donnée inscrite au programme de la spécialité NSI en classe de terminale. Après une première phase d'expérimentation ayant permis d'améliorer l'activité et le recueil de données, nous avons conduit une seconde expérimentation permettant de mettre à l'épreuve nos hypothèses.

Au vu des résultats, nous pensons pouvoir conclure positivement aux deux premières hypothèses quant à l'intérêt d'une activité ludique pour l'engagement des élèves dans l'activité et par rapport à l'impact de la difficulté du jeu sur la nécessité de programmer pour l'améliorer.

La situation nous semble bien signifiante par rapport à l'usage de la pile, mais elle partage cette
propriété avec toute activité faisant usage du CTRL-Z.

Il serait donc finalement présomptueux de considérer cette activité particulière comme une
situation fondamentale pour l'apprentissage de la pile.

Parmi les perspectives de cette recherche, nous pensons développer dans deux directions complémentaires :

- décliner la situation à d'autres jeux de type solitaire, dont des casse-têtes plus difficiles où le CTRL-Z est indispensable.

- continuer à développer l'enregistrement automatique de l'activité des élèves lors d'activités de programmation en ligne, et développer des méthodes plus génériques d'analyse des logs à partir de cette première expérimentation.

Concernant la modalité de cette recherche-action, nous remercions l'IREMI de l'université de La Réunion, qui nous a permis de rassembler un groupe d'enseignant.e.s et de chercheurs autour de cette problématique.

Références bibliographiques

Brougère, G. (2018). *Jeu et éducation* (Numéro 3926, p. 28). PUF. <https://sorbonne-paris-nord.hal.science/hal-03628855>

Brousseau, G. (1998). *Théorie des situations didactiques*. La pensée Sauvage.

Chevallard, Y. (1991). *La transposition didactique, du savoir savant au savoir enseigné*. La pensée Sauvage.

Froidevaux, C., Gaudel, M.-C., & Soria, M. (1990). *Types de données et algorithmes* (Mc Graw-Hill).

MENJ. (2019). *Programme de l'enseignement de spécialité de numérique et sciences informatiques de la classe terminale de la voie générale*. Ministère de l'Éducation Nationale et de la Jeunesse.
<https://www.education.gouv.fr/bo/19/Special8/MENE1921247A.htm>

Meyer, A., & Modeste, S. (2022). Situation didactique autour d'un jeu de recherche: Expérimentation en classes de NSI. *L'informatique, objets d'enseignement et d'apprentissage. Quelles nouvelles perspectives pour la recherche ? Actes du colloque DIDAPRO 9, 100*. https://hal.archives-ouvertes.fr/hal-03697943

Meyer, A., & Modeste, S. (2020, février). Analyse didactique d'un jeu de recherche : Vers une
moutons noirs vers le haut ou vers la gauche. Cette dernière version a été programmée mais n'a
pas encore été expérimentée. Elle est disponible à l'adresse :

<https://iremi974.gitlab.io/python-de-la-fournaise/sautemouton2d.html>

Conclusion et perspectives

Nous avons proposé une activité ludique – le jeu de saute-mouton – pour faire découvrir aux élèves la pile en tant que structure de donnée inscrite au programme de la spécialité NSI en classe de terminale. Après une première phase d'expérimentation ayant permis d'améliorer l'activité et le recueil de données, nous avons conduit une seconde expérimentation permettant de mettre à l'épreuve nos hypothèses.

Au vu des résultats, nous pensons pouvoir conclure positivement aux deux premières hypothèses quant à l'intérêt d'une activité ludique pour l'engagement des élèves dans l'activité et par rapport à l'impact de la difficulté du jeu sur la nécessité de programmer pour l'améliorer.

La situation nous semble bien signifiante par rapport à l'usage de la pile, mais elle partage cette
propriété avec toute activité faisant usage du CTRL-Z.

Il serait donc finalement présomptueux de considérer cette activité particulière comme une
situation fondamentale pour l'apprentissage de la pile.

Parmi les perspectives de cette recherche, nous pensons développer dans deux directions complémentaires :

- décliner la situation à d'autres jeux de type solitaire, dont des casse-têtes plus difficiles où le CTRL-Z est indispensable.

- continuer à développer l'enregistrement automatique de l'activité des élèves lors d'activités de programmation en ligne, et développer des méthodes plus génériques d'analyse des logs à partir de cette première expérimentation.

Concernant la modalité de cette recherche-action, nous remercions l'IREMI de l'université de La Réunion, qui nous a permis de rassembler un groupe d'enseignant.e.s et de chercheurs autour de cette problématique.

Références bibliographiques

Brougère, G. (2018). *Jeu et éducation* (Numéro 3926, p. 28). PUF. <https://sorbonne-paris-nord.hal.science/hal-03628855>

Brousseau, G. (1998). *Théorie des situations didactiques*. La pensée Sauvage.

Chevallard, Y. (1991). *La transposition didactique, du savoir savant au savoir enseigné*. La pensée Sauvage.

Froidevaux, C., Gaudel, M.-C., & Soria, M. (1990). *Types de données et algorithmes* (Mc Graw-Hill).

MENJ. (2019). *Programme de l'enseignement de spécialité de numérique et sciences informatiques de la classe terminale de la voie générale*. Ministère de l'Éducation Nationale et de la Jeunesse.
<https://www.education.gouv.fr/bo/19/Special8/MENE1921247A.htm>

Meyer, A., & Modeste, S. (2022). Situation didactique autour d'un jeu de recherche: Expérimentation en classes de NSI. *L'informatique, objets d'enseignement et d'apprentissage. Quelles nouvelles perspectives pour la recherche ? Actes du colloque DIDAPRO 9, 100*. https://hal.archives-ouvertes.fr/hal-03697943

Meyer, A., & Modeste, S. (2020, février). Analyse didactique d'un jeu de recherche : Vers une
situation fondamentale pour la complexité d’algorithmes et de problèmes. *Didapro 8 – DidaSTIC, L’informatique, objets d’enseignements – enjeux épistémologiques, didactiques et de formation*. https://hal.archives-ouvertes.fr/hal-03014372

Nijimbere, C. (2013). Approche instrumentale et didactiques : Apports de Pierre Rabardel. *Adjectif.net*.

Rabardel, P. (1995). *Les hommes et les technologies; approche cognitive des instruments contemporains*. Armand Colin. https://hal.archives-ouvertes.fr/hal-01017462
situation fondamentale pour la complexité d’algorithmes et de problèmes. *Didapro 8 – DidaSTIC, L’informatique, objets d’enseignements – enjeux épistémologiques, didactiques et de formation*. https://hal.archives-ouvertes.fr/hal-03014372

Nijimbere, C. (2013). Approche instrumentale et didactiques : Apports de Pierre Rabardel. *Adjectif.net*.

Rabardel, P. (1995). *Les hommes et les technologies; approche cognitive des instruments contemporains*. Armand Colin. https://hal.archives-ouvertes.fr/hal-01017462
# Annexe 1
## Protocole de recueil de données – fiche enseignant

### Déroulement de l'activité en classe

Au début de l'activité, communiquer le lien aux élèves :
https://iremi974.gitlab.io/python-de-la-fournaise/sautemouton.html

Ne pas déposer le lien au préalable sur l'ENT, pour éviter que des élèves ne s'entraînent au préalable sans que leur activité ne soit enregistrée.

### Lire la consigne suivante :

L'activité comporte 2 parties :

* Pour la 1ère partie, le but du jeu est d'emmener tous les moutons blancs à droite et tous les moutons noirs à gauche ! Les moutons blancs peuvent se déplacer vers la droite vers une case vide ou en sautant par dessus un mouton noir. Les moutons noirs peuvent se déplacer vers la gauche vers une case vide ou en sautant par dessus un mouton blanc.

* La deuxième partie consiste à programmer : le fonctionnement du bouton UNDO n'est pas satisfaisant. Il faut modifier le programme pour qu'il permette de revenir à la configuration précédente.

* Ne pas oublier à la fin de la session, d'enregistrer l'activité.

L'activité est à faire individuellement pour permettre l'analyse à partir des seules traces enregistrées automatiquement. En cas d'activité en binôme, il faudrait un dispositif permettant d'enregistrer les conversations.

Laisser les élèves jouer et travailler en autonomie pendant le temps choisi (45 mn à 1 h).

### Recueil des traces

Les traces d'activités sont loguées automatiquement dans le `localstorage` du navigateur. Le dispositif a été testé sous Firefox et fonctionne à condition que les paramètres de vie privée autorisent les données de sites.

Si la coche « supprimer les données de site à la fermeture de Firefox » est cochée, le recueil doit être fait immédiatement après l'activité, sans que les élèves ne ferment leur session de Firefox.

Le recueil de données peut être directement enregistré par l'élève en cliquant sur le lien `Enregistre ton activité`. Choisir un nom de fichier de la forme :

`log_saute_mouton_1.json` en prenant soin de ne pas indiquer de nom d'élève mais seulement un numéro, ce qui permet à ce recueil de données d'être effectué sans aucune collecte de données personnelles.

Le recueil de données peut aussi être visualisé dans la page :
https://iremi974.gitlab.io/python-de-la-fournaise/log.html

Pour l'enregistrer, choisir « Enregistrer sous au format Fichier texte ».

Pour information, la trace est au format JSON et sera analysée par un code écrit en Python.

### Envoi des traces pour analyse

Merci de m'adresser les fichiers de traces par mail à l'adresse :
christophe.declercq@univ-reunion.fr

Attention : le serveur de l'université bloque les archives zip !
# Annexe 1
## Protocole de recueil de données – fiche enseignant

### Déroulement de l'activité en classe

Au début de l'activité, communiquer le lien aux élèves :

https://iremi974.gitlab.io/python-de-la-fournaise/sautemouton.html

Ne pas déposer le lien au préalable sur l'ENT, pour éviter que des élèves ne s'entraînent au préalable sans que leur activité ne soit enregistrée.

### Lire la consigne suivante :

L'activité comporte 2 parties :

* Pour la 1ère partie, le but du jeu est d'emmener tous les moutons blancs à droite et tous les moutons noirs à gauche ! Les moutons blancs peuvent se déplacer vers la droite vers une case vide ou en sautant par dessus un mouton noir. Les moutons noirs peuvent se déplacer vers la gauche vers une case vide ou en sautant par dessus un mouton blanc.

* La deuxième partie consiste à programmer : le fonctionnement du bouton UNDO n'est pas satisfaisant. Il faut modifier le programme pour qu'il permette de revenir à la configuration précédente.

* Ne pas oublier à la fin de la session, d'enregistrer l'activité.

L'activité est à faire individuellement pour permettre l'analyse à partir des seules traces enregistrées automatiquement. En cas d'activité en binôme, il faudrait un dispositif permettant d'enregistrer les conversations.

Laisser les élèves jouer et travailler en autonomie pendant le temps choisi (45 mn à 1 h).

### Recueil des traces

Les traces d'activités sont loguées automatiquement dans le `localstorage` du navigateur. Le dispositif a été testé sous Firefox et fonctionne à condition que les paramètres de vie privée autorisent les données de sites.

Si la coche « supprimer les données de site à la fermeture de Firefox » est cochée, le recueil doit être fait immédiatement après l'activité, sans que les élèves ne ferment leur session de Firefox.

Le recueil de données peut être directement enregistré par l'élève en cliquant sur le lien `Enregistre ton activité`. Choisir un nom de fichier de la forme :

`log_saute_mouton_1.json` en prenant soin de ne pas indiquer de nom d'élève mais seulement un numéro, ce qui permet à ce recueil de données d'être effectué sans aucune collecte de données personnelles.

Le recueil de données peut aussi être visualisé dans la page :

https://iremi974.gitlab.io/python-de-la-fournaise/log.html

Pour l'enregistrer, choisir « Enregistrer sous au format Fichier texte ».

Pour information, la trace est au format JSON et sera analysée par un code écrit en Python.

### Envoi des traces pour analyse

Merci de m'adresser les fichiers de traces par mail à l'adresse :

christophe.declercq@univ-reunion.fr

Attention : le serveur de l'université bloque les archives zip !
Annexe 2
Exemple de trace d'activité

```c
[('2022-09-19 10:45:22.091000', {'coup': 'Load', 'jeu': ['B', 'B', 'B', 'X', 'N', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:39.136000', {'coup': 2, 'jeu': ['B', 'B', 'X', 'B', 'N', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:40.267000', {'coup': 4, 'jeu': ['B', 'B', 'N', 'B', 'X', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:41.715000', {'coup': 3, 'jeu': ['B', 'B', 'N', 'X', 'B', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:42.755000', {'coup': 1, 'jeu': ['B', 'X', 'N', 'B', 'B', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:43.404000', {'coup': 2, 'jeu': ['B', 'N', 'X', 'B', 'B', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:44.844000', {'coup': 0, 'jeu': ['X', 'N', 'B', 'B', 'B', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:46.242000', {'coup': 'Undo', 'jeu': ['B', 'B', 'B', 'X', 'N', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:48.118000', {'coup': 2, 'jeu': ['B', 'B', 'X', 'B', 'N', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:49.029000', {'coup': 4, 'jeu': ['B', 'B', 'N', 'B', 'X', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:51.224000', {'coup': 'Reset', 'jeu': ['B', 'B', 'B', 'X', 'N', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:46:14.153000', {'coup': 2, 'jeu': ['B', 'B', 'X', 'B', 'N', 'N', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N')],
 'prog': 'def saute(i):
     historique.append(jeu.copy())
     if jeu[i] == "B" and i<6 and
     jeu[i+1] == "X":
     jeu[i], jeu[i+1] = "X", "B"
     elif jeu[i] == "B" and i<5 and
     jeu[i+1] == "N" and jeu[i+2] == "X":
     jeu[i], jeu[i+2] = "X", "B"
     elif jeu[i] == "N" and
     i>0 and jeu[i-1] == "X":
     jeu[i], jeu[i-1] = "X", "N"
     elif jeu[i] == "N" and i>1 and
     jeu[i-1] == "B" and jeu[i-2] == "X":
     jeu[i], jeu[i-2] = "X", "N"
     else:
     historique.pop()
     #ndef undo():
     global jeu
     jeu = historique.pop()\n'}),
('2022-09-19 10:46:19.468000', {'coup': 4, 'jeu': ['B', 'B', 'N', 'B', 'X', 'N', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N'), ('B', 'B', 'X', 'B', 'N', 'N', 'N')]}),
('2022-09-19 10:46:22.046000', {'coup': 3, 'jeu': ['B', 'B', 'N', 'X', 'B', 'N', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N'), ('B', 'B', 'X', 'B', 'N', 'N', 'N'),
 ('B', 'B', 'N', 'B', 'X', 'N', 'N')]}),
('2022-09-19 10:46:30.761000', {'coup': 5, 'jeu': ['B', 'B', 'N', 'N', 'B', 'X', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N'), ('B', 'B', 'X', 'B', 'N', 'N', 'N'),
 ('B', 'B', 'N', 'B', 'X', 'N', 'N'), ('B', 'B', 'N', 'X', 'B', 'N', 'N')]}),
('2022-09-19 10:46:33.940000', {'coup': 'Undo', 'jeu': ['B', 'B', 'N', 'X', 'B', 'N', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N'), ('B', 'B', 'X', 'B', 'N', 'N', 'N'),
 ('B', 'B', 'N', 'B', 'X', 'N', 'N')]}),
('2022-09-19 10:46:41.365000', {'coup': 'Undo', 'jeu': ['B', 'B', 'N', 'B', 'X', 'N', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N'), ('B', 'B', 'X', 'B', 'N', 'N', 'N')]})
```
Annexe 2
Exemple de trace d'activité

```c
[('2022-09-19 10:45:22.091000', {'coup': 'Load', 'jeu': ['B', 'B', 'B', 'X', 'N', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:39.136000', {'coup': 2, 'jeu': ['B', 'B', 'X', 'B', 'N', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:40.267000', {'coup': 4, 'jeu': ['B', 'B', 'N', 'B', 'X', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:41.715000', {'coup': 3, 'jeu': ['B', 'B', 'N', 'X', 'B', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:42.755000', {'coup': 1, 'jeu': ['B', 'X', 'N', 'B', 'B', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:43.404000', {'coup': 2, 'jeu': ['B', 'N', 'X', 'B', 'B', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:44.844000', {'coup': 0, 'jeu': ['X', 'N', 'B', 'B', 'B', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:46.242000', {'coup': 'Undo', 'jeu': ['B', 'B', 'B', 'X', 'N', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:48.118000', {'coup': 2, 'jeu': ['B', 'B', 'X', 'B', 'N', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:49.029000', {'coup': 4, 'jeu': ['B', 'B', 'N', 'B', 'X', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:45:51.224000', {'coup': 'Reset', 'jeu': ['B', 'B', 'B', 'X', 'N', 'N', 'N'],
 'histo': []}),
('2022-09-19 10:46:14.153000', {'coup': 2, 'jeu': ['B', 'B', 'X', 'B', 'N', 'N', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N')],
 'prog': 'def saute(i):
     historique.append(jeu.copy())
     if jeu[i] == "B" and i<6 and
     jeu[i+1] == "X":
     jeu[i], jeu[i+1] = "X", "B"
     elif jeu[i] == "B" and i<5 and
     jeu[i+1] == "N" and jeu[i+2] == "X":
     jeu[i], jeu[i+2] = "X", "B"
     elif jeu[i] == "N" and
     i>0 and jeu[i-1] == "X":
     jeu[i], jeu[i-1] = "X", "N"
     elif jeu[i] == "N" and i>1 and
     jeu[i-1] == "B" and jeu[i-2] == "X":
     jeu[i], jeu[i-2] = "X", "N"
     else:
     historique.pop()\ndef undo():
     global jeu
     jeu = historique.pop()\n"},
('2022-09-19 10:46:19.468000', {'coup': 4, 'jeu': ['B', 'B', 'N', 'B', 'X', 'N', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N'), ['B', 'B', 'X', 'B', 'N', 'N', 'N']]}),
('2022-09-19 10:46:22.046000', {'coup': 3, 'jeu': ['B', 'B', 'N', 'X', 'B', 'N', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N'), ['B', 'B', 'X', 'B', 'N', 'N', 'N'],
 ['B', 'B', 'N', 'B', 'X', 'N', 'N']]}),
('2022-09-19 10:46:30.761000', {'coup': 5, 'jeu': ['B', 'B', 'N', 'N', 'B', 'X', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N'), ['B', 'B', 'X', 'B', 'N', 'N', 'N'],
 ['B', 'B', 'N', 'B', 'X', 'N', 'N'], ['B', 'B', 'N', 'X', 'B', 'N', 'N', 'N']]}),
('2022-09-19 10:46:33.940000', {'coup': 'Undo', 'jeu': ['B', 'B', 'N', 'X', 'B', 'N', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N'), ['B', 'B', 'X', 'B', 'N', 'N', 'N'],
 ['B', 'B', 'N', 'B', 'X', 'N', 'N', 'N']]}),
('2022-09-19 10:46:41.365000', {'coup': 'Undo', 'jeu': ['B', 'B', 'N', 'B', 'X', 'N', 'N'],
 'histo': [('B', 'B', 'B', 'X', 'N', 'N', 'N'), ['B', 'B', 'X', 'B', 'N', 'N', 'N', 'N']]}]
```
Annexe 3
Résultats de la première expérimentation

<table><thead><tr><th>ident</th><th>t_total</th><th>t_jeu</th><th>tProg</th><th>gagne</th><th>t_gagne</th><th>n_gagne</th><th>n</th><th>appréciation</th><th>code</th></tr></thead><tbody><tr><td>LLG001</td><td>44:34</td><td>09:00</td><td>35:33</td><td>True</td><td>06:47</td><td>82</td><td>254</td><td>historique sans copie du jeu</td><td>3</td></tr><tr><td>LLG002</td><td>37:44</td><td>05:35</td><td>32:08</td><td>False</td><td></td><td></td><td>185</td><td>programmation incohérente</td><td>1</td></tr><tr><td>LLG003</td><td>51:08</td><td>19:14</td><td>31:54</td><td>True</td><td>02:34</td><td>90</td><td>343</td><td>programmation incohérente</td><td>1</td></tr><tr><td>LLG004</td><td>52:45</td><td>12:19</td><td>40:25</td><td>False</td><td></td><td></td><td>201</td><td>historique sans copie du jeu</td><td>3</td></tr><tr><td>LLG005</td><td>54:19</td><td>13:15</td><td>41:03</td><td>True</td><td>01:02</td><td>33</td><td>168</td><td>programmation incohérente</td><td>1</td></tr><tr><td>LLG006</td><td>12:47</td><td>01:50</td><td>10:57</td><td>True</td><td>01:35</td><td>25</td><td>41</td><td>pas de programmation</td><td>0</td></tr><tr><td>LLG007</td><td>43:36</td><td>40:11</td><td>03:25</td><td>True</td><td>10:40</td><td>163</td><td>444</td><td>pas de programmation</td><td>0</td></tr><tr><td>LLG008</td><td>42:40</td><td>09:23</td><td>33:16</td><td>False</td><td></td><td></td><td>226</td><td>réussite</td><td>4</td></tr><tr><td>LLG101</td><td>55:53</td><td>09:20</td><td>46:33</td><td>False</td><td></td><td></td><td>175</td><td>historique un coup</td><td>2</td></tr><tr><td>LLG102</td><td>45:52</td><td>13:48</td><td>32:03</td><td>True</td><td>10:39</td><td>74</td><td>402</td><td>pas de programmation</td><td>0</td></tr><tr><td>LLG103</td><td>43:35</td><td>24:01</td><td>19:34</td><td>True</td><td>17:39</td><td>222</td><td>348</td><td>programmation incohérente</td><td>1</td></tr><tr><td>LLG104</td><td>45:07</td><td>19:16</td><td>25:50</td><td>False</td><td></td><td></td><td>237</td><td>historique un coup</td><td>2</td></tr><tr><td>LLG105</td><td>31:28</td><td>25:21</td><td>06:06</td><td>True</td><td>12:55</td><td>137</td><td>167</td><td>pas de programmation</td><td>0</td></tr><tr><td>LLG106</td><td>33:37</td><td>13:35</td><td>20:02</td><td>True</td><td>12:56</td><td>354</td><td>510</td><td>pas de programmation</td><td>0</td></tr></tbody></table>
Annexe 3
Résultats de la première expérimentation

<table><thead><tr><th>ident</th><th>t_total</th><th>t_jeu</th><th>tProg</th><th>gagne</th><th>t_gagne</th><th>n_gagne</th><th>n</th><th>appréciation</th><th>code</th></tr></thead><tbody><tr><td>LLG001</td><td>44:34</td><td>09:00</td><td>35:33</td><td>True</td><td>06:47</td><td>82</td><td>254</td><td>historique sans copie du jeu</td><td>3</td></tr><tr><td>LLG002</td><td>37:44</td><td>05:35</td><td>32:08</td><td>False</td><td></td><td></td><td>185</td><td>programmation incohérente</td><td>1</td></tr><tr><td>LLG003</td><td>51:08</td><td>19:14</td><td>31:54</td><td>True</td><td>02:34</td><td>90</td><td>343</td><td>programmation incohérente</td><td>1</td></tr><tr><td>LLG004</td><td>52:45</td><td>12:19</td><td>40:25</td><td>False</td><td></td><td></td><td>201</td><td>historique sans copie du jeu</td><td>3</td></tr><tr><td>LLG005</td><td>54:19</td><td>13:15</td><td>41:03</td><td>True</td><td>01:02</td><td>33</td><td>168</td><td>programmation incohérente</td><td>1</td></tr><tr><td>LLG006</td><td>12:47</td><td>01:50</td><td>10:57</td><td>True</td><td>01:35</td><td>25</td><td>41</td><td>pas de programmation</td><td>0</td></tr><tr><td>LLG007</td><td>43:36</td><td>40:11</td><td>03:25</td><td>True</td><td>10:40</td><td>163</td><td>444</td><td>pas de programmation</td><td>0</td></tr><tr><td>LLG008</td><td>42:40</td><td>09:23</td><td>33:16</td><td>False</td><td></td><td></td><td>226</td><td>réussite</td><td>4</td></tr><tr><td>LLG101</td><td>55:53</td><td>09:20</td><td>46:33</td><td>False</td><td></td><td></td><td>175</td><td>historique un coup</td><td>2</td></tr><tr><td>LLG102</td><td>45:52</td><td>13:48</td><td>32:03</td><td>True</td><td>10:39</td><td>74</td><td>402</td><td>pas de programmation</td><td>0</td></tr><tr><td>LLG103</td><td>43:35</td><td>24:01</td><td>19:34</td><td>True</td><td>17:39</td><td>222</td><td>348</td><td>programmation incohérente</td><td>1</td></tr><tr><td>LLG104</td><td>45:07</td><td>19:16</td><td>25:50</td><td>False</td><td></td><td></td><td>237</td><td>historique un coup</td><td>2</td></tr><tr><td>LLG105</td><td>31:28</td><td>25:21</td><td>06:06</td><td>True</td><td>12:55</td><td>137</td><td>167</td><td>pas de programmation</td><td>0</td></tr><tr><td>LLG106</td><td>33:37</td><td>13:35</td><td>20:02</td><td>True</td><td>12:56</td><td>354</td><td>510</td><td>pas de programmation</td><td>0</td></tr></tbody></table>
# Annexe 4
## Aide à propos des listes

## Mémo sur les listes

L'historique est au départ une liste (tableau) vide.

Les méthodes suivantes sont disponibles pour ajouter des éléments à une liste ou en supprimer :

* list.append(x) : Ajoute un élément à la fin de la liste.

* list.insert(i, x) : Insère un élément à la position indiquée.

* list.pop(i) : Enlève de la liste l'élément situé à la position indiquée et le renvoie en valeur de retour.

* list.pop() : Enlève de la liste le dernier élément et le renvoie en valeur de retour.

Attention : si une même liste est utilisée et modifiée plusieurs fois dans un programme, il est prudent d'en réaliser des copies :

* list.copy() : Renvoie une copie de la liste.
# Annexe 4
## Aide à propos des listes

## Mémo sur les listes

L'historique est au départ une liste (tableau) vide.

Les méthodes suivantes sont disponibles pour ajouter des éléments à une liste ou en supprimer :

* list.append(x) : Ajoute un élément à la fin de la liste.

* list.insert(i, x) : Insère un élément à la position indiquée.

* list.pop(i) : Enlève de la liste l'élément situé à la position indiquée et le renvoie en valeur de retour.

* list.pop() : Enlève de la liste le dernier élément et le renvoie en valeur de retour.

Attention : si une même liste est utilisée et modifiée plusieurs fois dans un programme, il est prudent d'en réaliser des copies :

* list.copy() : Renvoie une copie de la liste.
Annexe 5
Résultats de la deuxième expérimentation

<table><thead><tr><th>ident</th><th>t_total</th><th>t_jeu</th><th>tProg</th><th>gagne</th><th>t_gagne</th><th>nlg</th><th>nrg</th><th>nug</th><th>ng</th><th>nl</th><th>nr</th><th>nu</th><th>n</th><th>modif</th><th>deb_program</th><th>code</th></tr></thead><tbody><tr><td>LLV01</td><td>00:43:20</td><td>00:30:05</td><td>00:13:15</td><td>True</td><td>12:30</td><td>1</td><td>21</td><td>1</td><td>265</td><td>1</td><td>27</td><td>19</td><td>317</td><td>True</td><td>21:49</td><td>3</td></tr><tr><td>LLV02</td><td>00:47:43</td><td>00:21:00</td><td>00:26:43</td><td>True</td><td>06:01</td><td>1</td><td>5</td><td>1</td><td>39</td><td>1</td><td>33</td><td>33</td><td>136</td><td>True</td><td>06:01</td><td>4</td></tr><tr><td>LLV03</td><td>00:52:23</td><td>00:22:24</td><td>00:29:59</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>8</td><td>20</td><td>10</td><td>72</td><td>True</td><td>03:49</td><td>1</td></tr><tr><td>LLV04</td><td>00:38:02</td><td>00:18:15</td><td>00:19:47</td><td>True</td><td>15:38</td><td>1</td><td>3</td><td>2</td><td>23</td><td>1</td><td>9</td><td>10</td><td>73</td><td>True</td><td>10:32</td><td>1</td></tr><tr><td>LLV05</td><td>00:11:20</td><td>00:11:20</td><td>00:00:00</td><td>True</td><td>11:20</td><td>1</td><td>12</td><td>1</td><td>171</td><td>1</td><td>12</td><td>1</td><td>172</td><td>False</td><td></td><td>0</td></tr><tr><td>LLV06</td><td>00:52:17</td><td>00:10:59</td><td>00:41:18</td><td>True</td><td>17:26</td><td>1</td><td>16</td><td>10</td><td>62</td><td>2</td><td>23</td><td>23</td><td>94</td><td>True</td><td>03:32</td><td>1</td></tr><tr><td>LLV07</td><td>01:02:11</td><td>00:28:14</td><td>00:33:57</td><td>True</td><td>38:34</td><td>2</td><td>27</td><td>46</td><td>287</td><td>2</td><td>43</td><td>82</td><td>335</td><td>True</td><td>00:00</td><td>4</td></tr><tr><td>LLV08</td><td>01:04:01</td><td>00:08:24</td><td>00:55:37</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>13</td><td>5</td><td>47</td><td>True</td><td>02:56</td><td>1</td></tr><tr><td>LLV09</td><td>00:49:39</td><td>00:49:39</td><td>00:00:00</td><td>True</td><td>16:30</td><td>1</td><td>6</td><td>1</td><td>66</td><td>2</td><td>7</td><td>1</td><td>85</td><td>False</td><td></td><td>0</td></tr><tr><td>LLV10</td><td>01:02:26</td><td>00:55:18</td><td>00:07:08</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>11</td><td>31</td><td>185</td><td>True</td><td>39:47</td><td>1</td></tr><tr><td>LLV11</td><td>01:05:23</td><td>00:25:00</td><td>00:40:23</td><td>True</td><td>05:03</td><td>1</td><td>6</td><td>8</td><td>36</td><td>1</td><td>19</td><td>54</td><td>107</td><td>True</td><td>00:33</td><td>4</td></tr><tr><td>LLV12</td><td>01:05:51</td><td>00:20:49</td><td>00:45:02</td><td>True</td><td>05:54</td><td>1</td><td>2</td><td>12</td><td>75</td><td>1</td><td>37</td><td>109</td><td>225</td><td>True</td><td>02:29</td><td>4</td></tr><tr><td>LLV13</td><td>00:57:18</td><td>00:47:22</td><td>00:09:56</td><td>True</td><td>23:45</td><td>1</td><td>26</td><td>3</td><td>190</td><td>2</td><td>68</td><td>31</td><td>352</td><td>True</td><td>36:48</td><td>1</td></tr><tr><td>LLV14</td><td>01:07:10</td><td>00:18:41</td><td>00:48:29</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>46</td><td>47</td><td>110</td><td>True</td><td>00:00</td><td>1</td></tr><tr><td>LLV15</td><td>01:03:49</td><td>00:50:21</td><td>00:13:29</td><td>True</td><td>34:04</td><td>1</td><td>24</td><td>11</td><td>224</td><td>2</td><td>37</td><td>16</td><td>411</td><td>True</td><td>04:15</td><td>1</td></tr><tr><td>LMH101</td><td>00:42:55</td><td>00:19:06</td><td>00:23:49</td><td>True</td><td>07:31</td><td>1</td><td>14</td><td>0</td><td>136</td><td>1</td><td>31</td><td>13</td><td>223</td><td>True</td><td>13:03</td><td>1</td></tr><tr><td>LMH102</td><td>00:46:00</td><td>00:20:57</td><td>00:25:03</td><td>True</td><td>07:25</td><td>1</td><td>11</td><td>0</td><td>113</td><td>1</td><td>16</td><td>20</td><td>299</td><td>True</td><td>07:25</td><td>3</td></tr><tr><td>LMH103</td><td>00:47:05</td><td>00:09:20</td><td>00:37:45</td><td>True</td><td>04:52</td><td>1</td><td>3</td><td>3</td><td>41</td><td>1</td><td>47</td><td>44</td><td>121</td><td>True</td><td>04:52</td><td>3</td></tr><tr><td>LMH104</td><td>00:43:37</td><td>00:18:59</td><td>00:24:38</td><td>True</td><td>17:44</td><td>1</td><td>34</td><td>1</td><td>244</td><td>1</td><td>53</td><td>38</td><td>253</td><td>True</td><td>17:44</td><td>3</td></tr><tr><td>LMH105</td><td>00:45:05</td><td>00:07:09</td><td>00:37:56</td><td>True</td><td>02:45</td><td>1</td><td>0</td><td>8</td><td>61</td><td>1</td><td>4</td><td>43</td><td>149</td><td>True</td><td>02:45</td><td>3</td></tr><tr><td>LMH106</td><td>00:46:02</td><td>00:18:00</td><td>00:28:03</td><td>True</td><td>17:29</td><td>1</td><td>30</td><td>8</td><td>152</td><td>1</td><td>50</td><td>25</td><td>221</td><td>True</td><td>05:53</td><td>3</td></tr><tr><td>LMH107</td><td>00:30:18</td><td>00:30:10</td><td>00:00:08</td><td>True</td><td>10:01</td><td>1</td><td>1</td><td>24</td><td>201</td><td>2</td><td>1</td><td>37</td><td>331</td><td>True</td><td>23:12</td><td>0</td></tr><tr><td>LMH108</td><td>00:39:07</td><td>00:27:03</td><td>00:12:04</td><td>True</td><td>26:15</td><td>1</td><td>57</td><td>26</td><td>404</td><td>2</td><td>63</td><td>26</td><td>454</td><td>True</td><td>15:31</td><td>1</td></tr><tr><td>LMH109</td><td>00:36:02</td><td>00:07:36</td><td>00:28:26</td><td>True</td><td>04:32</td><td>1</td><td>9</td><td>1</td><td>108</td><td>2</td><td>16</td><td>11</td><td>181</td><td>True</td><td>04:32</td><td>3</td></tr><tr><td>LMH110</td><td>00:47:22</td><td>00:15:05</td><td>00:32:18</td><td>True</td><td>03:10</td><td>1</td><td>1</td><td>3</td><td>32</td><td>1</td><td>48</td><td>49</td><td>111</td><td>True</td><td>03:10</td><td>1</td></tr><tr><td>LMH111</td><td>00:45:26</td><td>00:23:31</td><td>00:21:55</td><td>True</td><td>29:56</td><td>1</td><td>32</td><td>3</td><td>193</td><td>1</td><td>37</td><td>3</td><td>219</td><td>True</td><td>17:57</td><td>3</td></tr><tr><td>LMH112</td><td>00:37:12</td><td>00:13:31</td><td>00:23:41</td><td>True</td><td>00:39</td><td>1</td><td>1</td><td>0</td><td>23</td><td>2</td><td>20</td><td>43</td><td>184</td><td>True</td><td>02:26</td><td>4</td></tr><tr><td>LMH113</td><td>00:28:05</td><td>00:28:05</td><td>00:00:00</td><td>True</td><td>19:44</td><td>1</td><td>34</td><td>2</td><td>271</td><td>1</td><td>44</td><td>3</td><td>361</td><td>False</td><td></td><td>0</td></tr><tr><td>LMH201</td><td>00:41:30</td><td>00:11:38</td><td>00:29:52</td><td>True</td><td>08:19</td><td>1</td><td>0</td><td>5</td><td>142</td><td>1</td><td>4</td><td>13</td><td>207</td><td>True</td><td>05:27</td><td>3</td></tr><tr><td>LMH202</td><td>00:10:36</td><td>00:02:47</td><td>00:07:49</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>6</td><td>14</td><td>45</td><td>True</td><td>00:00</td><td>4</td></tr><tr><td>LMH203</td><td>00:46:59</td><td>00:04:45</td><td>00:42:14</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>12</td><td>17</td><td>44</td><td>True</td><td>03:26</td><td>4</td></tr><tr><td>LMH204</td><td>00:46:13</td><td>00:23:25</td><td>00:22:48</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>67</td><td>67</td><td>712</td><td>True</td><td>20:38</td><td>4</td></tr><tr><td>LMH205</td><td>00:46:14</td><td>00:25:25</td><td>00:20:49</td><td>True</td><td>01:42</td><td>1</td><td>3</td><td>4</td><td>64</td><td>1</td><td>18</td><td>28</td><td>297</td><td>True</td><td>11:29</td><td>4</td></tr><tr><td>LMH206</td><td>00:46:27</td><td>00:34:06</td><td>00:12:21</td><td>True</td><td>05:01</td><td>1</td><td>8</td><td>1</td><td>77</td><td>1</td><td>60</td><td>9</td><td>505</td><td>True</td><td>23:16</td><td>3</td></tr><tr><td>LMH207</td><td>00:46:05</td><td>00:23:56</td><td>00:22:09</td><td>True</td><td>02:08</td><td>1</td><td>2</td><td>1</td><td>32</td><td>1</td><td>8</td><td>86</td><td>304</td><td>True</td><td>01:00</td><td>4</td></tr></tbody></table>
Annexe 5
Résultats de la deuxième expérimentation

<table><thead><tr><th>ident</th><th>t_total</th><th>t_jeu</th><th>tProg</th><th>gagne</th><th>t_gagne</th><th>nlg</th><th>nrg</th><th>nug</th><th>ng</th><th>nl</th><th>nr</th><th>nu</th><th>n</th><th>modif</th><th>deb_program</th><th>code</th></tr></thead><tbody><tr><td>LLV01</td><td>00:43:20</td><td>00:30:05</td><td>00:13:15</td><td>True</td><td>12:30</td><td>1</td><td>21</td><td>1</td><td>265</td><td>1</td><td>27</td><td>19</td><td>317</td><td>True</td><td>21:49</td><td>3</td></tr><tr><td>LLV02</td><td>00:47:43</td><td>00:21:00</td><td>00:26:43</td><td>True</td><td>06:01</td><td>1</td><td>5</td><td>1</td><td>39</td><td>1</td><td>33</td><td>33</td><td>136</td><td>True</td><td>06:01</td><td>4</td></tr><tr><td>LLV03</td><td>00:52:23</td><td>00:22:24</td><td>00:29:59</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>8</td><td>20</td><td>10</td><td>72</td><td>True</td><td>03:49</td><td>1</td></tr><tr><td>LLV04</td><td>00:38:02</td><td>00:18:15</td><td>00:19:47</td><td>True</td><td>15:38</td><td>1</td><td>3</td><td>2</td><td>23</td><td>1</td><td>9</td><td>10</td><td>73</td><td>True</td><td>10:32</td><td>1</td></tr><tr><td>LLV05</td><td>00:11:20</td><td>00:11:20</td><td>00:00:00</td><td>True</td><td>11:20</td><td>1</td><td>12</td><td>1</td><td>171</td><td>1</td><td>12</td><td>1</td><td>172</td><td>False</td><td></td><td>0</td></tr><tr><td>LLV06</td><td>00:52:17</td><td>00:10:59</td><td>00:41:18</td><td>True</td><td>17:26</td><td>1</td><td>16</td><td>10</td><td>62</td><td>2</td><td>23</td><td>23</td><td>94</td><td>True</td><td>03:32</td><td>1</td></tr><tr><td>LLV07</td><td>01:02:11</td><td>00:28:14</td><td>00:33:57</td><td>True</td><td>38:34</td><td>2</td><td>27</td><td>46</td><td>287</td><td>2</td><td>43</td><td>82</td><td>335</td><td>True</td><td>00:00</td><td>4</td></tr><tr><td>LLV08</td><td>01:04:01</td><td>00:08:24</td><td>00:55:37</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>13</td><td>5</td><td>47</td><td>True</td><td>02:56</td><td>1</td></tr><tr><td>LLV09</td><td>00:49:39</td><td>00:49:39</td><td>00:00:00</td><td>True</td><td>16:30</td><td>1</td><td>6</td><td>1</td><td>66</td><td>2</td><td>7</td><td>1</td><td>85</td><td>False</td><td></td><td>0</td></tr><tr><td>LLV10</td><td>01:02:26</td><td>00:55:18</td><td>00:07:08</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>11</td><td>31</td><td>185</td><td>True</td><td>39:47</td><td>1</td></tr><tr><td>LLV11</td><td>01:05:23</td><td>00:25:00</td><td>00:40:23</td><td>True</td><td>05:03</td><td>1</td><td>6</td><td>8</td><td>36</td><td>1</td><td>19</td><td>54</td><td>107</td><td>True</td><td>00:33</td><td>4</td></tr><tr><td>LLV12</td><td>01:05:51</td><td>00:20:49</td><td>00:45:02</td><td>True</td><td>05:54</td><td>1</td><td>2</td><td>12</td><td>75</td><td>1</td><td>37</td><td>109</td><td>225</td><td>True</td><td>02:29</td><td>4</td></tr><tr><td>LLV13</td><td>00:57:18</td><td>00:47:22</td><td>00:09:56</td><td>True</td><td>23:45</td><td>1</td><td>26</td><td>3</td><td>190</td><td>2</td><td>68</td><td>31</td><td>352</td><td>True</td><td>36:48</td><td>1</td></tr><tr><td>LLV14</td><td>01:07:10</td><td>00:18:41</td><td>00:48:29</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>46</td><td>47</td><td>110</td><td>True</td><td>00:00</td><td>1</td></tr><tr><td>LLV15</td><td>01:03:49</td><td>00:50:21</td><td>00:13:29</td><td>True</td><td>34:04</td><td>1</td><td>24</td><td>11</td><td>224</td><td>2</td><td>37</td><td>16</td><td>411</td><td>True</td><td>04:15</td><td>1</td></tr><tr><td>LMH101</td><td>00:42:55</td><td>00:19:06</td><td>00:23:49</td><td>True</td><td>07:31</td><td>1</td><td>14</td><td>0</td><td>136</td><td>1</td><td>31</td><td>13</td><td>223</td><td>True</td><td>13:03</td><td>1</td></tr><tr><td>LMH102</td><td>00:46:00</td><td>00:20:57</td><td>00:25:03</td><td>True</td><td>07:25</td><td>1</td><td>11</td><td>0</td><td>113</td><td>1</td><td>16</td><td>20</td><td>299</td><td>True</td><td>07:25</td><td>3</td></tr><tr><td>LMH103</td><td>00:47:05</td><td>00:09:20</td><td>00:37:45</td><td>True</td><td>04:52</td><td>1</td><td>3</td><td>3</td><td>41</td><td>1</td><td>47</td><td>44</td><td>121</td><td>True</td><td>04:52</td><td>3</td></tr><tr><td>LMH104</td><td>00:43:37</td><td>00:18:59</td><td>00:24:38</td><td>True</td><td>17:44</td><td>1</td><td>34</td><td>1</td><td>244</td><td>1</td><td>53</td><td>38</td><td>253</td><td>True</td><td>17:44</td><td>3</td></tr><tr><td>LMH105</td><td>00:45:05</td><td>00:07:09</td><td>00:37:56</td><td>True</td><td>02:45</td><td>1</td><td>0</td><td>8</td><td>61</td><td>1</td><td>4</td><td>43</td><td>149</td><td>True</td><td>02:45</td><td>3</td></tr><tr><td>LMH106</td><td>00:46:02</td><td>00:18:00</td><td>00:28:03</td><td>True</td><td>17:29</td><td>1</td><td>30</td><td>8</td><td>152</td><td>1</td><td>50</td><td>25</td><td>221</td><td>True</td><td>05:53</td><td>3</td></tr><tr><td>LMH107</td><td>00:30:18</td><td>00:30:10</td><td>00:00:08</td><td>True</td><td>10:01</td><td>1</td><td>1</td><td>24</td><td>201</td><td>2</td><td>1</td><td>37</td><td>331</td><td>True</td><td>23:12</td><td>0</td></tr><tr><td>LMH108</td><td>00:39:07</td><td>00:27:03</td><td>00:12:04</td><td>True</td><td>26:15</td><td>1</td><td>57</td><td>26</td><td>404</td><td>2</td><td>63</td><td>26</td><td>454</td><td>True</td><td>15:31</td><td>1</td></tr><tr><td>LMH109</td><td>00:36:02</td><td>00:07:36</td><td>00:28:26</td><td>True</td><td>04:32</td><td>1</td><td>9</td><td>1</td><td>108</td><td>2</td><td>16</td><td>11</td><td>181</td><td>True</td><td>04:32</td><td>3</td></tr><tr><td>LMH110</td><td>00:47:22</td><td>00:15:05</td><td>00:32:18</td><td>True</td><td>03:10</td><td>1</td><td>1</td><td>3</td><td>32</td><td>1</td><td>48</td><td>49</td><td>111</td><td>True</td><td>03:10</td><td>1</td></tr><tr><td>LMH111</td><td>00:45:26</td><td>00:23:31</td><td>00:21:55</td><td>True</td><td>29:56</td><td>1</td><td>32</td><td>3</td><td>193</td><td>1</td><td>37</td><td>3</td><td>219</td><td>True</td><td>17:57</td><td>3</td></tr><tr><td>LMH112</td><td>00:37:12</td><td>00:13:31</td><td>00:23:41</td><td>True</td><td>00:39</td><td>1</td><td>1</td><td>0</td><td>23</td><td>2</td><td>20</td><td>43</td><td>184</td><td>True</td><td>02:26</td><td>4</td></tr><tr><td>LMH113</td><td>00:28:05</td><td>00:28:05</td><td>00:00:00</td><td>True</td><td>19:44</td><td>1</td><td>34</td><td>2</td><td>271</td><td>1</td><td>44</td><td>3</td><td>361</td><td>False</td><td></td><td>0</td></tr><tr><td>LMH201</td><td>00:41:30</td><td>00:11:38</td><td>00:29:52</td><td>True</td><td>08:19</td><td>1</td><td>0</td><td>5</td><td>142</td><td>1</td><td>4</td><td>13</td><td>207</td><td>True</td><td>05:27</td><td>3</td></tr><tr><td>LMH202</td><td>00:10:36</td><td>00:02:47</td><td>00:07:49</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>6</td><td>14</td><td>45</td><td>True</td><td>00:00</td><td>4</td></tr><tr><td>LMH203</td><td>00:46:59</td><td>00:04:45</td><td>00:42:14</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>12</td><td>17</td><td>44</td><td>True</td><td>03:26</td><td>4</td></tr><tr><td>LMH204</td><td>00:46:13</td><td>00:23:25</td><td>00:22:48</td><td>False</td><td></td><td></td><td></td><td></td><td></td><td>1</td><td>67</td><td>67</td><td>712</td><td>True</td><td>20:38</td><td>4</td></tr><tr><td>LMH205</td><td>00:46:14</td><td>00:25:25</td><td>00:20:49</td><td>True</td><td>01:42</td><td>1</td><td>3</td><td>4</td><td>64</td><td>1</td><td>18</td><td>28</td><td>297</td><td>True</td><td>11:29</td><td>4</td></tr><tr><td>LMH206</td><td>00:46:27</td><td>00:34:06</td><td>00:12:21</td><td>True</td><td>05:01</td><td>1</td><td>8</td><td>1</td><td>77</td><td>1</td><td>60</td><td>9</td><td>505</td><td>True</td><td>23:16</td><td>3</td></tr><tr><td>LMH207</td><td>00:46:05</td><td>00:23:56</td><td>00:22:09</td><td>True</td><td>02:08</td><td>1</td><td>2</td><td>1</td><td>32</td><td>1</td><td>8</td><td>86</td><td>304</td><td>True</td><td>01:00</td><td>4</td></tr></tbody></table>
<table><tr><td>LMH208</td><td>00:46:18</td><td>00:22:22</td><td>00:23:56</td><td>True</td><td>02:25</td><td>1</td><td>2</td><td>0</td><td>33</td><td>4</td><td>37</td><td>58</td><td>364</td><td>True</td><td>04:17</td><td>3</td></tr><tr><td>LMH209</td><td>00:46:31</td><td>00:13:54</td><td>00:32:36</td><td>True</td><td>10:09</td><td>1</td><td>21</td><td>0</td><td>134</td><td>1</td><td>33</td><td>17</td><td>203</td><td>True</td><td>10:09</td><td>1</td></tr><tr><td>LMH210</td><td>00:45:39</td><td>00:18:03</td><td>00:27:36</td><td>True</td><td>24:34</td><td>2</td><td>57</td><td>24</td><td>443</td><td>2</td><td>75</td><td>102</td><td>496</td><td>True</td><td>07:44</td><td>1</td></tr><tr><td>Min</td><td>00:10:36</td><td>00:02:47</td><td>00:00:00</td><td></td><td>00:00:40</td><td>1</td><td>0</td><td>0</td><td>23</td><td>1</td><td>1</td><td>1</td><td>44</td><td></td><td>00:00:00</td><td></td></tr><tr><td>Max</td><td>01:07:10</td><td>00:55:18</td><td>00:55:37</td><td></td><td>00:38:34</td><td>2</td><td>57</td><td>46</td><td>443</td><td>8</td><td>75</td><td>109</td><td>712</td><td></td><td>00:39:48</td><td></td></tr><tr><td>Moy</td><td>00:46:18</td><td>00:22:01</td><td>00:24:17</td><td></td><td>00:12:41</td><td>1</td><td>15</td><td>7</td><td>140</td><td>2</td><td>30</td><td>33</td><td>237</td><td></td><td>00:09:41</td><td></td></tr></table>
<table><tr><td>LMH208</td><td>00:46:18</td><td>00:22:22</td><td>00:23:56</td><td>True</td><td>02:25</td><td>1</td><td>2</td><td>0</td><td>33</td><td>4</td><td>37</td><td>58</td><td>364</td><td>True</td><td>04:17</td><td>3</td></tr><tr><td>LMH209</td><td>00:46:31</td><td>00:13:54</td><td>00:32:36</td><td>True</td><td>10:09</td><td>1</td><td>21</td><td>0</td><td>134</td><td>1</td><td>33</td><td>17</td><td>203</td><td>True</td><td>10:09</td><td>1</td></tr><tr><td>LMH210</td><td>00:45:39</td><td>00:18:03</td><td>00:27:36</td><td>True</td><td>24:34</td><td>2</td><td>57</td><td>24</td><td>443</td><td>2</td><td>75</td><td>102</td><td>496</td><td>True</td><td>07:44</td><td>1</td></tr><tr><td>Min</td><td>00:10:36</td><td>00:02:47</td><td>00:00:00</td><td></td><td>00:00:40</td><td>1</td><td>0</td><td>0</td><td>23</td><td>1</td><td>1</td><td>1</td><td>44</td><td></td><td>00:00:00</td><td></td></tr><tr><td>Max</td><td>01:07:10</td><td>00:55:18</td><td>00:55:37</td><td></td><td>00:38:34</td><td>2</td><td>57</td><td>46</td><td>443</td><td>8</td><td>75</td><td>109</td><td>712</td><td></td><td>00:39:48</td><td></td></tr><tr><td>Moy</td><td>00:46:18</td><td>00:22:01</td><td>00:24:17</td><td></td><td>00:12:41</td><td>1</td><td>15</td><td>7</td><td>140</td><td>2</td><td>30</td><td>33</td><td>237</td><td></td><td>00:09:41</td><td></td></tr></table>