Introduction à la programmation
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érentes 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, 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 ennemies (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’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 outils à 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 :
- Une application est efficace si elle permet d’obtenir l’output souhaité à partir d’inputs identifiables.
- Une application est efficiente si le nombre d’inputs nécessaires est proportionnel à la qualité/complexité de l’output.
- 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.
On peut utiliser une similitude avec les langues naturelles pour expliquer la différence entre les deux types de langage. Le dictionnaire d’une langue étrangère représente une sorte de langage de bas niveau, car il met à disposition tous les mots de cette langue. Cependant, quelqu’un qui ne parle pas la langue aura du mal à s’exprimer en s'aidant seulement d’un dictionnaire. Au contraire, un langage de haut niveau peut être comparé à un guide linguistique pour touristes qui contient les phrases les plus utilisées pendant un séjour à l’étranger. Contrairement au dictionnaire, le guide ne présente pas tous les mots disponibles dans cette langue, mais permet par contre de formuler quelques phrases basilaires même pour des personnes qui ne connaissent pas la langue.
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 à tout autre langage humain. En effet, du moment que les interprètes/comiplateur traduisent le langage de haut niveau, les caractéristiques de celui-ci peuvent être determiné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 :
- Il dispose d’un lexique, c’est-à-dire une liste de mots qui ont une signification particulière ;
- Il dispose d’une syntaxe, c’est-à-dire des règles d’associations de mots et de la ponctuation ;
- Il est de nature combinatoire, car on peut produire différentes expressions et potentiellement un code source infini ;
- Il est de nature conventionnelle et arbitraire, car le fait d’utiliser certains mots et une certaine syntaxe est décidée par les créateurs du langage ;
- 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 :
Un programme est une solution automatisée qui permet à des utilisateurs d’obtenir, à partir de certains inputs, des outputs qui contribuent à résoudre un problème initial ou à répondre à un besoin.
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 (Graphic User Inerface, GUI) qui 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 qui peuvent être utiles pour le programme tels qu’une base de données pour sauvegarder, récupérer, modifier ou effacer des données, comme un espace de stockage pour sauvegarder les outputs du programme ainsi que le web pour récupérer des informations en temps réel, etc.
- Une partie logique qui 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 événements
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. 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, 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 à le définir à chaque fois, par exemple il est plus pratique d'écrire le nom d'une variable tel que "PI" plutôt que saisir à chaque fois 3.141592653589793.
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 utilisés dans la programmation « orientée aux objets » qui est une forme de programmation avancée.
Le type de variable est important, car elle détermine les types de manipulation 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ère 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 plus répandue des structures de contrôle équivaut à l’inférence logique « si… alors… » (e.g. si l’utilisateur a fait le login, alors afficher son profil utilisateur).
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é.
Les boucles
Les boucles sont à la base d’un concept très utile en programmation : la réitération. La réitération permet d’exécuter une ou plusieurs instructions plusieurs fois de la même manière. 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 crée cycliquement des obstacles à éviter ou des objets à intercepter.
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. Par exemple on peut dire au programme de créer des nouveaux ennemis dans un jeu jusqu’à ce que le joueur n’ait pas atteint un certain score. En effet, une des caractéristiques fondamentales des boucles est qu’elles doivent se terminer à un moment donné dans la logique de l’application.
Les fonctions
Les fonctions en programmation jouent un rôle similaire aux schémas cognitifs en psychologie. L’action d’aller au restaurant se compose d’une série de « sous actions » séquentielles qui se répètent normalement à chaque expérience : choisir le restaurant, y aller, lire le menu, choisir parmi les suggestions, communiquer le choix au serveur, manger, payer, sortir. De la même manière, une fonction en programmation regroupe de manière structurée des instructions qui « vont ensemble ». On peut penser par exemple à une fonction de login qui exécute les instructions suivantes :
- Récupérer le nom d’utilisateur et le mot de passe
- Contrôler que les données saisies correspondent aux données présentes dans la base des données des utilisateurs
- Garantir l’accès ou afficher un message d’erreur si les données ne correspondent pas
Souvent les fonctions sont créées pour exécuter un groupe d’instructions qui se répètent plusieurs fois dans la logique de l’application. Par exemple, dans un logiciel de traitement de texte, on peut avoir une fonction de sauvegarde du fichier dont les instructions (fictives) ressemblent à celles-ci :
- Récupérer l’état actuel du document
- Récupérer la position du fichier dans le disque dur de l’ordinateur
- Supprimer l’ancienne version
- Sauvegarder la nouvelle version
On peut imaginer que la fonction de sauvegarde soit exécutée à chaque fois que l’utilisateur clique sur un bouton correspondant, mais également à des intervalles régulières de façon automatique. Dans les deux cas, la fonction de sauvegarde pourra être utilisée car elle exécute les mêmes instructions.
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, etc.
- Les événements liés au temps: la disparition d’un message après 10 secondes, le temps limite pour reserver des tickets online, etc. ;
- Les événements liés aux ressources internes ou externes à l’application: la connexion à une base de données, la fin du téléchargement d’une image, la fin d'une vidéo, etc. ;
- ...
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: on ne peut pas savoir à quel moment précis un utilisateur va cliquer sur un bouton, par exemple. Pour cette raison, on crée des gestionnaires d'événements qui s'occupe de:
- Définir quel sera l'événement déclencheur
- Exécuter les instructions souhaitées suite au déclenchement de l'événement
Ressources
Scratch
Développé par le MIT, Scratch permet d'appliquer les aspects fondamentales 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.
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.
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
- Visual Basic : langage utilisé dans l’environnement Microsoft
- XSLT : langage de transformation de XML
Bibliographie
- Petzold, C. (2000). Code. The Hidden Language of Computer Hardware and Software. Redmond, WA: Microsoft Press.