Règles du bon pseudocode

Quelques raccourcis :

Le pseudocode est un langage pour exprimer clairement et formellement un algorithme. Ce langage est près d'un langage de programmation comme Pascal, C# ou C++, sans être identique à l'un ou à l'autre. Il exprime des idées formelles dans une langue près du langage naturel de ses usagers (pour nous, le français) en lui imposant une forme rigoureuse.

Quelques trucs suivent pour vous aider à rédiger du « bon » pseudocode.

Identification

Il est essentiel d'identifier l'auteur de tout document remis au professeur, même s'il ne s'agit « que » de pseudocode. Assurez-vous de respecter les règles d'identification en vigueur dans votre cours.

Nomenclature

Pour une réflexion plus poussée sur la nomenclature, voir ../../Sujets/Developpement/Pratique-programmation.html#nomenclature

Quelques règles de nommage simples suivent :

Règles générales

En pseudocode :

Correct Incorrect
PI ← 3,14159
Lire rayon
volume ← 4 / 3 * PI * rayon ^ 3
Écrire volume
PI ← 3,14159;
Lire rayon;
volume ← 4 / 3 * PI * rayon ^ 3;
Écrire volume;
Correct Incorrect
TAUX_CHANGE_CANADIEN ← 0,79
lire montantCanadien
montantAmérican ← montantCanadien * TAUX_CHANGE_CANADIEN
// ou encore
montantAmérican ← montantCanadien *
                  TAUX_CHANGE_CANADIEN
Écrire montantAméricain
TAUX_CHANGE_CANADIEN ← 0,79
lire montantCanadien
// présentation confuse
montantAmérican ← montantCanadien *
TAUX_CHANGE_CANADIEN
Écrire montantAméricain
Correct Incorrect
PI ← 3,14159
Lire rayon
volume ← 4 / 3 * PI * rayon ^ 3
Écrire volume
const float PI ← 3,14159
float rayon,
      volume
Lire rayon
volume ← 4 / 3 * PI * rayon ^ 3
Écrire volume

Opérations primitives

Le symbole ← utilisé pour l'affectation en pseudocode est un emprunt direct au langage APL, qui a inspiré plusieurs autres langages

À propos des opérations primitives exprimées en pseudocode :

Correct Incorrect
Lire hauteur
Lire largeur
Lire nom
// une constante ne peut être lue au clavier, par définition
Lire HAUTEUR
// le littéral "largeur" est du texte; ce n'est pas une variable
Lire "largeur"
// la primitive Lire ne lit qu'une variable à la fois
Lire hauteur, largeur ,nom
Correct
Écrire surface
Écrire TAILLE
Écrire 3
Écrire "J'aime mon prof"
// affichera 5
Écrire 2 + 3
// affichera le texte 2 + 3
Écrire "2 + 3"
// Présumant une fonction Sqrt qui calcule et retourne la racine carrée
// de son paramètre, ce qui suit affichera 4
Écrire Sqrt(16)
Correct Incorrect
PI ← 3,14159
Lire hauteur
surface ← hauteur ^ 2
résultat ← Sqrt(4)
message ← "J'aime mon prof"
// on ne peut modifier un littéral
3 ← hauteur
"J'aime mon prof" ← message
// on ne peut modifier un appel de fonction
Sqrt(4) ← résultat
// on ne peut modifier une expression
2 + 3 ← 5
Correct Incorrect
PI ← 3,14159
E ← 2,71828
Lire hauteur
surface ← hauteur ^ 2
résultat ← Sqrt(4)
message ← "J'aime mon prof"
PI ← 3,14159, E ← 2,71828
Lire hauteur, largeur
Écrire "J'aime mon prof" nomDuProf "!"
Correct Incorrect
PI ← 3,14159
E ← 2,71828
MESSAGE ← "J'aime mon prof"
PI ← 3,14159
// on ne peut lire la valeur d'une constante : cette valeur est fixée a priori
Lire PI
MESSAGE ← "J'aime mon prof"
// on ne peut plus modifier une constante une fois celle-ci initialisée
MESSAGE ← "Moi aussi!"

Exemple simple d'un programme calculant et affichant le volume d'une sphère, étant donné son rayon, le tout exprimé en pseudocode. Notez la constante en majuscules, les noms de variables, la notation pour l'affectation, etc.

PI ← 3,14159
Lire rayon
volume ← 4 / 3 * PI * rayon^3
Écrire volume

Autres opérations

Le pseudocode ne se limite pas aux opérations primitives.

Opérations arithmétiques

Les opérateurs arithmétiques admis sont les suivants :

