Concepts et définitions

Algorithmique et programmation

Introduction

Vous reverrez dans cette partie les notions d'algorithme, de programme, d'instructions, de commentaires, de variables, de la déclaration de variable avec const let ou var, et de fonction.

Algorithme

Un algorithme est une méthode pour résoudre un problème donné sous forme d'un ensemble d'instructions.

Un algorithme est (1) une méthode (2) pour résoudre une problème (3) sous forme d'instructions. Si ce n'est pas une méthode, ce n'est pas un algorithme, si cela ne résout pas un problème, ce n'est pas un algorithme non plus, si ce n'est pas sous forme d'instructions, ce n'est pas un algorithme. Par exemple, un théorème n'est pas un algorithme car il ne dit pas stricto sensu comment résoudre le problème. Pour le théorème de Pythagore, A²+B²=C² ne permet pas directement de trouver la longeur d'un côté d'un triangle rectangle. Les instructions seraient: prendre la racine carrée de C²-B² pour trouver A, celle de C²-A² pour trouver B et celle de A²+B² pour trouver C.


Un algorithme est un objet abstrait, non implémenté et indépendant de la notation utilisée pour le représenter

Un algorithme est indépendant de la manière dont il est représenté, c'est un concept. Bien qu'on puisse le représenter sous certaines formes (organigrammes, pseudo-code) de manière à le communiquer ou à l'utiliser, un algorithme n'a pas de forme, de représentation ou de langage pour le représenter. Cela est une différence avec un programme qui sera écrit dans un langage de programmation.

Un algorithme résout un problème une et une seule instruction à la fois

Un algorithme permet de résoudre un problème en réalisant une série d'instructions. Une seule et une seule instruction est réalisée à la fois.


Un algorithme ne nécessite pas de prise de décision

Un algorithme décrit étape par étape les instructions, et il n'y a qu'un seul choix possible à chaque étape.


Un algorithme a toujours un résultat final

Un algorithme présente toujours un résultat final, car il a pour but de résoudre un problème donné. L'algorithme résout donc ce problème d'une part, et d'autre il part a toujours une fin.


Un algorithme ne décrit pas les niveaux élémentaires des instructions

La granularité de l'algorithme n'est pas infinie. On ne décrit pas toutes les actions sous forme de sous-actions et elles-mêmes sous forme de sous-sous actions. Bien que le concept soit flou, on utilise directement des instructions qui sont assez triviales pour être utilisables: si l'utilisateur d'un algorithme sait comment faire une multiplication, attraper un objet, allumer une machine, lire un texte, ces instructions ne seront pas elles-mêmes décrites dans l'algorithme, et constituerons le premier niveau de granularité.

Programme

Un programme est un ensemble d'instructions qui peut resoudre un problème, plusieurs problèmes ou aucun problème

Contrairement à un algorithme, un programme n'est pas tenu de résoudre un et un seul problème donné. Il peut ne résoudre aucun problème, en résoudre un (souvent, la transcription concrête d'un algorithme) et même souvent en résoudre plusieurs pour articuler un ensemble d'algorithme autour d'une finalité plus grande. Par exemple, il y a plusieurs algorithmes impliqués dans la réalisation d'un jeu vidéo entre la gestion des personnages, des mondes, de l'inventaire, de la detection des collisions, etc.


Un programme est un objet concret, implémenté et dépendant de la notation utilisée pour le représenter

Contrairement à un algorithme, un programme est dépendant de la manière dont il est représenté, c'est l'implémentation concrète (ex: un fichier) d'un objet abstrait. Le programme est représenté dans un langage de programamtion donné. Un programme n'est pas le même si l'on change le langage de programmation. Un programme est compréhensible et utilisable par une machine correctement configurée.


