VP-SE Research Group (C)

Techniques de génie logiciel pour l'EAO

B. Ibrahim, A. Aubord, B. Laustsen, M. Tepper Université de Genève
24, rue du Général Dufour
CH-1211 Genève 4
Une version Postscript de ce document est disponible ici.

Résumé:

Le développement de logiciels d'Enseignement Assisté par Ordinateur (EAO) nécessite un travail d'envergure si l'on ne veut pas se limiter à quelques leçons d'utilité purement personnelle. Nous concevons donc le développement de tels logiciels comme un travail d'équipe. La voie la plus couramment utilisée dans ce domaine est celle des langages auteurs, lesquels imposent trop de contraintes aux concepteurs de leçons. Nous avons choisi d'utiliser un formalisme de spécification de leçon très simple et un langage de programmation d'utilité générale pour implanter ces spécifications.

Tout un environnement de développement a alors été conçu sur station de travail graphique pour faciliter la transcription des spécifications de leçons en programmes pouvant être exécutés sur diverses machines cibles. Cet environnement comporte entre autres, un éditeur graphique de scripts, un générateur automatique de programmes et un éditeur multi-fenêtres synchrones pour faciliter le travail des programmeurs qui doivent compléter le code généré automatiquement.

1. Introduction:

Lorsque nous nous sommes lancés dans le domaine de l'enseignement assisté par ordinateur, deux orientations principales se dessinaient alors: les systèmes auteurs d'une part et les bibliothèques de modules de programmation d'autre part, les premiers étant généralement liés à un langage auteur et les seconds à un langage de programmation dit "classique".

L'avantage généralement perçu des systèmes auteurs est l'absence de la nécessité de connaître un langage de programmation pour pouvoir les utiliser. Cela en fait un outil de choix pour des enseignants désireux de développer leurs propres leçons à moindre frais. A nos yeux, cet avantage constitue en fait un inconvénient puisque la simplicité d'utilisation se fait généralement au détriment de la richesse d'expression. Quelques rares systèmes offrent des possibilités de programmation plus étendues, mais leur complexité d'utilisation augmente d'autant. De plus, ces possibilités de programmation ne répondent que de loin aux critères modernes de sécurité et de lisibilité des programmes.

Soucieux de n'imposer aucune limitation aux enseignants désirant développer des leçons d'EAO, nous avons choisi l'alternative consistant à utiliser un langage de programmation se prêtant bien au travail en équipe, c'est-à-dire incorporant la notion de module. Indépendamment du choix d'un langage de programmation, nous utilisons un formalisme de spécification des leçons, développé par l'équipe du professeur A. Bork (Bork86) et qui, tel un scénario de film, permet de décrire le dialogue entre l'ordinateur et l'apprenant ainsi que la logique de déroulement de la leçon, prenant en compte les réponses fournies à l'ordinateur.

2. Formalisme de spécification:

Le formalisme de spécification que nous utilisons est fondé sur trois primitives de base: le texte à faire apparaître à l'écran, le commentaire au programmeur et la boîte de test (contenant généralement un critère d'analyse de réponse). La spécification d'une leçon se présente donc sous la forme d'un graphe orienté dont chaque noeud correspond à l'une des trois primitives citées précédemment et où les arcs indiquent le séquencement des opérations (exemple fig. 1).