Notation en pseudocode

Équivalent en notation mathématique

Sens

a + b

Addition de a et de b

a - b

Valeur de a à laquelle on aurait soustrait b

a * b

Produit de a et de b

a / b

Quotient de la division de a par b (indéfini si )

a % b

Reste de la division de a par b (indéfini si )

a ^ b

Résultat de l'élévation de a à la puissance b

Sur le plan de la notation, le pseudocode se limite à du texte susceptible d'être écrit au clavier. De même, la multiplication doit être exprimée explicitement

Correct Incorrect
PI ← 3,14159
Lire x
y ← 2 * x
volume ← 4 / 3 * PI * rayon ^ 3
Écrire Sqrt(x+y)
 ← 3,14159
Lire x
y ← 
volume ← 
Écrire 

Opérations relationnelles

Les opérateurs relationnels admis sont les suivants :

Notation en pseudocode

Équivalent en notation mathématique

Sens

a < b

a est plus petit que b (a précède b)

a <= b

a est plus petit ou égal à b

a > b

a est plus grand que b (a suit b)

a >= b

a est plus grand ou égal à b

a = b

a est égal à b

a != b

a est différent de b

Opérations logiques

Les opérateurs logiques admis sont les suivants :

 Notation en pseudocode   Équivalent en notation mathématique   Sens 
a ET b

Vrai seulement si a et b sont tous deux vrais

a OU b

Faux seulement si a et b sont tous deux faux

NON a

Vrai seulement si a est faux

Fonctions et répétitives

Pour les fonctions, les règles sont pour l'essentiel les mêmes : on ne se préoccupe pas des types, on s'intéresse aux noms, on adopte une indentation rigoureuse, etc.

Pour les répétitives, seul le Tant que importe vraiment (les boucles do...while et les boucles for sont en fait des while qui formalisent des cas particuliers). Notez que j'accepte personnellement les formes d'affectation composites (++, +=, -=, etc.) en pseudocode mais qu'il vaut mieux vérifier avec votre professeur avant de les utiliser, pour vous assurer que c'est aussi le cas avec elle ou avec lui.

Quelques exemples :

En C++ En C# En pseudocode
int carre(int n) {
   return n * n;
}
static int Carré(int n)
{
   return n * n;
}
Carré(n)
   Retourner n * n
int calculer_somme_valeurs(int de, int vers) {
   int somme = 0;
   for(int i = de; i <= vers; ++i)
      somme += i;
   return somme;
}
static int CalculerSommeValeur(int de, int vers)
{
   int somme = 0;
   for(int i = de; i <= vers; ++i)
   {
      somme += i;
   }
   return somme;
}
CalculerSommeValeurs(de, vers)
   somme ← 0
   cpt ← de
   Tant que cpt <= vers
      somme += cpt // ou somme ← somme + cpt
      ++cpt // ou cpt ← cpt + 1
   Retourner somme
int lire_entier(string invite, int min, int max) {
   cout << format("{} [{},{}] : ", invite, min, max);
   int nb;
   cin >> nb;
   while(nb < min || max < nb) {
      cout << format("{} [{},{}] : ", invite, min, max);
      cin >> nb;
   }
   return nb;
}
static int LireEntier(string invite, int min, int max)
{
   Console.Write($"{invite} [{min},{max}] : ");
   int nb = int.Parse(Console.ReadLine());
   while(nb < min || max < nb)
   {
      Console.WriteLine($"Entrée erronnée : {nb}");
      Console.Write($"{invite} [{min},{max}] : ");
      nb = int.Parse(Console.ReadLine());
   }
   return nb;
}
LireEntier(invite, min, max)
   Écrire invite // min, max
   Lire nb
   Tant que nb < min OU max < nb
      Écrire "erreur"
      Écrire invite // min, max
      Lire nb
   Retourner nb;
// exemple qui suppose l'existence des constantes
// CHOIX_MIN, CHOIX_MAX et du prédicat
// est_entre_inclusif(val,min,max)
char lire_choix() {
   char choix;
   do {
      cout << format("Votre choix [{}, {}] : ", CHOIX_MIN, CHOIX_MAX);
      cin >> choix;
   } while(!est_entre_inclusif(choix, CHOIX_MIN, CHOIX_MAX));
   return choix;
}
// exemple qui suppose l'existence des constantes
// CHOIX_MIN, CHOIX_MAX et du prédicat
// EstEntreInclusif(val,min,max)
static char LireChoix()
{
   char choix;
   do
   {
      Console.Write($"Votre choix [{CHOIX_MIN}, {CHOIX_MAX}] : ");
      choix = char.Parse(Console.ReadLine());
   }
   while(!EstEntreInclusif(choix, CHOIX_MIN, CHOIX_MAX));
   return choix;
}
// exemple qui suppose l'existence des constantes
// CHOIX_MIN, CHOIX_MAX et du prédicat
// est_entre_inclusif(val,min,max)
LireChoix()
   Lire choix
   Tant que NON EstEntreInclusif(choix, CHOIX_MIN, CHOIX_MAX)
      Lire choix
   Retourner choix
