programmation modulaire

This commit is contained in:
gwen 2017-04-13 10:50:18 +02:00
parent eb3daeae4e
commit 15fd0fa136
5 changed files with 446 additions and 22 deletions

View File

@ -0,0 +1,14 @@
Structures de données simples
=============================
- tableaux
- listes
- piles
- files
Structures de données complexes
================================
- graphes
- arbres
- hachages

View File

@ -0,0 +1,295 @@
Les fonctions et les procédures
================================
Préliminaire : rappel de théorie de l'information
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Théorie de l'information (Claude Shannon, 1949), (ou théorie de la communication)
Canal de transmission::
entrée -> récepteur -> émetteur -> sortie
Description d'une procédure
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
En programmation impérative, un programme est une suite dinstructions qui font
évoluer létat mémoire, le résultat est dans létat final de la mémoire.
- une procédure peut prendre des paramètres
- elle modifie l'état courant du système
- Déclaration des paramètes
- Déclaration du corps
- Appel de la procédure
.. raw:: latex
\begin{algorithm}
\caption{Procédure de permutation de deux entiers}\label{permutation}
\begin{algorithmic}[1]
\Procedure{permuter}{$a,b$}{}
\BState \emph{parametres}:
\State $a: \textit{int}$
\State $b: \textit{int}$
\BState \emph{locales}:
\State $z: \textit{int}$ \Comment{Une variable intermédiaire est nécessaire}
\BState \emph{corps}:
\State $z \gets a$
\State $a \gets b$
\State $b \gets z$
\EndProcedure
\State \Call{permuter}{10, 12} \Comment{appel de la procédure}
\end{algorithmic}
\end{algorithm}
effet de bord
toute modification de la mémoire ou modification d'un support externe
instruction
commande ou phrase en mesure de modifier l'état du programme ou de la machine hôte
(allocation mémoire, support externe, disque, écran...)
Une procédure ne renvoie pas de valeur, mais provoque un 'effet de bord' (écriture dans une globale, dans un flux sortant etc.).
Une procédure permet de créer une instruction nouvelle qui deviendra une primitive pour le programmeur.
Cela permet de structurer le texte source du programme et améliorer sa
lisibilité. Cela permet aussi d'appeler plusieurs fois, et à plusieurs endroit
dans le code, cette primitive.
Appel d'une procédure
~~~~~~~~~~~~~~~~~~~~~
(ex: pseudo-pascal)
**déclaration de procédure**
.. raw:: latex
\begin{algorithm}
\caption{Procédure de permutation de deux entiers}\label{permutation}
\begin{algorithmic}[1]
\Procedure{permuter}{$a,b$}{}
\BState \emph{parametres}:
\State $a: \textit{int}$ \Comment{paramètres formels de la procédure}
\State $b: \textit{int}$
\BState \emph{locales}:
\State $z: \textit{int}$ \Comment{les variables locales de la procédure}
\BState \emph{corps}:
\State ... \Comment{Le corps de la procedure}
\EndProcedure
\State \Call{permuter}{10, 12} \Comment{l'appel de la procédure}
\end{algorithmic}
\end{algorithm}
- les variables x1,...,xn sont appelées *paramètres formels* de p
- les variables v1,...,vm sont appelées *les variables locales* de p
les valeurs effectivement passées en paramètres, ici `10, 12`
sont appelées **paramètres effectifs** de p
signature
C'est l'ensemble paramètre formel + resultat de l'appel
fermeture
L'ensemble procédure + variables locales + signature + parametres effectifs
est appelé une **fermeture**. C'est la procédure + son contexte qui permet
de l'instancier dans un programme.
Environnement
Contexte dévaluation d'une expression ou d'une fonction
Portée
La portée d'une variable est sa condition d'utilisation dans un contexte donné
(utilisation locale uniquement, ou bien globale, ou bien locale et globale)
.. ifconfig:: exercice
**Exercice** : Que donne ce code ?
.. code-block:: ocaml
# let x = 42 in
let y = x - 1 in x - y ;;
.. ifconfig:: correction
**Correction** :
.. code-block:: ocaml
- : int = 1
Exemple de variable globale modifiée localement (** attention, mauvaise pratique ** !) :
.. code-block:: python
>>> a = 5
>>> def print_a():
... print("La variable a = {0}.".format(a))
...
>>> print_a()
La variable a = 5.
>>> a = 8
>>> print_a()
La variable a = 8.
>>>
.. important::
Lordre dévaluation dans un let ... in ... est bien déterminé,
sans grande importance dans un cadre purement fonctionnel, mais important
en cas deffets de bord
niveau
Le niveau dune déclaration (de variable ou de procédure) est le nombre
de procédures sous lesquelles elle est déclarée. Le programme principal
a le niveau 0.
Description d'une fonction
~~~~~~~~~~~~~~~~~~~~~~~~~~
Une fonction renvoie une valeur et ne modifie pas l'état courant du programme
en cours d'exécution ni ne réalise d'effets de bord. Elle renvoie
**toujours** quelque chose (même la valeur ``None`` qui n'est pas rien)
- une procédure peut prendre des paramètres
- elle modifie l'état courant du système
- Déclaration des paramètes
- Déclaration du corps
- Appel de la fonction
En programmation fonctionnelle, programme est un ensemble de définitions de fonctions,
un résultat est l'application dune fonction à une structure de données effective.
- composant de base : la fonction
- opération de base : lapplication
.. raw:: latex
\begin{algorithm}
\caption{Exemple de fonction}\label{fonction}
\begin{algorithmic}[1]
\Function{permuter}{$a,b$}{} \Comment{définition de la fonction}
\BState \emph{parametres}: \Comment{déclaration (noms, types) des paramètres formels}
\State $a: \textit{int}$
\State $b: \textit{int}$
\BState \emph{locales}: \Comment{déclaration (noms, types) des valeurs locales}
\State $z: \textit{int}$
\BState \emph{corps}:
\State $z \gets a$
\State $a \gets b$
\State $b \gets z$
\BState \emph{return}: \Comment{La valeur, le résulat renvoyé par la fonction}
\EndFunction
\State \Call{permuter}{10, 12} \Comment{appel de la fonction}
\BState \emph{result}:
\State (12, 10) \Comment{Le résultat effectif de la fonction après appel}
\end{algorithmic}
\end{algorithm}
Définition mathématique
~~~~~~~~~~~~~~~~~~~~~~~~~
fonction
Une fonction f dun ensemble E vers un ensemble F est une
correspondance qui associe à chaque élément de E au plus
un élément de F.
- E est appelé le domaine de définition
- F est appelé codomaine
- la **signature** de la fonction : `E → F (int -> int = <fun>)`
curryfication
évaluation de l'application d'une fonction
- évaluter `(f x y)`
- peut donner une **valeur fonctionnelle**
- évaluation de la valeur fonctionnelle sur une valeur des types de base
::
let g = function n -> (function p -> p + 1) n;;
typage d'une fonction
~~~~~~~~~~~~~~~~~~~~~
.. code-block:: ocaml
# let f x y z = if x > 0 then y + x else z - x;;
val f : int -> int -> int -> int = <fun>
cest en fait une fonction à un argument qui retourne une fonction::
.. code-block:: ocaml
val f : int -> (int -> (int -> int)) = <fun>
application de f à trois valeurs
.. code-block:: ocaml
# f 1 2 3;;
- : int = 3
en programmation fonctionnelle,
les fonctions sont des valeurs comme les autres
.. code-block:: ocaml
# fun x -> x * x;;
- : int -> int = <fun>
récursivité
~~~~~~~~~~~~
.. code-block:: ocaml
let rec fact n =
if n=0 then 1 else n * fact (n-1)
équivalent impératif utilisant une boucle
.. code-block:: c
int fact(int n){
int f = 1 ;
int i = n ;
while (i>0){
f = f * i;
i-- ;
} ;
return f ;
}
Définitions par cas
~~~~~~~~~~~~~~~~~~~
.. code-block:: ocaml
let rec fact n =
match n with
0 -> 1
| -> n * fact (n-1)
**exemple** : la fonction puissance
.. code-block:: ocaml
let rec puissance x n = match n with
0 -> 1
| -> x * puissance x (n-1)

View File

@ -11,6 +11,8 @@ Introduction à l'algorithmique
programme programme
fonctions fonctions
control control
donnees
apercu apercu
modularite modularite
modules
annexes/index annexes/index

View File

@ -60,6 +60,39 @@ traitements et les données.**
Structuration et sûreté d'exécution Structuration et sûreté d'exécution
----------------------------------- -----------------------------------
La programmation raisonnée
~~~~~~~~~~~~~~~~~~~~~~~~~~
Un **programme** est le codage d'un algorithme dans un langage de programmation.
La programmation consiste à modéliser un problème du monde réel sous une forme
symbolique (pour faire résoudre ce problème par un ordinateur).
Certains problèmes sont **indécidables** ou **ouverts**.
On utilise un langage de programmation pour décrire la **solution** du programme.
La sémantique du programme est le sens de chacune des constructions du langage.
**Comment passer de l'énoncé d'un problème à un programme de bonne qualité ?**
spécifier
décrire de manière complète et rigoureuse le problème à résoudre
modéliser
proposer une représentation du réel qui soit accessible au calcul
algorithmique
transcrire
La transcription du modèle algorithmique se fait dans un langage
de programmation cible adapté au problème
valider
La validation du programme est une étape qui permet de s'assurer plus ou
moins fortement que le programme produit les résultats attendus.
La validation va de la série de tests unitaires (validation faible)
à la preuve de programme (validation mathématique forte).
La preuve de programme La preuve de programme
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
@ -90,19 +123,30 @@ système lors de ses exécutions possibles et permetent de dire si globalement,
donné, le programme va fonctionner correctement. Encore très lourdes, ces techniques ne sont donné, le programme va fonctionner correctement. Encore très lourdes, ces techniques ne sont
utilisées que dans un contexte industriel de haute sécurité. utilisées que dans un contexte industriel de haute sécurité.
Les tests d'acceptation Les tests d'acceptation
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
C'est sont les tests unitaires et fonctionnels Il y a plusieurs types de tests
- unitaires
- fonctionnels
- acceptation
Très utilisés dans l'industrie, les tests unitaires et fonctionnels ne testent que certaines Très utilisés dans l'industrie, les tests unitaires et fonctionnels ne testent que certaines
parties du programme et permettent de dire que le programme va marcher grosso-modo à peu près. parties du programme et permettent de dire que le programme va marcher grosso-modo à peu près.
Beaucoup moins coûteux à installer, ce sont des éléments cléfs des méthodes agiles. Beaucoup moins coûteux à installer, ce sont des éléments cléfs des méthodes agiles.
Les Outils de linting (validation)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
la dette technique - vérifications syntaxiques
- vérification sémantiques
- vérification sur les imports inutiles ou mal formés (imports croisés
Exemple en python : pylint
La dette technique
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
Au bout d'un moment le code devient du code spaghetti et les techniques sont obsolètes. Au bout d'un moment le code devient du code spaghetti et les techniques sont obsolètes.
@ -114,7 +158,6 @@ sinon il peut y avoir un coût à payer qui sera pohibitoire.**
On solde la dette technique parce que à un moment ça va devenir beaucoup trop On solde la dette technique parce que à un moment ça va devenir beaucoup trop
cher à payer. cher à payer.
Les méthodologies agiles Les méthodologies agiles
~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~
@ -141,30 +184,44 @@ sprint. Un sprint aboutit toujours sur la livraison d'un produit partiel fonctio
temps, le facilitateur a la charge de réduire au maximum les perturbations extérieures et de temps, le facilitateur a la charge de réduire au maximum les perturbations extérieures et de
résoudre les problèmes non techniques de l'équipe. résoudre les problèmes non techniques de l'équipe.
Conception descendante d'un programme
-------------------------------------
Les Outils de linting (validation) Il s'agit d'une méthode de résolution d'un problème. On le découpe en tâches
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ de plus en plus fines, de plus en plus détaillées, qui aboutiront au programme final.
- vérifications syntaxiques On met des *trous* dans les algorithmes de plus haut niveau,
- vérification sémantiques c'est-à-dire des phrases en langage naturel.
- vérification sur les imports inutiles ou mal formés (imports croisés
Exemple en python : pylint .. ifconfig: exercice
Les modules **Exercice** : **Calculer la date du lendemain**
-----------
Il s'agit de décomposer un grand programme en .. ifconfig: correction
morceaux (**modules**) connectés entre eux par des **interfaces** bien
définies.
Ces modules doivent être aussi indépendants que possible. - l'algorithme de plus bas niveau
module ::
ensemble de ressources liées sémantiquement lendemain jour =
si jour [est le dernier jour du mois] alors
resultat = [calculer le 1er janvier de l'année suivante]
sinon
resultat = lendemain_dansl'année jour
interface - les algorithmes de plus bas niveau
mode demploi du module, avec en plus un principe de masquage ::
des informations (partie publique, partie secrète)
lendemain_dans_l'année jour =
si jour [est le dernier jour du mois] alors
resultat = [calculer le premier jour du mois suivant]
sinon
resultat = jour suivant jour
::
jour_suivant jour =
jour + 1
et ainsi de suite jusqu'à ce que toutes les phrases soient calculables.

View File

@ -0,0 +1,56 @@
Les modules
============
Il s'agit de décomposer un grand programme en
morceaux (**modules**) connectés entre eux par des **interfaces** bien
définies.
Ces modules doivent être aussi indépendants que possible.
module
ensemble de ressources liées sémantiquement
interface
mode demploi du module, avec en plus un principe de masquage
des informations (partie publique, partie secrète)
Exemples d'interface
--------------------
::
type: son type
arguments
arg1 : description de l'argument 1
arg2 : description de l'argument 2
préconditions:
arg1 > 10
postconditions:
result < 19
raises: TypeError, AssertionError, SystemError...
test: tests nominaux pour chaque cas spécifié
- L'interface racine carrée
::
racine:
type: float -> float
arguments x: float, flottant dont on veut calculer la racine
pré: x >= 0
test: racine 25.0 -> 5.0 ; racine (-25) -> raises TypeError
- L'interface `lendemain`
Il faut définir auparavant un type spécifique appelé `date`
::
lendemain: le lendemain est la date qui désigne
le jour suivant de la date passée en argument
type: date -> date
arguments :
d: date
description: la date dont on veut calculer le lendemain