Un programme peut externaliser la prise de décision (ex: demander à l'utilisateur)

Un programme peut se référer à l'utilisateur pour effectuer un choix, sans avoir les instructions pour réaliser ces choix ou actions. On peut utiliser la génération de nombres aléatoires ( "random").


Un programme peut ne pas avoir de résultat final

Un programme n'a pas toujours un résultat final. Il existe des cas où un programme ne résout pas un problème d'une part (bug, cas non pris en compte, site web), et d'autre il est possible qu'un programme soit destiné à tourner indéfiniement ou ne rencontre jamais une condition de fin.


Un programme ne décrit pas les niveaux déjà implémentés dans le langage de programmation

La granularité d'un programme s'arrête aux niveaux des éléments existants dans le langage de programmation utilisé. Ce langage permet de faire le lien entre les 0 et les 1 compris par l'ordinateur, et les instructions données par les humains. Le code source d'un programme est code écrit dans un langage de programmation qui va être traduit en binaire (utilisable par l’ordinateur).


Instructions

Les informations de ce paragraphe sont transposables aux programmes et ne sont pas limitées aux algorithmes.

Les instructions sont les actions "atomiques" dans un algorithme

On entend par actions atomiques les plus petites actions faisant du sens. On pourrait dire les actions "élémentaires". Par exemple, l'action "diviser" ne constitue pas une action concrête; et n'est donc pas une instruction. En revanche "diviser a par b" est une instructions car on peut faire cette action.

Un algorithme effectue une instruction à la fois, selon une séquence définie. On represente souvent une instruction par ligne si on le représente en pseudo-code.


Les instructions sont des actions effectuées "à leur tour"

Les instructions sont présentées les unes après les autres dans un algorithme. Chaque instruction est effectuée, puis l'on passe à l'instruction suivante, et ainsi de suite.


Les instructions peuvent être organisées en blocs d'instructions

Les instructions peuvent être regroupées dans un bloc d'instructions. Quand on arrive, dans un algorithme, dans un bloc d'instructions, on verifie si doit utiliser ou non le bloc d'instructions. Si on l'utilise, chaque instruction du bloc est effectuée, puis l'on passe à l'instruction suivante, et ainsi de suite. On passe à la suite de l'algorithme quand le bloc d'instruction est fini d'être utilisé. Si on n'utilise pas le bloc d'instructions, on saute l'ensemble du bloc d'instructions (i.e. toutes les instructions contenues dans celui ci) et on continue l'algorithme.


Les blocs d'instructions peuvent être contextuels et leurs instructions utilisées seulement dans certaines conditions: Les Conditions

Les blocs d'instuctions conditionnels sont utilisés sous certaines conditions.

Si les conditions sont réunies au môment où l'on arrive à ce bloc d'instruction, les instructions dans le bloc d'instructions sont suivies. Si les conditions ne sont pas réunies au moment ou l'on arrive au bloc, les instructions du bloc sont sautées et on passe à la suite.


Les blocs d'instructions peuvent être répétés dans certaines conditions et leurs instructions utilisées autant de fois que nécéssaire: Les Boucles

Les blocs d'instructions qui se répètent sont appelées des boucles. Il y a une condition pour répéter les instructions, comme un nombre de répétitions (retourner deux cartes d'une pioche), des répétitions tant qu'il reste des éléments (retourner la carte du dessus d'une pioche tant qu'il y a des cartes, sans préciser le nombre de carte de la pioche), ou des conditions pour continuer (tant qu'il n'y a pas de gagnant, continuer à jouer).

Si les conditions de répétition sont réunies quand on arrive à ce bloc d'instruction, les instructions du bloc sont effectuées une fois de plus. Si les conditions ne sont pas réunies au moment ou l'on arrive au bloc, les instructions du bloc sont sautées et on passe à la suite.


Les blocs d'instructions peuvent être imbriqués (ex: des conditions et des boucles dans une boucle)

Un bloc d'instruction peut contenir d'autres blocs d'instuctions. Dans ce cas, si l'on rentre dans le premier bloc d'instructions, on va y executer à chaque fois toutes les instructions et blocs d'instructions à l'interieur de celui-ci dans l'ordre. On verifiera si les conditions pour effectuer ou répéter les blocs d'instuctions à l'interieur sont présents à chaque fois qu'on les rencontrera, et l'on continuera avec les instructions et blocs d'instructions suivants. Si on ne rentre pas dans le bloc d'instructions, on va sauter l'ensemble des instructions et blocs d'instructions qu'il contient et passer à la suite.

