\chapter{Langages et programmation}

\enlargethispage*{5em}

\begin{exointro}{Lycée Jean-Joseph Fourier, Auxerre}
On donne le programme suivant, écrit en Fortran:
\begin{listing}[language=fortran]{}{05-solintro.txt}\end{listing}

\begin{questions}
\item En vous référant aux langages que vous connaissez, que peut signifier \og \texttt{len=20} \fg{} ? 
\item Que représente la commande \og \texttt{gt} \fg{} présente dans l'instruction conditionnelle ?
\item Que fait ce programme ?
\end{questions}
\end{exointro}
\enlargethispage*{3em}
\begin{aretenir}
Pour faire tourner en ligne un programme (C, PHP, HTML, etc.), vous pouvez vous rendre sur le site:
\begin{center}\ttfamily
https://www.onlinegdb.com
\end{center}
\end{aretenir}

\newpage

Nous avons vu dans les premiers chapitres des programmes écrits en langage\linebreak Python.

Python est un langage parmi d'autres. Nous allons voir dans ce chapitre quels sont les points communs à tous les langages, et quelles sont aussi les différences.

Citons quelques langages dans l'ordre alphabétique : 
\begin{center}
Basic, C, C++, Caml, Fortran, Java, Pascal, Perl, PHP Python, \TeX...
\end{center}
Sur la page :
\begin{center}
\texttt{https://fr.wikipedia.org/wiki/Liste\_de\_langages\_de\_programmation},
\end{center}

\Par

on peut visualiser l'ensemble des langages informatiques qui existent. 

\section{Constructions élémentaires}

\subsection{Séquences et affectations}

\begin{defins}
\begin{itemize}
\item Une \textit{séquence} est une suite d'instructions.
\item Une \textit{affectation} est le fait de donner une valeur à une variable.
\end{itemize}
\end{defins}

En algorithmique, une affectation est symbolisée par une flèche de la valeur (à droite) vers la variable (à gauche).

\begin{Exemple}~\par 
\qquad\texttt{a $\leftarrow$ 3}
\end{Exemple}

En revanche, dans un programme, l'affectation est symbolisée par une égalité.
\enlargethispage*{3em}


\begin{Exemples} 
\begin{itemize}
\item En Python, le code suivant :

\qquad\texttt{a, texte = 32, "Bonjour"}


\Par

affecte la valeur 32 à la variable \texttt{a} et la valeur \og Bonjour \fg{} à la variable \texttt{texte}.

\item En C, les mêmes affectations s'écrivent :

\qquad\texttt{int a = 32;}

\qquad\texttt{char texte[] = "Bonjour";}

\item En PHP, cela donne :

\qquad\texttt{\$a = 32;}

\qquad\texttt{\$texte = "Bonjour";}
\end{itemize}
Il y a certes quelques différences dans la syntaxe, mais on arrive à comprendre, même si l'on ne connaît pas parfaitement le langage.
\end{Exemples}

\subsection{Instructions conditionnelles}

\subsubsection{Le modèle \og if ... then ... else ... \fg{} }

Les instructions conditionnelles sont traduites en algorithmique par :

\Par

\qquad\texttt{SI <condition> ALORS <instructions> SINON <instructions>}


\Par

En programmation, la <condition> prend la forme :
\begin{itemize}
\item d'un test d'égalité (\og SI a == b \fg),
\item d'un test d'inégalité (\og SI a <=b \fg),
\item d'un test booléen (\og SI b ALORS ... \fg{} ou \og SI !b ALORS ...\fg).
\end{itemize}

\begin{Exemples}
\begin{itemize}
\item En Python, nous avons vu que la syntaxe était la suivante :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
if a==b:\\
\qquad ... instructions 1 ...\\
else:\\
\qquad ... instructions2 ...
\end{tabular}

\item En C, ou en PHP, cela donne :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
if (a==b) \{\\
\qquad ... instructions1 ...\\
\}\\
else \{\\
\qquad ... instructions2 ...\\
\}
\end{tabular}

\Par

Notez la présente de délimiteurs (les accolades) contrairement à Python (où un \og : \fg{} et une indentation automatique suffisent).
\end{itemize}
\end{Exemples}

\subsubsection{Le modèle \og switch \fg{} }

Ce modèle est une façon plus condensée d'écrire certaines instructions conditionnelles avec \og if \fg.

\begin{Exemples}
\begin{itemize}
\item En PHP, on peut avoir par exemple :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
switch (\$i) \{\\
\qquad case 0: instructions si \$i=0 ; break;\\
\qquad case 1: instructions si \$i=1 ; break;\\
\qquad default : instructions si \$i est différent de 0 et 1;\\
\}
\end{tabular}
\Break
\item En C, cela donne :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
switch(i) \{\\
\qquad case 0: instructions si i=0; break;\\
\qquad case 1: instructions si i=1; break;\\
\qquad default: instructions si i est différent de 0 et 1;\\
\}
\end{tabular}

\item Avec Python, c'est moins simple :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
if i==0:\\
\qquad instructions si i=0\\
elif i==1:\\
\qquad instructions si i=1\\
else:\\
\qquad instructions si i est différent de 0 et 1
\end{tabular}
\end{itemize}
\end{Exemples}

\subsection{Les boucles}

\subsubsection{Les boucles bornées}

Les boucles bornées sont traduites en algorithmique par :

\Par

\begin{algorithme}{}
POUR i ALLANT DE ... à ... FAIRE
	... instructions ...
FIN DU POUR
\end{algorithme}

\Par

En programmation, on utilise les mots anglais adéquats (comme toujours).

\enlargethispage*{\baselineskip}

\begin{Exemples}
\begin{itemize}
\item En Python, cela donne :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
for i in range(50): (exécute 50 fois les instructions)\\
\qquad ... instructions ...
\end{tabular}

\item En C, cela donne :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
int i;\\
for (i=0 ; i<50 ; i++) \{\\
\qquad ... instructions ...\\
\}
\end{tabular}

\item En PHP, cela donne :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
for (\$i=1 ; \$i<=50 ; \$i++) \{\\
\qquad 	... instructions ...\\
\}
\end{tabular}
\end{itemize}
\end{Exemples}

\subsubsection{Les boucles non bornées}

En algorithmique, ce sont les boucles du type :

\Par

\begin{algorithme}{}
TANT QUE $<$condition$>$ FAIRE 
	... instructions ...
FIN DU TANT QUE
\end{algorithme}

\Par

En programmation, le \og TANT QUE \fg{} est traduit par \og while \fg.

\begin{Exemples}
\begin{itemize}
\item En Python, cela donne :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
while a<50:\\
\qquad 	... instructions ...
\end{tabular}

\item En C, cela donne :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
while (a<50) \{\\
\qquad ... instructions ...\\
\}
\end{tabular}

\Par

ou :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
do \{\\
\qquad ... instructions ...\\
\} while (a<50)
\end{tabular}

La différence est qu'avec la 1\iere{} boucle \og while \fg, si la condition \og a<50 \fg{} n'est pas satisfaite dès le début, les instructions ne seront pas exécutées alors qu'avec la 2\ieme{} boucle \og do ... while \fg, les instructions sont exécutées au moins une fois (car le test est effectué après le premier passage dans la boucle).

\item En PHP, cela donne :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
while (\$i<=50) \{\\
\qquad ... instructions ...\\
\}
\end{tabular}
\end{itemize}
\end{Exemples}

\enlargethispage*{\baselineskip}

\begin{attention}
Les boucles \og while \fg{} sont très souvent les victimes d'une mauvaise programmation quand on débute : elles peuvent être infinies si l'on ne fait pas attention aux instructions. Par exemple, en C:

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
int i = 1;\\
int s = 0;\\
while (i < 10) \{\\
\qquad s = s + i;\\
\}
\end{tabular}

est une boucle infinie car la valeur de la variable \texttt{i} n'est pas modifiée dans la boucle. 
\vspace*{-1.5em}
\Break
Ainsi, \texttt{i} vaut toujours 1 et la condition \og i<10 \fg{} est toujours réalisée. Il faut écrire par exemple :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
int i = 1;\\
int s = 0;\\
while (i < 10) \{\\
\qquad	s = s + i;\\
\qquad	i++;\\
\}
\end{tabular}

\Par

Dans ce cas, \texttt{i} est incrémentée à chaque passage dans la boucle et prendra tôt ou tard une valeur supérieure ou égale à 10; la boucle s'arrêtera alors.
\end{attention}

\subsection{Les fonctions}

\subsubsection{Définition}

Les fonctions sont des blocs d'instructions admettant aucun, un ou plusieurs\linebreak arguments. Elles sont très utiles pour éviter d'écrire un grand nombre de fois des instructions qui doivent être exécutées à de multiples reprises.


\begin{Exemples}
\begin{itemize}
\item En Python, on peut avoir par exemple :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
def toto(a,b):\\
\qquad return a*a+b*b-a*b
\end{tabular}

\Par

qui définit la fonction $f(a,b)=a^2+b^2-ab$.

\item En C, cela donne :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
double toto(double a, double b) \{\\
\qquad double r = a*a+b*b-a*b;\\
\qquad return r;\\
\} 
\end{tabular}

\Par

Le type \og double \fg{} devant la fonction (ainsi que devant ses arguments) signifie que ce qui suit est un nombre \og réel \fg{} (ou presque... voir chapitre \ref{chap-types-valeurs-base}). Le résultat retourné par la fonction est donc un \og réel \fg.

Si la fonction ne retourne rien, le type \og void \fg{} est attendu.

\item En PHP, cela donne :

\Par

\begin{tabular}{@{\qquad}>{\ttfamily}l}
function toto(\$a,\$b) \{\\
\qquad return \$a*\$a+\$b*\$b-\$a*\$b;\\
\}
\end{tabular}
\end{itemize}
\end{Exemples}

\begin{Remarque}
en langage C, un programme est toujours contenu dans au moins une fonction; par défaut, c'est la fonction \texttt{main()}.
\end{Remarque}



\subsubsection{Prototyper une fonction}

\begin{defin}
Le \textit{prototype} d'une fonction est la donnée:
\begin{itemize}
\item de son type (entier, flottant...);
\item de son nom;
\item du type de ses arguments.
\end{itemize}
\end{defin}

Les prototypes sont en général utilisés sur les gros projets (contenant beaucoup de fichiers). Ils permettent de présenter dans un fichier une fonction définie dans un autre fichier.

\Par

En C, le prototypage d'une fonction se fait en général (même si cela n'est pas obligatoire pour un programme court) en début de code.

