« Introduction à la programmation » : différence entre les versions
m (→Conclusion) |
|||
Ligne 294 : | Ligne 294 : | ||
#: Disposer d'assez de temps et de connaissances (ou de "force de travail") pour traduire en code tous les éléments constitutifs du programme (logique, interface, sauvegarde des données, etc.). | #: Disposer d'assez de temps et de connaissances (ou de "force de travail") pour traduire en code tous les éléments constitutifs du programme (logique, interface, sauvegarde des données, etc.). | ||
{{ bloc | {{ bloc important | En ligne de compte, donc, le code source d'un programme ou d'une application représente la manière ultime de répondre à un besoin. }} | ||
==Ressources== | ==Ressources== |
Version du 13 février 2018 à 17:13
Introduction
Cette introduction à la programmation a pour but de fournir à des personnes sans un background technique les éléments conceptuels principaux pour s’initier à la programmation, indépendamment du langage ou des technologies envisagés. Pour ce faire, nous allons d’abord situer la programmation dans le contexte plus large du développement. Ensuite, nous proposerons trois types d’approches différents qui sont toutefois complémentaires à la programmation. La première approche, plutôt conceptuelle, introduit la programmation dans une perspective fidèle au contexte de ce wiki, c’est-à-dire en utilisant des concepts issus des Sciences de l’Éducation et de la Psychologie. La deuxième approche, plus technique, illustre la fonction de médiation entre le développeur et la machine de la programmation. La troisième approche, plus pragmatique, essaye de mettre ensemble les approches conceptuelles et techniques pour illustrer les aspects fondamentaux de la programmation. En guise de conclusion, nous proposons une liste de ressources liées à la programmation.
La programmation dans le cycle de développement
Le développement est un processus qui est souvent considéré comme un cycle. Il existe plusieurs méthodologies de développement qui déterminent de manières différentes le nombre et l’ordre (e.g. séquentiel ou itérative) des étapes. De manière très succincte, on peut identifier les étapes fondamentales suivantes :
- Analyse des besoins et/ou du contexte d’utilisation : développer signifie créer quelque chose qui répond à une certaine nécessité, représentant ainsi une solution à une exigence d'utilisateur(s).
- Prototypage : l’application à développer est déterminée de manière conceptuelle en fonction des objectifs et de la manière de les achever. Selon le type de méthode adoptée, à ce stade, on fait souvent des dessins de l’interface, de scénarios d’utilisation, etc.
- Implémentation : l’application est « traduite » dans une forme interprétable par le dispositif sur lequel elle est censée fonctionner. Cette étape correspond normalement à la programmation, c’est-à-dire à l’écriture du code.
- Test : l’application est contrôlée dans le but qu’elle fonctionne de la manière imaginée/souhaitée.
- Déploiement : l’application est rendue disponible aux utilisateurs (e.g. publiée sur le web).
- Maintien : l’application est modifiée ou adaptée à des nécessités qui se présentent dans le temps.
Cette page s’intéresse principalement à la phase d’implémentation, mais considère la programmation comme un élément intégré dans le cycle de développement.
Approche conceptuelle à la programmation
L’approche behavioriste des utilisateurs
La plupart des personnes qui utilisent un logiciel ou une application adopte une approche qu’on pourrait qualifier de behavioriste. En effet, les utilisateurs ne se préoccupent pas de comprendre ce qui se passe à l’intérieur de la « boîte noire » de l’application, mais ils se limitent à évaluer ce que l’application permet de faire en termes de manipulations (i.e. les stimuli) et les résultats qu’on peut obtenir (i.e. les réponses).
Dans le cadre de la programmation, le schéma « stimulus-réponse » est assez proche du principe du « input-output » (abrégé I/O) : à un certain input introduit dans le système correspond un output.
Le principe du Input/Output
Le rôle du programmeur est donc de déterminer ce qui se passe à l’intérieur de la « boîte noire », c’est-à-dire de déterminer quel comportement l’application va adopter sur la base des stimuli fournis par les utilisateurs. Plus spécifiquement, dans la plupart des cas, programmer est le fait de fournir aux utilisateurs la possibilité de transformer des inputs dans des outputs, car jugées plus utiles, intéressantes et/ou adaptées à leurs besoins, etc.
Le mécanisme d’I/O peut se faire à différents niveaux, pouvant discriminer l’input de l’output ce qui signifie que cela dépend parfois de la perspective adoptée. Voici quelques exemples très simples pour illustrer le principe :
- Dans une application qui permet de faire des calculs, l’utilisateur connait deux chiffres ou plus qu’il désire associer mathématiquement (inputs) pour obtenir un résultat qu’il ne connaît pas (output).
- Dans une application de traitement de texte, l’utilisateur saisit des mots qui forment des phrases (inputs) et applique des transformations sur le texte (inputs) pour obtenir un document final (output) ; en même temps, il peut également partir d’un document existant (output) pour sélectionner une partie spécifique qui l’intéresse (input) et la sauvegarder dans un nouveau document (output).
- Dans un jeu vidéo « point and shoot », l’utilisateur fournit plusieurs instructions d'input (bouger, tirer, etc.) et l’application fournit des outputs correspondant (augmenter les points, passer de niveau, etc.). En même temps, le jeu crée automatiquement des obstacles ou des ennemis (output) qui déterminent les actions du joueur (input).
- Dans un QCM online, le système propose des questions à choix multiples (output) parmi lesquels l’utilisateur doit identifier et sélectionner la réponse correcte (input). Un feedback (output) est finalement fait à l’utilisateur qui lui dit s'il a choisi la bonne réponse.
L’interaction homme-machine
Le principe de l’I/O est à la base de l'interactive computing et de l’interaction homme-machine (IHM ou HCI an anglais, pour Human-Computer Interaction). En effet, en simplifiant les choses, on peut illustrer l’interaction entre l'utilisateur et la machine à travers une série d’échanges cycliques qui prévoie de l’I/O du côté de la machine, et du stimulus/réponse (ou comportement) chez l’utilisateur :
- L’utilisateur obtient des stimuli depuis l’application, par exemple à travers des instructions à faire, des éléments à manipuler (boutons, champ de texte, etc.), des feedbacks, etc.
- L’utilisateur transforme ces stimuli en comportement (e.g. en cliquant sur un bouton).
- Ce comportement représente un input pour l’application, qui détermine un output correspondant (e.g. afficher une nouvelle page).
- Cet output représente un nouveau stimulus pour l’utilisateur - on revient donc au point 1, à moins que l’output ne soit considéré définitif (par l’utilisateur et/ou l’application).
Dans cette perspective, les trois aspects qui déterminent l’ergonomie d’une application (efficacité, efficience et satisfaction) peuvent être analysés par rapport à ces échanges entre l'homme et la machine :
- Efficacité
- Une application est efficace si elle permet d’obtenir l’output souhaité à partir d’inputs identifiables.
- Efficience
- Une application est efficiente si le nombre d’inputs nécessaires est proportionnel à la qualité/complexité de l’output.
- Satisfaction
- Une application est satisfaisante si les échanges I/O vs. stimulus/réponse entre homme et machine sont considérés de manière positive par l’utilisateur.
Approche technique à la programmation
Le langage de programmation
De manière concrète, la programmation permet de résoudre un problème (ou un besoin) de manière automatisée grâce à l’application d’un algorithme. On utilise souvent cette équation pour définir un programme informatique :
Programme = Algorithme + Données
Un algorithme est une suite d’expressions (ou instructions) qui sont évaluées par le processeur du dispositif sur lequel « tourne » le programme. La totalité des expressions utilisées dans un programme représente le « code source ». Pour que le dispositif puisse exécuter le code source, il faut utiliser un langage que la machine peut comprendre : un langage de programmation.
Langage de bas vs. haut niveau
Il existe plusieurs langages de programmation et différentes manières pour les différencier. Une des distinctions les plus communes divise les langages en bas et en haut niveau. Cette distinction peut s’expliquer en partant du présupposé que machines et humains parlent deux langues différentes et nécessitent donc une sorte de compromis pour se comprendre :
- Un langage de bas niveau peut se considérer plus proche du langage de la machine (i.e. binaire) plutôt que du langage humain. Un langage de bas niveau est plus difficile à apprendre et à utiliser, mais il permet néanmoins plus de possibilités d’interaction avec le hardware de la machine.
- Un langage de haut niveau, au contraire, est plus proche du langage des êtres humains, et il est par conséquent plus facile à utiliser. Cependant, cette facilité limite les possibilités d’interagir avec la machine selon ce que le langage met à disposition.
Compilation vs. Interprétation
Un langage de programmation de haut niveau nécessite une « traduction » (i.e. le transformer en code binaire) pour que la machine puisse le comprendre et l’exécuter. Traditionnellement, ce mécanisme peut se faire de deux manières différentes :
- Compilation : la compilation d’un programme consiste à transformer toutes les instructions (i.e. le code source) d’une application dans un autre langage pour qu’il soit « compréhensible » par la machine. Celle-ci se fait avant que le programme puisse être exécuté et après chaque changement du code source, ainsi il sera nécessaire de refaire la compilation. Par exemple, les logiciels installés sur les ordinateurs (.exe pour Windows, .app pour Mac) ont été compilés, c’est pourquoi une nouvelle installation est nécessaire pour les mises à jour des logiciels.
- Interprétation : dans le cas des langages de programmation qui ne sont pas compilés, il est nécessaire qu'un interprète lise et traduise le langage « en temps réel » (ou en anglais, « on run time »). Dans ce cas, le code source est lu à chaque exécution, ainsi les changements apportés au code seront pris en compte directement. Cependant, pour ce faire, il est nécessaire que la machine sur laquelle le programme tourne dispose de l’interprète. Par exemple, les langages de programmation pour le web sont des langages qui disposent d’un interprète soit au niveau du serveur (e.g. PHP, Ruby, …), soit dans le navigateur de l’utilisateur (JavaScript).
Des langages pour les hommes
Du moment qu'on n'écrit plus en code binaire, les langages de programmation s'approchent de tout autre langage humain. En effet, du moment que les interprètes/compilateurs traduisent le langage de haut niveau en langage machine, les caractéristiques de celui-ci peuvent être déterminées de manière arbitraire. Imaginons une instruction qui permet d'afficher un simple message à l'écran: on peut l'écrire avec deux langages de programmation différentes, mais la "traduction" en code binaire sera équivalente (ou assez proche), car la machine va exécuter la même opération dans les deux cas.
Un langage de programmation partage ainsi plusieurs caractéristiques avec une langue naturelle :
- Lexique
- Il dispose d’un lexique, c’est-à-dire une liste de mots qui ont une signification particulière ;
- Syntaxe
- Il dispose d’une syntaxe, c’est-à-dire des règles d’associations de mots et de la ponctuation ;
- Combination
- Il est de nature combinatoire, car on peut produire différentes expressions et potentiellement un code source infini ;
- Conventions
- Il est de nature conventionnelle et arbitraire, car le fait d’utiliser certains mots et une certaine syntaxe est décidé par les créateurs du langage ;
- Évolution
- Il évolue dans le temps, car de nouveaux mots ou de nouvelles possibilités syntaxiques peuvent s’ajouter ou disparaître du langage lorsqu’une nouvelle version est introduite.
Approche pragmatique à la programmation
Si on intègre les aspects conceptuels et techniques de la programmation, on peut obtenir une sorte de définition pragmatique similaire à celle-ci :
Cette définition peut s’adapter à tout type de programme: un algorithme qui permet de mieux comprimer la taille d'un fichier audio sans perdre en qualité sonore, un logiciel de traitement de texte, un système d'exploitation ou encore un portail web comme Moodle. Dans cette approche pragmatique, nous considérons la programmation comme la phase d’implémentation d’une application destinée à d’autres utilisateurs. Cela se traduit par le fait qu'une partie des inputs utilisés par l'agorithme est déterminée par les utilisateurs eux-mêmes. Ce principe est à la base de l'interactivité : plus une application est interactive, plus les manipulations de l'utilisateur seront utilisées en tant qu'input pour déterminer l'output.
Anatomie d'une application interactive
Dans une application interactive (e.g. un logiciel, une application web, une application pour smartphone, etc.), on peut souvent identifier trois composantes :
- Une partie graphique
- L'interface utilisateur (Graphic User Inerface, GUI) présente des éléments « visibles » sur l’interface et permet aux utilisateurs de fournir des inputs et/ou de recevoir les outputs du programme.
- D’autres éléments
- Il s'agit de toute sorte de extension de l'application qui peut être utile pour le programme, comme par exemple une base de données pour sauvegarder, récupérer, modifier ou effacer des données ; un espace de stockage pour sauvegarder les outputs du programme ; ou encore le web pour récupérer des informations en temps réel, etc.
- Une partie logique
- Elle régit le I/O du programme en termes de causalité (e.g. si je clique sur le bouton A, il se passe B, si je clique sur le bouton C, il se passe D). La partie logique est normalement censée changer la partie graphique en présentant une évolution de l’état initial qui atteint la solution envisagée, ou qui néanmoins représente un état plus intéressant pour l’utilisateur. En même temps, elle sert d' « intermédiaire » entre le programme et les éléments externes, par exemple en indiquant à la base de données quelles données récupérer ou au système d'exploitation quel fichier sauvegarder.
Formellement, seule la partie logique est nécessaire à un programme (e.g. algorithme pour comprimer une fichier audio), mais dans une perspective interactive, les deux autres éléments sont souvent présents. L’interface graphique est censée faciliter l’interaction homme-machine (décrite plus haut dans la page), tandis que l’intégration avec d’autres éléments est souvent nécessaire pour « prolonger » les fonctionnalités du programme et atteindre ainsi les objectifs de l’utilisateur.
Ainsi, de manière plus concrète, programmer correspond à définir la partie logique d’une application pour qu’elle puisse mener à bien une ou plusieurs tâches qui contribuent à résoudre un problème ou à répondre à un besoin. Pour ce faire, il faut créer les algorithmes correspondant aux comportements attendus. Les langages de programmation diffèrent dans la manière de constituer les instructions qui forment les algorithmes (i.e. écrire le code source) mais on retrouve souvent des éléments communs qui représentent des éléments fondamentaux de la programmation. Parmi ces éléments figurent :
- Les variables
- Les opérateurs
- Les structures de contrôle
- Les boucles
- Les fonctions
- Les tableaux (ou array)
- Les objets
- Les événements
- Les expressions régulières
Les variables
Comme le nom l’explique, les variables sont des éléments qui sont censés changer à un moment donné dans la logique de l’application. En même temps, comme dans les formules mathématiques ou physiques (e.g. vitesse), elles permettent d’identifier une valeur avec un nom : chaque fois qu’on fait référence au nom de la variable, elle sera substituée dans l’algorithme par la valeur correspondante à ce moment dans la logique de l’application.
De manière métaphorique, on peut penser aux variables comme des boîtes avec des étiquettes. Les boîtes peuvent contenir un ou plusieurs éléments, et l'étiquette sert en tant que référence symbolique pour indiquer l'élément ou les éléments contenu dans la boîte. Une fois que la boîte à sa propre étiquette, on peut utiliser celle-ci pour faire référence à tous les éléments contenus. Ces éléments peuvent changer dans le temps, mais l'étiquette servira toujours pour référencer cette boîte en particulier. La métaphore est néanmoins limité par les contraintes physiques des boîtes, tandis que pour les variables on peut avoir toute sorte de cas de figure : des variables qui sont utilisés comme des références à d'autres variables ; des variables qui sont contenues à l'intérieur d'autres variables ; des variables qui sont utilisées à l'intérieur de plusieurs autres variables.
Parmi les différentes utilités des variables, on peut en identifier deux principales :
- Modifier la valeur associée à travers la logique de l’application
- C'est l'une de manière les plus utilisées pour garder une trace de l'évolution de l'application suite à son utilisation. Par exemple dans le cas du « score » dans un jeu, celui-ci est destiné à augmenter (ou diminuer) selon les objectifs atteints par le joueur ;
- Réutiliser dans différents endroits du code source une valeur sans avoir à la répéter littéralement à chaque fois
- Il est plus pratique d'écrire le nom d'une variable tel que "PI" plutôt que saisir à chaque fois 3.141592653589793. Dans certains langages de programmation, on utilise dans ce contexte plutôt des constantes justement parce qu'elle ne sont pas censées varier. Une fois définit, une constante va garder la même variable pendant toute la logique de l'application.
Dans la littérature technique, aux variables sont souvent associées les actions suivantes :
- Déclaration d’une variable : cela correspond à créer une variable, c’est-à-dire à insérer pour la première fois une variable dans la logique de l’application ;
- Affectation/Assignation d’une variable : cela correspond à associer une valeur à la variable, ce qui se fait normalement grâce à un opérateur d’affectation (par exemple le symbole = ) ;
Selon le langage de programmation utilisé, il faut également définir à quel type de valeur/de donnée une variable va être associée. Parmi les types de données plus fréquentes, on identifie :
- Les suites de caractères (string) : elles sont utilisées pour représenter du texte (des mots, des phrases, etc.) ;
- Les chiffres (nombre entier, à virgule flottante, etc.) : ils sont utilisés surtout avec des opérateurs mathématiques ;
- Les valeurs booleans : elles sont des valeurs dichotomiques (soit vrai, soit faux) ;
- Les tableaux (array) : ils sont utilisés pour créer des listes avec des indices qui permettent de récupérer la valeur associée;
- Les objets : ils sont des conteneurs qui peuvent inclure souvent tout type de données, y compris de sous-objets.
Le type de variable est important, car elle détermine les types de manipulations qu’on peut faire. Par exemple, dans le cas d’une variable qui contient un nombre entier, on peut effectuer des opérations mathématiques ; pour une suite de caractères, on peut transformer le texte (mettre tout en majuscules, remplacer certains mots, etc.) ; pour un array, ajouter ou enlever des éléments de la liste ; etc.
Les opérateurs
Les opérateurs permettent de manipuler ou comparer des valeurs, notamment des variables. Parmi les opérateurs utilisés fréquemment dans tout langage de programmation on identifie :
- Les opérateurs mathématiques : addition, soustraction, multiplication, division, etc.
- Les opérateurs de comparaison (égalité, différence, majeur ou mineur)
- Les opérateurs logiques (AND et OR)
Les structures de contrôle
Les structures de contrôle permettent d’exécuter seulement certaines instructions d’un programme selon la vérification d’une ou plusieurs conditions. La version sémantique la plus répandue des structures de contrôle équivaut à l’inférence logique « si… alors… ». Le type de mécanisme de contrôle peut concerner différents niveau de granularité. Par exemple :
- Si l'utilisateur clique sur le bouton rouge, alors cache l'image verte ;
- Si l’utilisateur a fait le login, alors affiche son profil utilisateur ;
- Si le score est supérieur à 100, alors termine le jeu avec un applaudissement de félicitation ;
- Si le timer de la tâche a échoué, alors redirige l'utilisateur sur la page du questionnaire d'évaluation ;
Les structures de contrôle sont parmi les éléments les plus utilisés dans la création des algorithmes car elles permettent d’adapter le comportement de l’application à certaines conditions qui ont été prévues à l’avance, pour que le programme puisse fournir un output adapté. De plus, elles peuvent déterminer également l'exécution (ou pas) de certaines instructions selon le schéma :
- Si cette condition s'avère, alors...
- Exécute l'instruction #1
- Exécute l'instruction #2
- Exécute l'instruction #9
- Si non...
- Exécute l'instruction #7
- Exécute l'instruction #10
Les boucles
Les boucles sont à la base d’un concept très utile en programmation : l'itération. L'itération permet d’exécuter de manière recursive une ou plusieurs opérations (les mêmes ou différentes) à tous les éléments qui font partie de la liste itérée. Les boucles sont par exemple très utiles en relation avec les tableaux ou les bases de données, car elles permettent d’effectuer des opérations sur tous les éléments contenus dans une liste (e.g. pour chaque étudiant présent dans un cours, on peut afficher son nom et récupérer la moyenne de ses notes de manière automatisée). Les boucles sont également utilisées pour créer des éléments de manière récursive, ce qui peut être utile par exemple dans un jeu qui propose un nombre d'obstacles proportionnel au niveau du joueur. On peut créer une boucle qui disperse des obstacles selon le rapport niveau de jeux * 2. À ce moment, la boucle va faire une itération 2 fois pour le premier niveaux, 4 fois pour le deuxième, etc.
De manière sémantique, une boucle correspond à instruire le programme de faire quelque chose jusqu’à ce qu’une condition ne s’avère pas. Dans l'exemple précédent, cette condition équivaut à donner l'instruction :
- Crée des obstacles et disperse-les jusqu'à ce qu'on en a deux fois le niveau actuel.
- Lorsqu'on a atteint ce nombre d'obstacle, arrête de créer des obstacles.
En effet, une des caractéristiques fondamentales des boucles est qu’elles doivent se terminer à un moment donné dans la logique de l’application. Pour ce faire, on utilise très souvent une variable (voir plus haut) qui mémorise une valeur et met à jour cette valeur après chaque itération. La boucle évalue donc au prochain tour si cette nouvelle valeur respecte encore le critère de vérification. Si elle le fait, alors la boucle continue ; si non, la boucle s'arrête.
- Exécute les instructions suivantes jusqu'à ce que le nombre d'obstacles créés est mineur ou égale à 16
- Crée l'obstacle
- Augmente le nombre d'obstacles crées d'une unité
Après la 16ème itération, le nombre d'obstacles créés ne sera plus mineur ou égale à 16 et par conséquent la boucle s'arretra.
Les fonctions
Les fonctions représentent une sorte de "programme dans le programme", car elles sont la première forme d'organisation du code. On utilise des fonctions pour regrouper des instructions et les appeler sur demande : chaque fois qu'on a besoin de ces instructions, il suffira d'appeler la fonction au lieu de répéter toutes les instructions. Pour accomplir ce rôle, le cycle de vie d'une fonction se divise en deux :
- Une phase unique dans laquelle la fonction est déclarée (i.e. créée)
- On définit à ce stade toutes les instructions qui doivent être groupées pour obtenir le résultat souhaité ;
- Une phase qui peut être répétée une ou plusieurs fois dans laquelle la fonction est exécutée (i.e. appelé)
- On demande à la fonction de mener à bien toutes les instructions dont elle se compose à un moment donnée dans la logique de notre application.
On peut imaginer d'utiliser une fonction dans le jeu morpion (i.e. Tic-tac-toe). Cette fonction sera appelé chaque fois que l'utilisateur ajoute un nouveau symbole dans une case. À minima cette fonction devrait exécuter les instructions suivantes :
- Contrôler que la case n'est pas déjà occupée
- Contrôler que le symbole appliqué soit différent du précédent (pour garantir l'alternance)
- Contrôler si, suite à l'ajoute de ce symbole, un tris a été formé dans l'une des directions permises par les règles du jeu
- Si un tris est créé, alors le jeu s'arrête et le jouer gagne le point;
- Si aucun tris a été créé, alors le jeu continue
- Contrôler s'il reste des cases vides
- S'il reste au moins une case vide, le jeu se continue
- Si non, le jeu s'arrête
Si on utilise une notation formelle pour exprimer cette logique, on peut identifier la fonction qu'on vient de créer avec le symbole générique F() et lui passer un argument qui correspond au nombre de la case de 1 à 9 en tant que input X. Donc on aura :
F(X)
qui peut assumer selon la dynamique du jeu les valeurs :
- F(1)
- F(2)
- F(3)
- ...
et générer selon la logique interne de la fonction un output correspondant :
- Continuer l'alternance
- Arrêter car l'un des joueurs à gagné
- Arrêter car il n'y a plus de cases disponibles
Les tableaux (array)
Les tableaux (ou array en anglais) sont des listes indexées d'éléments qui partagent normalement une certaine rélation sémantique pour appartenir à la liste. Un exemple tout simple d'array est la liste des courses : on peut indexer cette liste en fonction de l'ordre des articles à acheter :
- Lait
- Farine
- Pommes
- Fromage
Par la suite, on peut se référer aux éléments dans notre liste avec l'index. Par exemple vous pouvez barrer le deuxième élément de votre liste lorsque vous avez mis de la farine dans votre panier, ou ajouter un cinquième élément parce que vous avez besoin de quelque chose d'autre. Veuillez noter que dans la plupart des langages informatiques, on commence à compter à partir de zéro, donc l'index du lait serait 0, de la farine 1, etc.
La plupart des éléments d'un système informatique qui s'occupent du stockage de données (e.g. Base de données, gestionnaire de fichiers, ...) sont de quelques sorte une extension du concept de array, car les items individuels stockés peuvent être récupérés à partir d'un index. La flexibilité de ce principe permet d'associer à un index toute sorte de valeur, et de pouvoir le manier (récupérer, modifier, effacer, ...) par la suite à travers la référence à cet index.
Les objets
On dit souvent en informatique qu'un langage est "orienté aux objets". Un objet en programmation est un élément qui possède des caractéristiques (appelées propriétés) et qui peut normalement exécuter certaines fonctions (appelées méthodes). On peut imaginer des objets par exemple dans un jeu comme Super Mario Bros. Les différents ennemis qu'il faut éviter pendant le jeu sont des objets, et selon le type d'ennemi (c'est-à-dire le type d'objet), ils varient en fonction :
- De leur caractéristiques (propriétés) : la couleur, la forme, les coups nécessaires pour les faire disparaître, etc.
- Des actions (méthodes) qu'ils peuvent effectuer: sauter, lancer des objets, etc.
Chaque fois qu'un ennemi (objet) d'un certain type se présente à l'écran, il est une instance du type d'ennemi auquel il appartient. En tant qu'instance, il partage avec les autres ennemis de son type les mêmes propriétés et méthodes, mais il est en même temps unique, car lorsque vous le tuez, c'est seulement lui (et pas tous les ennemis de ce type) qui va disparaître.
Pour rester sur le même exemple, on peut identifier Mario et Luigi comme appartenant au même type d'objet (e.g. personnage principal) : ils partagent les mêmes méthodes (sauter, courir, ...) mais ils sont différents dans certaines propriétés (couleur de la casquette, etc.).
Les événements
On parle d’événement lorsque la logique de l’application prévoit l’exécution de certaines instructions qui sont liées à une modification de l’état actuel du programme. Les événements peuvent être liés à plusieurs aspects, comme par exemple :
- Les événements liés aux manipulations de l’utilisateur
- Cliquer sur le bouton de la souris, sur la touche du clavier, déposer un objet après l'avoir glissé sur une cible, ...
- Les événements liés au temps
- La disparition d’un message après 10 secondes, le temps limite pour terminer un QCM, la mise à jour d'un graphique chaque 5 minutes, ...
- Les événements liés aux ressources internes ou externes à l’application
- L'établissement d'une connexion à une base de données, la fin du téléchargement d’une image, le démarrage de la lecture d'une vidéo, ...
Les événements sont à la base d'un type de programmation qu'on appelle asynchrone, car le code ne sera pas exécuté progressivement, dès que l'interprète du langage le lit. Il sera plutôt exécuté dans un deuxième temps, un temps que souvent nous ne pouvons pas prévoir à l'avance :
- À quel moment précis un utilisateur va cliquer sur un bouton dépend de la décision de la personne, sa dextérité, le temps de réaction pour identifier et pointer le bouton, etc.
- À quel moment précis se termine le téléchargement d'une image dépend de la réactivité du serveur qui la héberge, de la qualité de la connexion, etc.
Pour cette raison, on crée des gestionnaires d'événements qui s'occupent de:
- Définir quel sera l'événement déclencheur
- Il s'agit de manière générale d'une "nouveauté" par rapport à la situation actuelle. Un changement qui se produit et qui peut être déterminé, comme on l'a vu plus haut, par différents sources.
- Exécuter les instructions souhaitées suite au déclenchement de l'événement
- C'est la règle de comportement de l'application qui s'occupe de réagir à la "nouveauté" en fonction des intentions du programme/développeur. Le même événement peut avoir toujours la même réaction ou avoir une réaction différente en fonction d'autres éléments contextuels à l'état de l'application. Imaginez un jeu point-and-shoot qui lance un projectile chaque fois qu'on appuie sur la barre espace du clavier, à condition qu'on les ait pas épuisés.
Les expressions régulières
Parmi les nombreuses difficultés qu'on peut rencontrer dans la programmation, les expressions régulières sont parmi les plus compliquées à maîtriser. Néanmoins, elles sont fondamentales au fonctionnement de plusieurs concepts informatiques, y compris les langages de programmation eux-mêmes. Les expressions régulières permettent en effet d'identifier des patterns à l'intérieur d'une source d'information de référence (par exemple un texte).
Grâce a des règles d'identification très complexes, on arrive à identifier des éléments comme appartenant au même pattern, même avec des degrés de différences importants. Par exemple il existe des expressions régulières qui permettent d'identifier si une suite de caractères représente ou pas un URL valide indépendamment du fait que le texte propose :
- Le protocole http:// ou https://, ou pas de protocole du tout
- Le format www.domain.extension, seulement le format domain.extension, ou un ou plusieurs sous-domains (e.g. tecfa.unige.ch)
- Un, plusieurs ou aucun chemin (i.e. path) après le domain (e.g. tecfa.unige.ch/go/to/some/specific/directory)
Conclusion
Dans cette page nous avons proposé trois approches différentes, mais complémentaires, à la programmation :
- L'approche conceptuelle suggère que la programmation est tout d'abord une activité mentale, une manière de penser, qui consiste à computer une solution en décomposant un problème en plusieurs étapes ;
- L'approche technique identifie la programmation en tant que trait d'union entre le langage humain et le langage des machines. Cette traduction se fait à l'aide d'algorithmes qui déterminent comment un programme doit gérer/transformer des données de input en données de output ;
- L'approche pragmatique combine les approches conceptuelles et technique en identifiant des éléments communs à la plupart des langages/techniques de programmation : les blocs constitutifs des algorithmes qui permettent de fournir des outputs satisfaisants par rapport aux inputs fournis.
La perspective qui permet de passer d'une représentation abstraite de la programmation à une image concrète, telle qu'un logiciel ou un jeu multi-utilisateur, consiste à s'imaginer une énorme quantité d'instructions (i.e., algorithmes) qui sont amplement déterminés ou influencés par les utilisateurs eux-mêmes (à travers des actions/inputs). Lorsqu'on comprend les éléments constitutifs de la programmation (variables, boucles, ...), le développement de systèmes complexes se réduit à deux aspects :
- Gérer la complexité
- Savoir s'orienter dans le labyrinthe du code source et savoir identifier les "intentions" de chaque bout de code : comment et pourquoi ces instructions contribuent à la solution du problème ;
- Planifier des objectifs atteignables
- Disposer d'assez de temps et de connaissances (ou de "force de travail") pour traduire en code tous les éléments constitutifs du programme (logique, interface, sauvegarde des données, etc.).
Ressources
Scratch
Développé par le MIT, Scratch permet d'appliquer les aspects fondamentaux de la programmation à travers une interface drag&drop. Pour sa simplicité, il est souvent utilisé pour introduire les néophytes de tout âge à la programmation. Essayer un tutoriel de Scratch peut être une bonne manière pour consolider les aspects techniques illustrés dans cette page.
- Scratch sur ce Wiki
- Site officiel de Scratch
JavaScript
Dans le cadre du cours STIC:STIC I, les bases de la programmation sont abordées en utilisant JavaScript, un langage de scripting qui peut être maîtrisé à plusieurs niveaux : les débutants peuvent assez facilement ajouter de l'interactivité à des pages web, mais le langage permet également de développer des applications complexes.
Programming Boty
Programming Boty est un kit de construction destiné à proposer une initiation à la programmation informatique afin d'initier à la pensée / la logique informatique. Il a été développé dans le cadre du cours STIC III (2016) par Lydie Boufflers et Sophie Linh Quang.
Cours Online
À présent (2016), beaucoup de cours proposés online (i.e. MOOCs) sont liés à l'informatique (Computer Science en anglais). On peut trouver des cours d'introduction ainsi que des cours axés sur des technologies/langages plus spécifiques.
Nand2Tetris
L'un des cours qui a eu un certain succès est le projet Nand2Tetris créé par Noam Nisan et Shimon Schocken dans lequel il est possible de créer, à partir d'éléments physiques séparés, un ordinateur fonctionnel et de le programmer pour pouvoir enfin jouer au jeu Tetris. Le projet est divisé en deux cours qui sont disponibles sur la plateforme Coursera. Le premier cours s'intéresse à la partie hardware, tandis que le deuxième est consacré à la partie software. Le projet est également lié à un livre "The Element of Computing System", MIT Press, et tous le matériel est disponible sous licence open-source avec la possibilité de le modifier dans des contextes éducationnels non-profit.
W3Cx
Le World Wide Web Consortium (W3C), organisme qui s'occupe des standard web, organise en partenariat avec la plateforme MOOC EdX des cours portant sur HTML5, CSS et JavaScript.
Liste de langages de programmation
Voici une liste arbitraire et non exhaustive des langages les plus utilisés, avec une petite description. Pour une liste complète voir la liste sur Wikipedia :
- ActionScript : utilisé dans les applications qui utilisent Adobe Flash
- ASP.NET : langage propriétaire de Microsoft, utilisé pour le développement d’application web
- C : langage pour la programmation système, il existe des « évolutions » telles que C++ ou C#
- ECMAScript : standard à la base d’autres langages tels que C++, ActionScript ou JavaScript
- Java : langage dont l’objectif principale est la portabilité entre plateforme
- JavaScript : langage utilisé surtout dans la programmation web côté client et dans Node.js
- Objective-C : langage utilisé surtout dans l’environnement Apple
- Perl : langage utilisé surtout en relation avec des fichiers de texte
- PHP : langage open-source très utilisé dans le développement de site web
- Python : langage utilisé souvent (mais pas seulement) dans les milieux académiques
- R : langage utilisé surtout en relation avec le traitement statistique des données
- Scheme : langage de programmation fonctionnel dérivé du langage Lisp
- Visual Basic : langage utilisé dans l’environnement Microsoft
- XSLT : langage de transformation de XML
La Free Ebook Foundation propose sur GitHub une liste de livres numériques gratuits sur différents langages de programmation. Il existe des listes dans plusieurs langues, la plus fournie est en anglais, mais il existe aussi une liste en français.
Bibliographie
- Denning, P. J., & Martell, C. H. (2015). Great Principles of Computing. Cambridge, MA: MIT press.
- Petzold, C. (2000). Code. The Hidden Language of Computer Hardware and Software. Redmond, WA: Microsoft Press.