Commentaires

Les commentaires sont des informations (souvent du texte) à destination du lecteur de l'algorithme ou du programme

Il n'est pas rare de voir des commentaires dans des algorithmes et programmes, par exemple précédés de "//". Ces commentaires ne font pas partie de l'algorithme au sens strict. Ce ne sont pas des actions et donnent simplement des informations supplémentaires au lecteur.


Contrairement aux instructions les commentaires sont systématiquement ignorés

Les commentaires ne sont JAMAIS utilisés dans les algorithmes et lors de l'execution du programme. L'algorithme est identique si l'on enlève les commentaires, il ne s'agit jamais d'instructions.

Variables

Exemple d'illustration utilisé dans la suite: un casier contenant ou non des objets. Selon les cas et les langages de programmation, on ne peut simplement pas mettre un objet dans un casier s'il n'existe pas (bug) ou on va créer automatiquement un casier avec le bon nom s'il n'existait pas avant.

Les variables sont des éléments identifiables, souvent par un nom, qui peuvent prendre une valeur potentiellement amenée à évoluer au fil de l'execution de l'alogrithme ou du programme

Une variable est un élément « fixe » dans lequel on va stocker des valeurs « changeantes » ou non, et auquel on va pouvoir faire référence. Par exemple, on aura une variable appellée compteur, qui prendra les valeurs de 1 à 10. Quand je ferais référence à la variable compteur grâce à son nom, je fais référence à ce compteur, et je peux connaitre la valeur en cours, entre 1 et 10.

Deux variables peuvent avoir la même valeur à un moment donnée, par exemple agePersonne1 et agePersonne2 peuvent valoir 18 ans dans les deux cas, mais cela reste deux variables.

En JavaScript, deux variables ont forcément des noms différents, car ils s'agit de l'adresse pour les retrouver. Sinon, si on utilise le même nom, cette variable ne gardera que la dernière valeur donnée.

Dans notre exemple d'illustration, la variable est un casier. On peut y mettre un objet (une valeur) à l'interieur. Ce casier a un nom affiché sur une étiquette. Cette étiquette permet d'y faire référence même si le casier change d'endroit dans la pièce. Je peux avoir deux objets identiques dans deux casiers différents: le casier1 a une paire de chaussures, et le casier2 a une paire identique. Cela reste deux casiers différents. En revanche, si je souhaite changer le nom du casier2 en casier1, comme le casier1 existe déja, j'enleverais seulement l'étiquette de casier1 pour la mettre sur casier2. Il n'y aura pas deux casiers1.

Les variables sont souvent des emplacements mémoires en programmation

En pratique, dans un programme, une variable est un emplacement mémoire dans lequel il y aura une valeur ou non. Le nom de la variable servira d'adresse pour retrouver cet emplacement et dire ce qu'il y a dedans.


Les variables sont créées (=déclaration)

Les variables doivent être créées, c'est à dire déclarées. Cela consiste à dire qu'à telle adresse ou qu'avec tel nom, nous faisons référence aux données stockées à tel endroit. Par exemple, je dis que je crée une variable compteur. Si cela est dit dans un langage de programmation, un emplacement en mémoire va être dédié à prendre les valeurs de compteur.

Dans notre exemple de programmation, la déclaration revient à apporter un casier (espace mémoir) et à y attribuer une étiquette avec le nom du casier (adresse mémoire, ou nom de variable).

On affecte des valeurs aux variables (=affectation)

Une variable peut prendre des valeurs. Par exemple, si j'écris compteur=2; la variable compteur contiendra 2.

Une variable garde la dernière valeur affectée. Par exemple, si j'écris compteur=2; compteur=3;compteur=10;compteur=4;compteur=3; la variable compteur contiendra 3.

Si je peux accumuler le contenu, il faut que ma variable prenne sa valeur précédente plus une nouvelle valeur. Par exemple, si j'écris compteur=2; compteur=compteur+3;compteur=compteur+10; la variable compteur contiendra 15 (compteur = 2, puis 2+3=5, puis 5+10=15).