Pour un programme long, le prototypage est écrit dans un fichier externe (avec l'extension \texttt{.h}) appelé en début de code :

\Par

\qquad\texttt{\#include <monfichier.h>}

\section{Points communs et différences des langages}

Avant tout chose, il ne vous est pas demandé de connaître \textit{tous} les langages de programmation (existe-t-il une personne qui les connaisse tous ?). 

En revanche, il est conseillé de connaître au moins un langage car la structure d'un programme, quel que soit son langage, restera la même.

\subsection{Les instructions conditionnelles}

Elles comportent toujours le mot \og if \fg{} (pour les plus simples) ou \og switch \fg{} (pour les instructions plus conséquentes).

Elles se terminent parfois par \og end if \fg{} ou \og endif \fg{} quand il n'y a pas d'accolades. Quelques fois, elles se terminent par \og fi \fg (comme en \TeX), mais c'est très rare.

En revanche, selon les langages, la syntaxe des conditions qui suivent \og if \fg{} peut varier :\enlargethispage*{3em}
\begin{itemize}
\item très souvent, les comparaisons utilisent \og == \fg, \og > \fg, \og >= \fg, etc., mais dans certains langages, les comparaisons sont écrites avec des lettres (\og gt \fg{} pour \og > \fg{} ou encore \og lt \fg{} pour \og < \fg{} par exemple);
\item en Python, les opérateurs booléens s'écrivent \og or \fg, \og and \fg, ou \og not \fg, mais dans de nombreux langages, ils s'écrivent respectivement \og || \fg, \og \&\& \fg{} et \og ! \fg. 
\end{itemize}

\subsection{Les boucles (itérations)}

Elles comportent souvent les mots \og for \fg{} ou \og while \fg, mais quand ce n'est pas le cas, il peut y avoir un \og do \fg.

Quelques fois, le mot \og break \fg{} ou \og exit \fg{}  apparaît pour \og casser \fg{} la boucle, c'est-à-dire sortir prématurément de la boucle sans aller jusqu'au bout de l'itération.

\subsection{Les fonctions}

Là encore, un mot apparaît presque toujours : \og function \fg. Si tel n'est pas le cas, le mot \og def \fg{} peut être utilisé (comme en Python).

\subsection{Une différence importante}

L'une des difficultés majeures pour un débutant en programmation réside dans la déclaration des variables et la gestion des types.
Certains langages, comme Python ou PHP, utilisent un typage dynamique : il n'est pas nécessaire de préciser le type d'une variable lors de sa création, car le langage le détermine automatiquement en fonction de la valeur affectée.
En revanche, d'autres langages, comme C ou Java, utilisent un typage statique, où le type de chaque variable doit être déclaré explicitement dès sa création. Ces langages proposent souvent plusieurs types numériques avec des tailles et des précisions différentes (\texttt{int}, \texttt{long}, \texttt{short}, \texttt{double}, \texttt{float}, etc.), ce qui peut complexifier la tâche pour un programmeur débutant. Consulter la documentation propre au langage est donc primordial.

Par exemple, en \textit{Java}:
\begin{itemize}
%\item le type \og byte \fg{} désigne un entier entre $-2^7$ et $2^7-1$;
%\item le type \og short \fg{}  désigne un entier entre $-2^{15}$ et $2^{15}-1$;
\item le type \og int \fg{} désigne un entier entre $-2^{31}$ et $2^{31}-1$;
%\item le type \og long \fg{} désigne un entier entre $-2^{63}$ et $2^{63}-1$;
%\item le type \og float \fg{} désigne un nombre à virgule sur 4 octets;
%\item le type \og double \fg{} désigne un nombre à virgule sur 8 octets (contient plus de chiffres après la virgule).
\end{itemize}

Mais en C:
\begin{itemize}
%\item le type \og signed char \fg{} désigne un entier entre $-2^7+1$ et $2^7-1$;
\item le type \og int \fg{}  désigne un entier entre $-2^{15}+1$ et $2^{15}-1$;
%\item le type \og long \fg{} désigne un entier entre $-2^{31}+1$ et $2^{31}-1$;
%\item le type \og float \fg{} désigne un nombre à virgule sur 4 octets;
%\item le type \og double \fg{} désigne un nombre à virgule sur 8 octets (contient plus de chiffres après la virgule).
\end{itemize}

%\Par
%
%\textit{Conclusion :} toute personne souhaitant apprendre un langage doit tôt ou tard\linebreak plonger le nez dans sa documentation !
\enlargethispage*{5em}

\begin{solintro}
\begin{questions}
\item Nous avons vu qu'en Python, \og len \fg{} était en rapport avec la longueur d'une chaîne de caractères (abréviation de \textit{length} = longueur).

Ainsi, \og \texttt{len=20} \fg{} pourrait désigner la longueur maximale des chaînes \texttt{mot1}, \texttt{mot2} et \texttt{mot}.

\item \og \texttt{gt} \fg{} est l'équivalent du test \og $>$ \fg.

\item L'instruction conditionnelle \texttt{if (mot1.gt.mot2)} laisse à supposer que les instructions suivantes s'exécutent quand la longueur de \texttt{mot1} est strictement plus grande que celle de \texttt{mot2}. Dans ce cas, les instructions intervertissent les deux variables.

Le programme semble donc trier les chaînes de caractères selon l'ordre croissant de leur longueur.
\end{questions}
\vspace*{-1.5em}
\end{solintro}

\section{Spécifications et tests}

\subsection{Documentation}

Le code seul ne suffit pas. En effet, le développement et la maintenance d'un programme peuvent impliquer plusieurs personnes et s'étaler sur plusieurs années. Documenter le code est donc essentiel, en utilisant des commentaires pour expliciter certaines lignes ou parties. Bien sûr, cela commence par utiliser des noms explicites pour les variables et fonctions.

Voici deux exemples de la même fonction, la première avec des noms quelconques :

\begin{listing}[language=python]{}{06-cours-noms-vagues.py}\end{listing}

et la seconde avec des noms explicites, beaucoup plus lisible :

\begin{listing}[language=python]{}{06-cours-noms-explicites.py}\end{listing}

\subsection{Documenter une fonction : \textit{docstring}}

Python permet de documenter une fonction en insérant une chaîne de caractères, appelée \textit{docstring}, encadrée par trois guillemets, immédiatement après l'instruction \texttt{def}. Cette chaîne peut s'étendre sur plusieurs lignes. En voici un exemple simple :\enlargethispage*{5em}

\begin{listing}[language=python]{}{06-13.py}\end{listing}

Cette documentation est alors accessible depuis la console : \texttt{help(carre)}.

%\Par \textit{Remarque} : Des outils peuvent exploiter ces docstrings pour générer la documentation technique pour les développeurs (indispensable pour des gros projets).

\subsection{Préconditions et postconditions}

\begin{defin}[Spécification]
La docstring d'une fonction précise les spécifications attendues :
\begin{itemize}
\item précondition : conditions sur les arguments (type, valeur attendue, etc.).
\item postcondition : ce que la fonction renvoie.
\end{itemize}
\end{defin}

Spécifier une fonction consiste donc à décrire clairement ces deux éléments. Pour garantir ces spécifications, on peut insérer des assertions dans le code. Une assertion vérifie qu'une condition est vraie durant l'exécution : si ce n'est pas le cas, le programme s'arrête et affiche un message d'erreur, que l'on peut personnaliser.

La syntaxe est : \texttt{assert <condition>} ou \texttt{assert <condition>, "message d'erreur"}
où \texttt{<condition>} est une expression (test) dont l'évaluation retourne un booléen.

\Par Exemple : 

\begin{listing}[language=python]{}{06-14.py}\end{listing}

\Par

\textit{Remarque} : Les assertions sont utiles pendant le développement et le débogage pour détecter les erreurs, mais elles ne sont généralement pas utilisées dans le code final en production. 

\section{Tests}

Même bien documenté et spécifié, un code n'est pas à l'abri d'erreurs. Une bonne pratique consiste à tester rigoureusement une fonction en l'exécutant avec divers exemples de paramètres et en comparant les résultats obtenus aux résultats attendus. Pour cela, il est essentiel de bien connaître les spécifications et d'anticiper les cas particuliers susceptibles de provoquer des erreurs.

\Par

Il est courant, dans l'industrie, de rédiger les tests après avoir spécifié la fonction, mais avant de l'implémenter. Cette tâche peut même être confiée à des personnes différentes de celles qui écrivent le code. 

Trouver un jeu de tests pertinent est une démarche cruciale : un ensemble de tests bien conçu permet de révéler un grand nombre d'erreurs potentielles, tandis qu'un jeu incomplet risque de laisser passer des erreurs non détectées.

\Par

Cependant, un jeu de tests, même étendu, n'est jamais exhaustif car il est impossible de couvrir tous les cas possibles. Ainsi, la réussite à un ensemble de tests ne garantit pas qu'un programme soit exempt de défauts. Néanmoins, plus les tests sont variés et nombreux, plus les erreurs sont susceptibles d'être détectées et corrigées en amont.

\Par

Exemple : la fonction \texttt{indice\_min} reçoit une liste de nombres et retourne l'indice de sa valeur minimale. Elle vérifie également que la liste n'est pas vide et retourne \texttt{None} dans ce cas. Un bon jeu de tests pourrait être :

\begin{listing}[language=python]{}{06-15.py}\end{listing}

\Par

Ce jeu de tests couvre différents cas : liste vide, valeurs positives, négatives et différentes positions de la valeur minimale. Il illustre bien l'importance de tester divers scénarios pour minimiser les erreurs.