Les différents critères d'analyse d'une réponse (ou d'une action) de l'apprenant sont spécifiés dans une suite de boîtes de tests qui se suivent en séquence. Les arcs partant d'une boîte de test sont généralement numérotés et indiquent ce qui doit être fait la première fois, la deuxième fois, etc, que le critère inscrit dans la boîte de test est satisfait. Si le critère d'une boîte de test n'est pas satisfait, c'est le critère suivant qui est évalué. S'il n'y a plus d'autre critère, des arcs partant de la base de la dernière boîte de test peuvent indiquer ce qui doit être fait le cas échéant.

3. Première étape: réutilisation de code

Les premiers développements que nous avons faits comportaient déjà une phase de conception pédagogique séparée de la phase de programmation. Le groupe d'enseignants et de pédagogues chargés de la conception pédagogique n'éprouvent généralement aucune difficulté à maîtriser notre formalisme de spécification assez simple. Le plus gros du travail incombe ensuite à l'équipe de programmeurs qui doivent transcrire cette spécification en programmes.

C'est dans le but de faciliter cette transcription et pour éviter que les mêmes efforts soient répétés à chaque fois qu'une série de modules réutilisables ont été développés. Ces modules permettent de gérer des fenêtres de texte et de graphique à l'écran, des entrées au clavier ou à la souris, des fichiers de messages en accès direct pour séparer la logique de déroulement des textes des dialogues, des fichiers d'images matricielles pour assurer une certaine indépendance vis-à-vis de la résolution de l'écran (Ibra88), l'accès à un réseau local pour contrôler le déroulement des leçons et récolter des statistiques (Ibra85), ainsi que des algorithmes de classification permettant l'analyse des réponses de l'apprenant.

Bien que d'une utilité certaine, ces divers modules n'offrent d'aide que dans une petite partie du cycle de vie d'un logiciel d'EAO. De plus, une bonne partie du travail de programmation qui reste à faire et qui a trait à la logique de déroulement est assez fastidieuse et sujette à des erreurs d'implantation.

4. Environnement de développement

De l'expérience acquise à développer diverses leçons d'EAO, nous avons pu cerner les besoins liés à l'utilisation d'un langage de programmation d'utilité générale. Ces besoins sont d'ailleurs assez similaires à ceux de tout projet d'envergure: des outils de spécification, des outils d'implantation, des outils de prototypage et de mise au point, et des outils de maintenance.

Les différentes phases de l'élaboration d'un didacticiel peuvent être représentées par la figure 2.



C'est pour faire correspondre à chacune de ces phases un ou plusieurs outils appropriés et pour réduire autant que possible le travail de codage que nous avons démarré le projet "IDEAL" (Infrastructure de Développement et d'Elaboration Automatisée de Leçons). Cet environnement de développement a été en priorité conçu pour être utilisé par des informaticiens. Cela signifie que la puissance de fonctionalité a été privilégiée par rapport à la simplicité d'utilisation, sans pour autant renoncer à toute convivialité. Nous pensons en effet que, même pour un professionnel de l'informatique, la convivialité constitue un facteur déterminant de la productivité.

Cet environnement de développement utilise une station de travail avec grand écran. Pour des raisons de portabilité et d'indépendance vis-à-vis des constructeurs le langage de programmation utilisé est le langage Ada et l'environnement de gestion de fenêtre est X-Windows, développé au M.I.T. dans le cadre du projet Athena (Sche86). Les leçons développées à l'aide de cet environnement sont conçues pour être exécutées sur un ordinateur personnel et nécessitent des ressources nettement plus modestes. Parmi les langages cibles envisagés, on peut citer Ada, Modula 2, Pascal UCSD, Turbo Pascal...

L'environnement de développement comporte, pour la phase de conception pédagogique, un éditeur de script permettant d'introduire graphiquement la spécification d'une leçon ou de modifier la spécification d'une leçon pré-existante.

La phase de révision de la conception pédagogique utilise un traducteur automatique (générateur automatique de programmes) qui, même s'il ne peut traduire la totalité du script, est capable de générer pour faire du prototypage rapide un programme dont l'exécution donnera une idée assez précise de ce que sera le produit final. A ce stade, l'éditeur de script peut être utilisé pour apporter des modifications au scénario avant même que la phase de codage n'ait commencé.

La phase de codage ainsi que celle de révision du code font, elles, appel à un éditeur multi-fenêtres synchrones qui permet à un programmeur de compléter dans une fenêtre le code généré par le traducteur automatique tout en visualisant dans une autre fenêtre la partie du script correspondante. C'est ici que l'utilisation d'un langage cible modulaire apporte un avantage certain. Cela permet en effet de séparer dans des modules le code ajouté par le(s) programmeur(s), ne nécessitant pas ainsi la modification du code généré par le traducteur automatique.

La phase de révision du code fait usage d'un outil de supervision à distance (sur une machine de développement) pour suivre le déroulement d'une leçon (sur une machine cible reliée au même réseau local), permettant de visualiser directement sur le script le cheminement du programme cible. Il est ainsi plus facile de déterminer à quel endroit de la leçon a lieu telle ou telle erreur. L'éditeur multi-fenêtres synchrones permet alors au programmeur de se placer directement sur le code concerné pour le corriger.

Un mécanisme similaire permet de récolter automatiquement des statistiques sur le déroulement des leçons, une fois que le didacticiel est opérationnel. L'étude de ces statistiques peut alors amener les concepteurs à revoir la conception pédagogique en utilisant l'éditeur de script.

A côté de la conception et de la mise au point de leçons, il est une phase qui est assez importante à nos yeux: la traduction des dialogues. En effet, tous les didacticiels que nous développons sont étudiés pour pouvoir être facilement traduits dans diverses langues utilisant le même alphabet (à quelques variantes de lettres accentuées près). Cette phase de traduction pouvant intervenir avant aussi bien qu'après des révisions du script, elle nécessite l'emploi d'un outil d'édition qui possède aussi les fonctionalité d'un gestionnaire de versions et gère une base de données de mises à jour.