Par ailleurs, je peux donner une valeur à la variable lors de la déclaration (l'espace mémoire est directement rempli par une valeur) ou non (l'espace mémoire existe mais reste vide).


Une fois que le casier existe, on peut y mettre des objets dedans ou il peut rester vide (=undefined en JavaScript). Par exemple, je peux dire "installer un casier appelé casier1" qui sera vide, ou "installer un casier appelé casier1 avec un T-shirt dedans" qui contiendra un T-shirt dès sa création.

Si je mets un objet dedans, je ne garde pas d'office les objets précédents mais je vide le casier avant d'y mettre le nouvel objet. Par exemple, si je dis "dans le casier1 il y a une paire de chaussure", le casier1 ne contiendra qu'une paire de chaussure. Si je dis "dans le casier1 il y a une paire de chaussure; dans le casier1 il y a un pull; dans le casier1 il y a des clefs; dans le casier1 il y a un pull", le casier1 ne contiendra qu'un pull.

Je peux accumuler du contenu: Si je dis "dans le casier1 il y a une paire de chaussures; dans le casier1 il y a le contenu du casier1 et un pull; dans le casier1 il y a le contenu du casier1 et des clefs; dans le casier1 il y a le contenu du casier1 et un pull", le casier1 contiendra une paire de chaussure, un pull, des clets et un autre pull (casier = une paire de chaussures, puis une paire de chaussures et un pull, puis une paire de chaussures, un pull et des clefs, puis une paire de chaussures, un pull, des clefs et un autre pull)


Javascript: const, var et let ou ⌀

Pour simplifier, en JavaScript, on peut déclarer des variables avec const, var ou let. Cela a un impact sur la possibilité de "changer" la valeur dans l'emplacement en mémoire (peut-on modifier le contenu du casier dans notre exemple illustratif) et sur la portée de "l'adresse" (dans notre exemple, ne peut-on avoir qu'un seul casier avec une étiquette donnée dans un batiment entier, ou des casiers peuvent-ils avoir la même étiquette tant qu'ils sont dans des pièces différentes)

Les const (constantes) ne changent pas d'emplacement en mémoire durant toute leur durée de vie et ont une portée de bloc

Si l'on déclare en Javascript une constante avec const (=on utilise const la première fois qu'on fait référence à son nom), elle aura entre autres les propriétés suivantes:

  • Portée ("disponibilité" ou "existence"):

    • si elle est déclarée avec const entre les accolades, elle n'existe qu'entre les accolades où elle a été définie. C'est à dire que l'on peut utiliser le même nom dans un bloc d'instructions totalement différent et dans les fonctions

    • si elle est déclarée en dehors d'accolades, c'est un peu plus compliqué:

      • si on déclare par ailleurs entre les accolades (avec un const, un var ou un let) une variable avec le même nom, on va créer une variable locale du même nom qui n'existe qu'entre les accolades. On ne modifiera donc pas la variable à l'exterieur des accolades, même si elle a le même nom. En dehors de ces accolades (bloc d'instuctions ou fonction), cette variable locale de même nom n'existera plus et on fera référence à la variable déclarée en dehors des accolades .

      • si on y fait référence sans déclaration, juste avec le nom, dans les accolades, elle aura la même valeur que la constante déclarée à l'exterieur des accolades (on fait référence à la variable globale)

      • si on y fait d'abord référérence sans déclaration à l'intérieur des accolades, on ne peut re-déclarer une variable locale du même nom en faisant une déclaration

  • Valeurs:

    • on est obligé de donner la valeur qu'aura la constante à la déclaration

    • on ne peut pas modifier la référence en mémoire de cette valeur:

      • les string, les booleans et numbers ne changeront pas de valeur

      • les cases d'un tableau (array) peuvent changer de contenu, car la constante contiendra le pointeur vers le tableau et non pas vers son contenu. Si son contenu change, cela sera répercuter. En revanche, on ne peut pas modifier le tableau auquel on fera référence.

      • le point précédent s'applique aux objets en programmation orienté objet.



Les variables var peuvent changer de valeur et ont portée de fonction