#include <iostream>
using namespace std;
bool est_pair(int n) {
   return n % 2 == 0;
}
char determiner_symbole(int noLigne) {
   char symbole;
   if(est_pair(noLigne)) {
      symbole = '-';
   } else {
      symbole = '*';
   }
   return symbole;
}
void dessiner_symboles(int noLigne) {
   int nbSymboles = 2 * noLigne - 1;
   char symbole = determiner_symbole(noLigne);
   for(int cpt = 1; cpt <= nbSymboles; ++cpt) {
      cout << symbole;
   }
}
void dessiner_espaces(int nbLignes, int noLigne) {
   int nbEspaces = nbLignes - noLigne;
   for(int cpt = 1; cpt <= nbEspaces; ++cpt) {
      cout << ' ';
   }
}
void dessiner_ligne(int nbLignes, int noLigne) {
   dessiner_espaces(nbLignes, noLigne);
   dessiner_symboles(noLigne);
}
void dessiner_sapin(int hauteur) {
   for(int cptLignes = 1; cptLignes <= hauteur; ++cptLignes) {
      dessiner_ligne(hauteur, cptLignes);
      cout << endl;
   }
}
// programme principal
// https://wandbox.org/permlink/eIcnfuuH5cgxp1VY
int main() {
   const int NB_LIGNES = 10;
   dessiner_sapin(NB_LIGNES);
}
using System;
// programme principal
// https://dotnetfiddle.net/tKwUfq

const int NB_LIGNES = 10;
DessinerSapin(NB_LIGNES);

static bool EstPair(int n)
{
   return n % 2 == 0;
}
static char DéterminerSymbole(int noLigne)
{
   char symbole;
   if(EstPair(noLigne))
   {
      symbole = '-';
   }
   else
   {
      symbole = '*';
   }
   return symbole;
}
static void DessinerSymboles(int noLigne)
{
   int nbSymboles = 2 * noLigne - 1;
   char symbole = DéterminerSymbole(noLigne);
   for(int cpt = 1; cpt <= nbSymboles; ++cpt)
   {
      Console.Write(symbole);
   }
}
static void DessinerEspaces(int nbLignes, int noLigne)
{
   int nbEspaces = nbLignes - noLigne;
   for(int cpt = 1; cpt <= nbEspaces; ++cpt)
   {
      Console.Write(' ');
   }
}
static void DessinerLigne(int nbLignes, int noLigne)
{
   DessinerEspaces(nbLignes, noLigne);
   DessinerSymboles(noLigne);
}
static void DessinerSapin(int hauteur)
{
   for(int cptLignes = 1; cptLignes <= hauteur; ++cptLignes)
   {
      DessinerLigne(hauteur, cptLignes);
      Console.WriteLine();
   }
}
// programme principal
    
NB_LIGNES ← 10
DessinerSapin(NB_LIGNES)

EstPair(n)
   Retourner n % 2 == 0

DéterminerSymbole(noLigne)
   Si EstPair(noLigne)
      symbole ← '-'
   Sinon
      symbole ← '*'
   Retourner symbole

DessinerSymboles(noLigne)
   nbSymboles ← 2 * noLigne - 1
   symbole ← DéterminerSymbole(noLigne)
   cpt ← 1
   Tant que cpt <= nbSymboles
      Écrire symbole
      ++cpt

DessinerEspaces(nbLignes, noLigne)
   nbEspaces ← nbLignes - noLigne
   cpt ← 1
   Tant que cpt <= nbEspaces
      Écrire ' '
      ++cpt

DessinerLigne(nbLignes, noLigne)
   DessinerEspaces(nbLignes, noLigne)
   DessinerSymboles(noLigne)

DessinerSapin(hauteur)
   cptLignes ← 1
   Tant que cptLignes <= hauteur
      DessinerLigne(hauteur, cptLignes)
      ChangerDeLigne()
      ++cptLignes

 

Tests

Un programme peut être testé même lorsqu'il n'existe que sous forme de pseudocode :