Tous ces outils sont interdépendants et forment un ensemble cohérent qui peut être illustré par la figure 3.



5. L'éditeur de scripts

L'éditeur de scripts est principalement un éditeur graphique dont les primitives de base ont été choisies en fonction de la finalité de l'outil. Il est utilisé dans la phase de conception pédagogique pour construire la spécification détaillée d'une leçon, tel l'exemple vu précédemment en figure 1. Cet éditeur est interactif et utilise une souris pour presque toutes les opérations (sauf l'entrée de texte) : choix d'une commande par menu jaillissant (pop up menu), sélection d'une zone à modifier, placement du point d'insertion . . .

La structure de donnée construite par cet éditeur et chargée de représenter le contenu de la leçon est un graphe orienté où chaque noeud représente une action élémentaire: l'affichage d'un texte (message) à l'écran, l'exécution d'une opération quelconque (commentaire au codeur) ou l'évaluation d'un test sur une action de l'apprenant. Les arcs orientés représentent quant à eux l'enchaînement des opérations. Cette structure est non-linéaire puisqu'un noeud représentant un test (généralement un critère d'analyse de réponse) peut avoir plusieurs successeurs:

Les primitives de positionnement comportent, en plus des primitives classiques de désignation directe et de mécanisme d'ascenseur, des primitives d'avancement le long des arcs (en avant ou en arrière) permettant ainsi de se déplacer facilement en fonction de la structure.

En plus des primitives d'édition, l'éditeur de script permet de contrôler la cohérence du graphe, mettant ainsi rapidement en évidence des arcs oubliés ou des chemins incomplets.

En sortie, cet éditeur crée un fichier contenant le graphe correspondant à la leçon et un fichier de messages contenant le texte des dialogues (contenu des noeuds de type message). Ces deux fichiers pourront ensuite être utilisés par les autres outils de l'environnement (fig. 3) pour obtenir une sortie papier ou pour produire les programmes correspondants.

6. Le générateur automatique de programmes

La structure de graphe orienté obtenue à l'aide de l'éditeur de scripts se prête assez facilement à une traduction automatique en programme. En effet, à la structure de graphe, l'on peut faire correspondre un automate à états finis où chaque état de l'automate contient l'exécution de l'action spécifiée dans le noeud correspondant du graphe. Les arcs sont, quant à eux, traduits en instructions de changement de la variable d'état.

Un noeud de type message sera traduit en un appel à la primitive d'affichage de texte sur l'écran avec, en paramètre, le nom du message correspondant. Un noeud de type test sera traduit en un appel à une fonction booléenne dont le corps sera défini dans un module externe. Un noeud de type commentaire au codeur sera traduit en un appel à une procédure dont le corps sera lui aussi défini dans un module externe.

Le code qui devra être ajouté par les programmeurs se trouve donc dans des modules séparés du code produit par le générateur automatique. Ces modules externes ont leur définition (interface) fixée par le générateur automatique et leur implantation pourra être définie à l'aide de l'éditeur multi-fenêtres synchrones.

Pour permettre un prototypage rapide des leçons, le générateur automatique peut produire une implantation "bidon" des modules externes dans laquelle les procédures correspondant aux commentaires au codeur ne contiennent qu'une instruction d'affichage du commentaire et les fonctions correspondant aux tests sollicitent interactivement le résultat qu'elles sont sensé retourner.

7. L'éditeur multi-fenêtres synchrones

Un des problèmes principaux liés à l'utilisation de code produit par un générateur automatique est que ce code est difficilement lisible par un humain, la plupart des symboles utilisés étant produits par des mécanismes simplistes les rendant assez incompréhensibles. C'est donc dans le but de remédier à cet inconvénient que nous avons conçu un éditeur qui, en plus des fonctionalités d'un éditeur de texte dans une fenêtre, gère une fenêtre auxiliaire dont le contenu est en correspondance directe avec le contenu de la fenêtre principale.

Cette fenêtre auxiliaire affiche la partie du script que le code de la fenêtre principale est sensé implanter. Toutes ces fenêtres (principale et auxiliaire) permettent d'introduire des commandes de positionnement qui provoqueront un déplacement synchronisé de l'autre fenêtre. En plus du code sur lequel il travaille, le programmeur a ainsi en permanence sous les yeux la spécification correspondante, qui constitue une documentation nettement plus lisible.

8. Le gestionaire de traductions

Comme il a déjà été dit plus haut, les didacticiels que nous concevons sont étudiés dès le départ pour permettre une traduction facile des dialogues. Si cette traduction n'était effectuée qu'après l'achèvement de la version initiale, il n'y aurait aucun inconvénient à utiliser un simple éditeur de texte pour créer une traduction du fichier de messages d'origine. Il arrive toutefois souvent que des modifications soient apportées au script à plusieurs reprises après un long moment d'utilisation réelle, à la suite de remarques provenant des utilisateurs ou des enseignants.

Pour faciliter le maintien de la cohérence entre les différentes traductions, un utilitaire multi-fenêtres de gestion des modifications apportées aux messages permet de se placer automatiquement à l'endroit où une modification a eu lieu pour une langue et pas pour une autre, d'afficher dans différentes fenêtres le message modifié avant et après modification ainsi que la traduction qui doit être mise à jour. Il y a donc une fenêtre active permettant de mettre à jour une langue et des fenêtres passives permettant de voir les modifications apportées à d'autres langues. Ces différentes fenêtres sont synchronisées et tout déplacement dans l'une d'elles provoque le même mouvement dans les autres.

En plus des primitives d'édition de texte, cet outil possède donc des primitives de gestion de versions tenant à jour une base de données de modifications.

9. Le superviseur de leçons

Le fait que le graphe du script est traduit en un automate à états finis permet de facilement visualiser l'avancement du déroulement d'une leçon. Il suffit pour cela que la machine cible et la station de développement soient sur le même réseau local. Pour exploiter cette liaison, le générateur automatique de programmes peut alors ajouter dans l'automate à états finis une instruction permettant d'envoyer sur le réseau, à chaque changement de la variable d'état, la valeur de cette variable ainsi que l'identification de la machine cible et de la leçon en cours d'exécution.

Lorsque la leçon se déroule sur la machine cible, il suffit alors de mettre une station de travail à l'écoute du réseau pour pouvoir visualiser à l'écran de la station de travail l'avancement de la leçon directement sur le dessin du script. Parallèlement à la visualisation de l'avancement de la leçon, il est possible de récolter par le même mécanisme des statistiques sur le déroulement de l'ensemble des leçons. Ces statistiques permettent ensuite de mieux se rendre compte de l'impact des leçons sur les apprenants, en dévoilant les parties où un grand nombre ont eu des difficultés, nécessitant éventuellement une modification du script en vue d'améliorer la situation. Nous avons d'ailleurs par le passé déjà tiré profit de machines connectées en réseau pour récolter des informations sur le déroulement de leçons (Ibra85).

Moyennant l'adjonction du nom de l'apprenant dans les informations envoyées par la machine cible, il serait aussi possible de faire du curriculum automatique. Nous sommes toutefois peu partisans d'une telle solution car il n'est pas toujours facile de contrôler l'identité réelle de la personne qui suit la leçon. Cela nuirait aussi au climat de confiance qui règne quand l'apprenant sait qu'il n'y a personne pour le surveiller et qu'il peut par conséquent faire des erreurs sans se sentir culpabilisé.

Il va de soi que le module d'accès au réseau est conçu de telle façon qu'en cas de défaillance de ce réseau, la machine ne soit pas bloquée pour autant. En plus de son utilité évidente dans la phase d'exploitation des didacticiels, cette possibilité de suivre le déroulement d'une leçon est très utile durant la phase de mise au point. En effet, s'il est possible de savoir à quel point du script on se trouve lorsqu'une leçon se "plante", l'éditeur multi-fenêtres synchrones permet de se placer très rapidement sur le code correspondant, facilitant ainsi la recherche des erreurs de programmation.

10. Extensions futures

Bien que la réalisation de cet environnement ne soit pas encore complètement achevée, nous envisageons déjà une direction dans laquelle il serait possible d'en étendre la fonctionalité. Comme le lecteur aura pu le remarquer, le formalisme de spécification que nous utilisons est très ouvert puisqu'il permet de fournir une partie de la spécification en langage naturel sous forme de commentaires au codeur. Pour la première phase de notre projet, nous avons prévu que le générateur automatique de programmes ne s'occupe que des messages et de la logique de déroulement, faisant correspondre à chaque commentaire au codeur une procédure se trouvant dans un module externe et dont le corps devra être défini par un programmeur.

Nous envisageons donc, dans une deuxième phase, d'augmenter la puissance de traduction à l'aide de techniques d'intelligence artificielle, en l'occurrence des mécanismes d'apprentissage et de généralisation. Cela consistera à essayer de reconnaître des similitudes entre différents commentaires au codeur et de solliciter du programmeur un prédicat permettant d'associer des paramètres spécifiques à chaque commentaire.

11. Références:

Site Hosting: Bronco