Si l'on déclare en Javascript une variable avec var (=on utilise var la première fois qu'on fait référence à son nom), elle aura entre autres les propriétés suivantes:

  • Portée ("disponibilité" ou "existence"):

    • si elle est déclarée avec var entre les accolades dans la déclaration d'une fonction, elle n'existera pas en dehors de la fonction. C'est à dire que l'on peut utiliser le même nom pour deux variables si l'une est en dehors de la fonction et l'autre dans la fonction

    • si elle n'est pas déclarée en avec var dans la déclaration d'une fonction:

      • si un argument de la fonction est une variable du même nom que la variable déclarée en dehors de la fonction, on ne modifiera pas la valeur de la variable à l'exterieur de la fonction

      • si aucun argument de la fonction est une variable du même nom que la variable déclarée en dehors de la fonction, on modifiera la valeur de la variable à l'exterieur de la fonction également

  • Valeurs:

    • on n'est pas obligé de donner une valeur de la variable à la déclaration (on peut déclarer une variable et ne pas lui donner de valeur)

    • on peut modifier la référence en mémoire de cette valeur:

      • la variable peut changer de valeur


Les variables let peuvent changer de valeur et ont une existence de bloc

Si l'on déclare en Javascript une variable avec let (=on utilise let la première fois qu'on fait référence à son nom), elle aura entre autres les propriétés suivantes:

  • Portée ("disponibilité" ou "existence"):

    • si elle est déclarée avec let entre les accolades, elle n'existe qu'entre les accolades où elle a été définie. C'est à dire que l'on peut utiliser le même nom dans un bloc d'instructions totalement différent et dans les fonctions

    • si elle est déclarée en dehors d'accolades, c'est un peu plus compliqué:

      • si on déclare par ailleurs entre les accolades (avec un const, un var ou un let) une variable avec le même nom, on va créer une variable locale du même nom qui n'existe qu'entre les accolades. On ne modifiera donc pas la variable à l'exterieur des accolades, même si elle a le même nom. En dehors de ces accolades (bloc d'instuctions ou fonction), cette variable locale de même nom n'existera plus et on fera référence à la variable déclarée en dehors des accolades .

      • si on y fait référence sans déclaration, juste avec le nom, dans les accolades, elle aura la même valeur que la variable déclarée à l'exterieur des accolades (on fait référence à la variable globale)

  • Valeurs:

    • on n'est pas obligé de donner une valeur de la variable à la déclaration (on peut déclarer une variable et ne pas lui donner de valeur)

    • on peut modifier la référence en mémoire de cette valeur:

      • la variable peut changer de valeur


Les variables ⌀ (sans var, ni let, ni const) peuvent changer de valeur et ont une existence globale

Les variables déclarées juste avec leur nom vont créer la variable comme si on avait déclarée une variable avec var en dehors de bloc d'instructions et de fonctions. Même si elles sont effectivements déclarées dans une fonction ou dans un bloc, elles vont exister en dehors. Si on les déclare sans var, let ni const dans une fonction, et qu'une variable existe en dehors de cette fonction avec ce nom, on va modifier la valeur de cette variable en dehors de la fonction.


Généralités: si l'utilisation convient, préférer const à let et let à var

Dès que l'on peut, il est intéressant d'utiliser const. Si cela ne convient pas, il est intéressant d'utiliser let. Si let ne convient pas, on peut utiliser var. En principe, il ne faudrait pas utiliser aucun des trois.

Les fonctions

Exemple d'illustration utilisé dans la suite: un guichet pour effectuer des actions.

Une fonction vise à réaliser une série d'instructions quand on l'exécute

Une fonction est un sous-programme visant à réaliser une action donnée à travers l’exécution d’une série d’instructions


Ce que fait une fonction est défini lors de sa déclaration

Une fonction doit être déclarée, c'est à dire que l'on indique ce qu'elle doit faire à chaque fois qu'on l'utilise.

Les personnes travaillant qu guichet savent quoi faire si quelqu'un se présente, tout est expliqué avant. Leur guichet a un nom qui les identifie. Si une personne extérieure veut utiliser l'ensemble des actions faites à ce guichet, pour elle ces actions se résument au nom du guichet. Le reste sera effectué à l'interieur du guichet sans autre intervention que de se présenter au guicher avec les bonnes informations.


Une définition / déclaration en JavaScript qui se compose comme suit:

  • Mot clef function

  • Nom de la fonction

  • Parenthèses entre lesquelles il y a ou non des arguments

  • Des accolades qui permettent de définir les instructions

  • Une fonction peut ou non renvoyer une valeur (mot clef return entre les accolades)


Ce que fait une fonction peut être défini n'importe où (dans le code)

Dans un programme, une fonction peut être définie à n'importe quel endroit du code accessible par le programme.

Les personnes travaillant qu guichet peuvent apprendre la procédure à suivre si quelqu'un se présente dans un manuel, où qu'il soit, et utiliser cette procédure au guichet.


Une fonction ne fait strictement RIEN jusqu'à ce qu'on l'utilise (=appel de fonction)

La déclaration d'une fonction n'entraine aucune action. Pour utiliser la fonction, il faut l'appeler. En JavaScript, on appelle une fonction en utilisant son nom (défini lors de la déclaration) suivi de parenthèses encadrant éventuellement les attributs.

Les personnes travaillant qu guichet savent quoi faire si quelqu'un se présente (= déclaration), mais ne font rien tant que personne ne se présente. Si une personne se présent au guichet les personnes y travaillant lance l'ensemble des actions à faire dans ce cas là (=appel de la fonction).


Une fonction est ré-utilisable: il suffit de l'appeler plusieurs fois

Une fonction est ré-exécutée autant de fois qu'elle est appelée.

Tant qu'une personne se présente au guichet, les actions à effectuer dans ce cas là sont réalisées pour ce nouveau cas. Et cela est vrai même si une même personne se représente plusieurs fois.


Une fonction peut être "contextuelle" ou effectuer des instructions sur des éléments qu'on lui fournit lors de l'appel (=attributs de la fonction)

Une fonction peut nécessiter des attributs, c'est à dire des parametres, pour fonctionner. Par exemple, on peut afficher un texte donné par l'utilisateur, si nous avons en attribut ce fameux texte; on peut faire la somme de deux nombres si on nous indique ces deux nombres. Ces paramètres nécessaire pour faire fonctionner la fonction sont les attributs de la fonction.

Si un guichet ne permet de déclencher une alarme par exemple, le simple fait de se présenter au guichet, même sans information, permet de lancer l'action du guichet (procédure pour déclencher l'alarme). Il n'y a donc pas d'attribut. Par contre, pour lancer un annonce, il faudra le contenu de l'annonce. Il faut donc se présenter au guichet avec le contenu de l'annonce (=attribut 1) et l'annonce sera lancée avec cet attribut 1. La procédure sera la même si l'on fait une annonce d'un autre message, juste l'attribut changera. On pourra avoir plusieurs attributs, par exemple pour déclarer une nouvelle adresse il faudra le nom et le prénom, le numéro de rue, la rue, le code postal, la ville, le pays et la date de déménagement, soit 8 attributs à fournir dans l'ordre au guichet.

Une fonction peut retourner un resultat

Une fonction peut effectuer une série d'action quand on l'appelle, mais elle peut aussi nous fournir un résultat que l'on peut récupérer. Ce resultat est renvoyé en utilisant le mot clef "return" en JavaScript.

Si l'on se présent au guichet pour demander une carte grise, on va obtenir en retour une nouvelle carte grise avec laquelle on va repartir. On peut également repartir avec une nouvelle information (ex: la date de la prochaine réunion publique). Contrairement aux exemples des parties précédentes, le fait de faire appel au guichet va se solder par la récupération d'un élément. Il peut s'agir d'une information de succès ou non de la procédure (votre changement d'adresse a été pris en compte ou non), ou d'un résultat (réponse à l'information demandée, nouvelle carte crise). Dans tous les cas, vous aurez un retour avec lequel vous pouvez repartir ou donner à une autre personne par exemple.