mise en place des cours algo + poo
This commit is contained in:
291
algo/tronCommun/algo.txt
Normal file
291
algo/tronCommun/algo.txt
Normal file
@ -0,0 +1,291 @@
|
||||
Algorithmique
|
||||
=============
|
||||
|
||||
Al-Kharezmi, auteur du traité "Kitab al jabr w'al-muqabala", est l'inventeur
|
||||
des manipulations algébriques (algèbre = **al jabr**).
|
||||
C'est Léonard de Pise, dit Fibonacci, qui emprunta le nom du célèbre
|
||||
mathématicien arabe du 9ème siècle, mais l'algèbre existe
|
||||
depuis bien plus longtemps (Depuis Babylone, puis ensuite l'Egypte ancienne).
|
||||
|
||||
.. glossary::
|
||||
|
||||
|
||||
algorithme
|
||||
|
||||
terme désignant une suite d'opérations constituant un schéma de calcul
|
||||
ou de résolution d'un problème. C'est un processus systématique de
|
||||
résolution d'un problème permettant de décrire précisément des étapes.
|
||||
C'est une suite finie d'instructions permettant de donner la réponse à un
|
||||
problème.
|
||||
|
||||
L'algorithmique est l'étude et la production de règles et de techniques
|
||||
qui sont impliquées dans la définition d'algorithmes.
|
||||
|
||||
Implémentation d'un algorithme
|
||||
------------------------------
|
||||
|
||||
.. glossary::
|
||||
|
||||
implémentation
|
||||
|
||||
Adaptation de la méthodologie de calculabilité au calcul effectif
|
||||
sur une machine abstraite ou via un langage formel.
|
||||
|
||||
Il n’y a pas de parcours à sens unique de l’algorithme vers l’implantation.
|
||||
La quête d’une implantation efficace nous amène souvent à effectuer
|
||||
un retour vers les algorithmes eux-mêmes, et à en modifier des points
|
||||
essentiels. L’aspect théorique de réflexion sur les algorithmes,
|
||||
et l’aspect pratique de l'implémentation sont donc en symbiose.
|
||||
|
||||
Un existant émerge de la décomposition structurale d'un
|
||||
domaine de base. Le fait essentiel, c'est la genèse des genres de l'existant les
|
||||
uns à partir des autres.
|
||||
|
||||
L'essence d'une forme (un algorithme) se réalise au sein d'une matière qu'elle créée
|
||||
(un langage). L'origine d'une matière fait naître les formes (concepts)
|
||||
que sa structure dessine.
|
||||
|
||||
- Notion structurale de non-contradiction
|
||||
- Notion extensive de "réalisation dans un champ donné"
|
||||
|
||||
Deux aspects réciproques : l'essence d'une forme se réalise au sein d'une
|
||||
matière qu'elle crée, l'essence d'une matière faisant naître les formes que sa
|
||||
structure dessine.
|
||||
|
||||
Abandonner l'idée trop simpliste de domaines concrets et d'opérations abstraites
|
||||
qui posséderaient en eux-mêmes comme une nature de matière et une nature de
|
||||
forme ; cette conception tendrait, en effet, à stabiliser les existants
|
||||
mathématiques dans certains rôles immuables et ignorerait le fait que les
|
||||
existants abstraits qui naissent de la structure d'un domaine plus concret
|
||||
peuvent à leur tour servir de domaine de base pour la genèse d'autres existants.
|
||||
|
||||
L'algorithme comme généralisation de la calculabilité
|
||||
------------------------------------------------------
|
||||
|
||||
L'importance croissante de l'informatique comme outil scientifique
|
||||
impose d'élaborer un nouveau mode de description des méthodes de calcul (appelées algorithmes)
|
||||
susceptible de satisfaire à la fois le critère de sécurité (maîtrise du résultat) et la possibilité
|
||||
d'implémenter les calculs sur un ordinateur.
|
||||
|
||||
Exemple d'algorithme
|
||||
---------------------
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{L'alorithme de Bellman-Kalaba}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure {BellmanKalaba}{$G$, $u$, $l$, $p$}
|
||||
\ForAll {$v \in V(G)$}
|
||||
\State $l(v) \leftarrow \infty$
|
||||
\EndFor
|
||||
\State $l(u) \leftarrow 0$
|
||||
\Repeat
|
||||
\For {$i \leftarrow 1, n$}
|
||||
\State $min \leftarrow l(v_i)$
|
||||
\For {$j \leftarrow 1, n$}
|
||||
\If {$min > e(v_i, v_j) + l(v_j)$}
|
||||
\State $min \leftarrow e(v_i, v_j) + l(v_j)$
|
||||
\State $p(i) \leftarrow v_j$
|
||||
\EndIf
|
||||
\EndFor
|
||||
\State $l(i) \leftarrow min$
|
||||
\EndFor
|
||||
\State $changed \leftarrow l \not= l’$
|
||||
\State $l \leftarrow l$
|
||||
\Until{$\neg changed$}
|
||||
\EndProcedure
|
||||
\Statex
|
||||
\Procedure {FindPathBK}{$v$, $u$, $p$}
|
||||
\If {$v = u$}
|
||||
\State \textbf{Write} $v$
|
||||
\Else
|
||||
\State $w \leftarrow v$
|
||||
\While {$w \not= u$}
|
||||
\State \textbf{Write} $w$
|
||||
\State $w \leftarrow p(w)$
|
||||
\EndWhile
|
||||
\EndIf
|
||||
\EndProcedure
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
Exemple d'algorithme avec son implémentation
|
||||
---------------------------------------------
|
||||
|
||||
Soit l'algorithme de factorielle suivant,
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Algorithme de la factorielle d'un nombre}\label{factorielle}
|
||||
\begin{algorithmic}[1]
|
||||
\Function{factorielle}{$n$}\Comment{La fonction récursive factorielle}
|
||||
\BState \emph{parametre} : $n$ entier
|
||||
\If{$n = 1$}
|
||||
\BState \emph{Sortie} : 1
|
||||
\Else
|
||||
\BState \emph{Sortie} : $n * \Call{factorielle}{n-1}$ \Comment{On appelle la fonction dans l'algorithme lui-même}
|
||||
\EndIf
|
||||
\EndFunction
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
et son implémentation en python :
|
||||
|
||||
.. literalinclude:: code/factorielle.py
|
||||
:language: python
|
||||
|
||||
En voici une autre implémentation (en OCaml) :
|
||||
|
||||
.. literalinclude:: code/factorielle.ml
|
||||
:language: ocaml
|
||||
|
||||
On remarque que le **pseudocode** est très proche de
|
||||
la syntaxe du python :
|
||||
|
||||
.. function:: factorielle(n:int)
|
||||
|
||||
::
|
||||
|
||||
if n=1
|
||||
return 1
|
||||
else
|
||||
return n * factorielle(n-1)
|
||||
end if
|
||||
|
||||
Qualité d'un algorithme
|
||||
-----------------------
|
||||
|
||||
- correction d'un algorithme
|
||||
- complétude d'un algorithme
|
||||
|
||||
Sémantique
|
||||
|
||||
Étude du sens, de la signification d'un langage
|
||||
Définir la sémantique d’un langage formel consiste à lui donner une
|
||||
signification mathématique.
|
||||
|
||||
Sémantique opérationnelle
|
||||
|
||||
on définit la sémantique par sa mise en œuvre sur
|
||||
une machine abstraite.
|
||||
|
||||
Sémantique dénotationnelle
|
||||
|
||||
on associe à chaque construction syntaxique un
|
||||
objet mathématique
|
||||
|
||||
Sémantique axiomatique
|
||||
|
||||
chaque construction est décrite par la manière dont
|
||||
elle transforme des propriétés ou des prédicats.
|
||||
|
||||
Proposition
|
||||
|
||||
une proposition est un énoncé qui est soit vrai, soit faux
|
||||
|
||||
**exemple** : ``2 + 3 = 5``. Proposition vraie.
|
||||
|
||||
Prédicats
|
||||
|
||||
Une proposition dont la valeur de vérité dépend de la valeur d’une ou plusieurs variables
|
||||
|
||||
**Exemple** : ``n est pair`` : vrai pour n = 4 mais faux pour n = 9
|
||||
|
||||
|
||||
Axiome
|
||||
|
||||
une proposition qui est supposée vraie
|
||||
|
||||
Un ensemble d’axiomes est consistant s’il n’existe pas de proposition
|
||||
dont on peut démontrer qu’elle est à la fois vraie et fausse.
|
||||
|
||||
Un ensemble d’axiomes est complet si, pour toute proposition, il est
|
||||
possible de démontrer qu’elle est vraie ou fausse.
|
||||
|
||||
Théorème d’incomplétude de Gödel (1931) : tout ensemble
|
||||
consistant d’axiomes pour l’arithmétique sur les entiers est
|
||||
nécessairement incomplet.
|
||||
|
||||
**Les concepts de base en algorithmique sont les axiomes**
|
||||
|
||||
inférence
|
||||
|
||||
règles d’inférence, règles permettant de combiner des axiomes et des
|
||||
propositions vraies pour établir de nouvelles propositions vraies.
|
||||
|
||||
Démonstration
|
||||
|
||||
vérification d’une proposition par une séquence de déductions logiques
|
||||
à partir d’un ensemble d’axiomes.
|
||||
|
||||
Lorsque le champ donné (le domaine) ne contient qu'un nombre fini d'individus,
|
||||
on peut définir un choix de valeur des variables permettant de vérifier la
|
||||
proposition obtenue par la *conjonction* de tous les axiomes du système proposé.
|
||||
On dit alors que ce choix *réalise* un système d'axiomes.
|
||||
|
||||
|
||||
Il ne s'agit plus de savoir si la définition entraîne l'existence, mais de
|
||||
chercher si la structure d'un système d'axiomes (*règles*) peut donner naissance
|
||||
à un champ d'individus qui soutiennent entre eux les relations définies pas les
|
||||
axiomes.
|
||||
|
||||
Concret et abstrait
|
||||
--------------------
|
||||
|
||||
Il est possible qu'un même genre d'existant joue dans un schéma de genèse le
|
||||
rôle d'abstrait par rapport à un concret de base, et soit au contraire dans une
|
||||
autre genèse le concret de base d'un nouvel abstrait.
|
||||
|
||||
Une pareille présentation des choses implique un tel renversement par rapport
|
||||
aux habitudes de pensée classiques, qu'il faut encore insister sur le sens
|
||||
nouveau que reçoivent ici les expressions de "concret" et "d'abstrait".
|
||||
|
||||
Les systèmes d'axiomes sont souvent conçus comme des structures purement
|
||||
formelles, abstraites. Ces structures sont si profondément engagées dans la
|
||||
genèse de leurs réalisations, qu'il valait mieux désigner par ces termes les
|
||||
structures de base.
|
||||
|
||||
Un système d'axiome *peut* devenir le concret de base.
|
||||
|
||||
Ceci permet d'exprimer non seulement l'engagement du concret dans la genèse de
|
||||
l'abstrait, mais encore les relations d'imitation qui peuvent exister entre la
|
||||
structure de cet abstrait et celle du concret de base.
|
||||
|
||||
Dans certains cas, la genèse de l'abstrait à partir d'un concret de base
|
||||
s'affirme jusqu'à réaliser une imitation de structure entre ces genres
|
||||
d'existants qui naissent l'un de l'autre.
|
||||
|
||||
**C'est pourquoi on représente souvent un algorithme en pseudo-code**,
|
||||
c'est-à-dire en fait dans le mode de représentation (issu du langage préféré de la
|
||||
personne qui l'exprime) dominant chez la personne qui exprime un algorithme.
|
||||
|
||||
Comment rendre un algorithme lisible
|
||||
------------------------------------
|
||||
|
||||
- Le bon algorithme utilise des identifiants explicites.
|
||||
- Le bon algorithme est structuré.
|
||||
- Le bon algorithme est indenté.
|
||||
|
||||
Complexité d'un algorithme
|
||||
--------------------------
|
||||
|
||||
On peut approximer la complexité des algorithmes.
|
||||
C'est utile pour pouvoir comparer des algorithmes.
|
||||
|
||||
complexité
|
||||
|
||||
estimer la complexité d'un algorithme, c'est estimer le nombre de calculs qu'il utilise.
|
||||
|
||||
Si f est la fonction caractérisant exactement le coût d’un algorithme et n
|
||||
la taille des données, on s’intéresse à la façon dont augment f(n) lorsque n augmente
|
||||
on va montrer que f(n) n'augmente pas plus vite qu’une autre fonction
|
||||
g(n). Du point de vue mathématique, on dit que la fonction f est dominée
|
||||
asymptotiquement par la fonction g ce qui se note f = O(g)
|
||||
|
||||
- Complexité temporelle : c’est le nombre d’op«erations effectuées par
|
||||
une machine qui exécute l’algorithme.
|
||||
|
||||
- Complexité spatiale : c’est le nombre de positions mémoire utilisées par
|
||||
une machine qui exécute l’algorithme.
|
586
algo/tronCommun/fonctions.txt
Normal file
586
algo/tronCommun/fonctions.txt
Normal file
@ -0,0 +1,586 @@
|
||||
Les fonctions et les procédures
|
||||
================================
|
||||
|
||||
Préliminaire : rappel de théorie de cybernétique
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Théorie de l'information (Claude Shannon, 1949), (ou théorie de la communication)
|
||||
|
||||
Canal de transmission::
|
||||
|
||||
entrée -> récepteur -> émetteur -> sortie
|
||||
|
||||
.. glossary::
|
||||
|
||||
cybernétique
|
||||
|
||||
étude des fonctions de réflexes conditionnés du cerveau humain
|
||||
utilisation au mieux en PNL ("programmation neuro-linguistique")
|
||||
ou en analyse transactionnelle, ou au pire en ingérinerie sociale.
|
||||
|
||||
La matérialité physique est considérée comme le hardware, le génétique (le
|
||||
réseau neuronal) étant assimilé au network hardware.
|
||||
|
||||
Les objets mentaux (fonctionnements psychologiques et épigénétiques du
|
||||
cerveaux) est assimilé au logiciel, au software.
|
||||
|
||||
IFTTT ("if this then that") : la causalité mondaine est ramenée à un ordre de
|
||||
comportement affecté à un assimilé-machine.
|
||||
|
||||
L'humain est ramené à une machine.
|
||||
C'est articulation entre "déclencheur contextuel" et "action en réponse de"
|
||||
n'est pas une "black box" mais un "feedback" qui, pour l'humain,
|
||||
loin d'être ramené à une entrée/sortie, constitue un **feedback**
|
||||
utile pour la connaissance de soi.
|
||||
|
||||
A la place, la communication est ramenée à une **boucle de rétroaction**
|
||||
(comme dans un prompt) entre un système comportemental et son environnement.
|
||||
La représentation sujet/objet (la perspective traditionnelle) est remplacée
|
||||
par le clivage intérieur/extérieur. Behaviorisme, procédural.
|
||||
|
||||
L'humain est donc ramené à
|
||||
|
||||
- un ordonnanceur
|
||||
- un comportement intrinsèque (boîte noire)
|
||||
|
||||
- un stimuli pavlovien (déclencheur, trigger) est considéré comme un paramètre d'entrée
|
||||
- une instruction comportementale est considérée comme une action de traitement
|
||||
- le résultat est observé.
|
||||
|
||||
Cette articulation entre "déclencheur contextuel" et "action en réponse"
|
||||
est très exactement une forclusion de la profondeur monadique (Leibniz) de
|
||||
l'humain à la black box informationnelle (et cybernétique).
|
||||
|
||||
Pour quoi faire ? Pour pirater. Pour manipuler.
|
||||
Le piratage consiste à
|
||||
|
||||
- isoler les constantes (les procédures répétitives, les algorithmes)
|
||||
- les observer (collecter les données)
|
||||
|
||||
afin de
|
||||
|
||||
- les réécrire (influence toxique, pishing - hammeçonnage)
|
||||
- les détruire (attaque en règle)
|
||||
|
||||
|
||||
Description d'une procédure
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
En programmation impérative, un programme est une suite d’instructions 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{appelpermutation}
|
||||
\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'un identifiant (une variable) est sa condition d'utilisation dans un contexte donné
|
||||
(utilisation locale uniquement, ou bien globale, ou bien locale et globale)
|
||||
La portée d’une liaison est la portion du code dans laquelle cette
|
||||
liaison est valide (i.e. où un identifiant est lié à une expression).
|
||||
|
||||
.. 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
|
||||
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let a = 3 (* première liaison pour l'identifiant a *)
|
||||
let b = 5 and c = 6
|
||||
let somme = a + b + c
|
||||
val somme : int = 14
|
||||
let a = 45 (* deuxième liaison pour l'identifiant a *)
|
||||
somme
|
||||
val a : int = 45
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Que donne ce code ?
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let a = 3 and b = 4 and c = 8 ;;
|
||||
let somme = a + b + c ;;
|
||||
val somme : int = ???
|
||||
let a = 44
|
||||
let b = 5
|
||||
let c = 1
|
||||
somme
|
||||
- : int = ???
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let a = 3 and b = 4 and c = 8 ;;
|
||||
- : int = 15
|
||||
let somme = a + b + c ;;
|
||||
val somme : int = 15
|
||||
let a = 44
|
||||
let b = 5
|
||||
let c = 1
|
||||
somme
|
||||
- : int = 15
|
||||
|
||||
Même code en python
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 1
|
||||
>>> b = 2
|
||||
>>> c = 3
|
||||
>>> somme = a + b + c
|
||||
>>> somme
|
||||
6
|
||||
>>> a = 56
|
||||
>>> b = 5678
|
||||
>>> c = 56789
|
||||
>>> somme
|
||||
6
|
||||
>>>
|
||||
|
||||
Portée locale dans une expression
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# let a = 2 and b = 3 and c = 4 in
|
||||
let somme = a+b+c in
|
||||
somme
|
||||
- : int = 9
|
||||
# somme ;;
|
||||
Error: Unbound value somme
|
||||
# a ;;
|
||||
Error: Unbound value a
|
||||
|
||||
.. important::
|
||||
|
||||
L’ordre d’évaluation dans un let ... in ... est bien déterminé,
|
||||
sans grande importance dans un cadre purement fonctionnel, mais important
|
||||
en cas d’effets de bord
|
||||
|
||||
|
||||
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.
|
||||
>>>
|
||||
|
||||
|
||||
|
||||
niveau
|
||||
|
||||
Le niveau d’une 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.
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
|
||||
def _get_config(name):
|
||||
# return config value
|
||||
if not isfile(CONFIG_FILE):
|
||||
raise Exception("Fichier de configuration non existant")
|
||||
from ConfigParser import ConfigParser
|
||||
cfg = ConfigParser(allow_no_value=True)
|
||||
cfg.read(CONFIG_FILE)
|
||||
|
||||
if name == "SUBNETS":
|
||||
return eval(cfg.get('eole', 'subnets'))
|
||||
elif name == "LEASES_FILE":
|
||||
DHCP_PATH = cfg.get('eole', 'container_path_dhcp')
|
||||
return join('/', DHCP_PATH, 'var/lib/dhcp/dhcpd.leases')
|
||||
def get_routes(*args, **kwargs):
|
||||
"""
|
||||
Send list of reserved IP
|
||||
return list of tuple (id, machine name, IP, MAC Adress)
|
||||
"""
|
||||
cfg = creole_loader(load_extra=True, rw=False, owner=MODNAME,
|
||||
mandatory_permissive=False)
|
||||
return zip(cfg.dhcp.dhcp.id_dhcp.id_dhcp, cfg.dhcp.dhcp.id_dhcp.hostname,
|
||||
cfg.dhcp.dhcp.id_dhcp.ip, cfg.dhcp.dhcp.id_dhcp.macaddress)
|
||||
|
||||
On voit que l'objet `cfg` ligne 6 et 7 a le même nom que l'objet `cfg` ligne 19.
|
||||
C'est autorisé et les espaces de nommages sont différents.
|
||||
|
||||
|
||||
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 d’une fonction à une structure de données effective.
|
||||
|
||||
- composant de base : la fonction
|
||||
- opération de base : l’application
|
||||
|
||||
.. 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}
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : factoriser le code suivant
|
||||
::
|
||||
|
||||
Ecrire "Etes-vous marié ?"
|
||||
Rep1 <- ""
|
||||
TantQue Rep1 <> "Oui" et Rep1 <> "Non"
|
||||
Ecrire "Tapez Oui ou Non"
|
||||
Lire Rep1
|
||||
FinTantQue
|
||||
...
|
||||
Ecrire "Avez-vous des enfants ?"
|
||||
Rep2 <- ""
|
||||
TantQue Rep2 <> "Oui" et Rep2 <> "Non"
|
||||
Ecrire "Tapez Oui ou Non"
|
||||
Lire Rep2
|
||||
FinTantQue
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
::
|
||||
|
||||
Fonction RepOuiNon() en caractère
|
||||
Truc <- ""
|
||||
TantQue Truc <> "Oui" et Truc <> "Non"
|
||||
Ecrire "Tapez Oui ou Non"
|
||||
Lire Truc
|
||||
FinTantQue
|
||||
Renvoyer Truc
|
||||
Fin
|
||||
|
||||
Ecrire "Etes-vous marié ?"
|
||||
Rep1 <- RepOuiNon()
|
||||
...
|
||||
Ecrire "Avez-vous des enfants ?"
|
||||
Rep2 <- RepOuiNon()
|
||||
|
||||
|
||||
Définition mathématique
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
fonction
|
||||
|
||||
Une fonction f d’un 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>)`
|
||||
|
||||
|
||||
Exemple de signature d'une fonction
|
||||
|
||||
::
|
||||
|
||||
Fonction RepOuiNon(Msg en Caractère) en Caractère
|
||||
Ecrire Msg
|
||||
Truc <- ""
|
||||
TantQue Truc <> "Oui" et Truc <> "Non"
|
||||
Ecrire "Tapez Oui ou Non"
|
||||
Lire Truc
|
||||
FinTantQue
|
||||
Renvoyer Truc
|
||||
Fin Fonction
|
||||
|
||||
...
|
||||
Rep1 <- RepOuiNon("Etes-vous marié ?")
|
||||
...
|
||||
Rep2 <- RepOuiNon("Avez-vous des enfants ?")
|
||||
...
|
||||
|
||||
|
||||
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>
|
||||
|
||||
c’est 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)
|
||||
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Portée locale dans une fonction**
|
||||
Quelles sera la valeur de la variable `a` ?
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 1
|
||||
>>> def myfunc():
|
||||
... a = 2
|
||||
... return a + 1
|
||||
...
|
||||
>>> a = myfunc() + a
|
||||
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
Correction:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 1
|
||||
>>> def myfunc():
|
||||
... a = 2
|
||||
... return a + 1
|
||||
...
|
||||
>>> a = myfunc() + a
|
||||
>>> a
|
||||
4
|
||||
>>>
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Portée locale dans une fonction avec variable globale
|
||||
Quelles sera la valeur de la variable `a` ?
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 1
|
||||
>>> def myfunc():
|
||||
... global a
|
||||
... a = 2
|
||||
... return a + 1
|
||||
...
|
||||
>>> a = myfunc() + 3
|
||||
>>>
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 1
|
||||
>>> def myfunc():
|
||||
... global a
|
||||
... a = 2
|
||||
... return a + 1
|
||||
...
|
||||
>>> myfunc()
|
||||
3
|
||||
>>> a
|
||||
2
|
||||
>>> a = myfunc() + 3
|
||||
>>> a
|
||||
6
|
||||
>>>
|
336
algo/tronCommun/langage.txt
Normal file
336
algo/tronCommun/langage.txt
Normal file
@ -0,0 +1,336 @@
|
||||
Les langages de programmation
|
||||
=============================
|
||||
|
||||
langage
|
||||
|
||||
Un langage de
|
||||
programmation
|
||||
doit permettre d'écrire des
|
||||
programmes de bonne qualité
|
||||
|
||||
Un programme doit être :
|
||||
|
||||
- correct
|
||||
- robuste
|
||||
- lisible, bien documenté
|
||||
- facile à modifier, extensible
|
||||
|
||||
Un langage de programmation doit permettre :
|
||||
|
||||
- la programmation structurée
|
||||
- la structuration avec les types
|
||||
- proposer un mécanisme d’exceptions
|
||||
- présenter des caractères de généricité, de polymorphisme et de surcharge
|
||||
|
||||
.. important:: La structuration et l'organisation modulaire sert à maintenir de grands programmes,
|
||||
Elles sont une nécessité
|
||||
|
||||
Approche historique et chronologique
|
||||
-------------------------------------
|
||||
|
||||
- Lambda calcul (1930)
|
||||
- machines de Turing (1936)
|
||||
- début des langages vers les années 1950 (A0, Fortran(impératif),
|
||||
Lisp(impératif et fonctionnel), Cobol)
|
||||
- années 60 : Simula (classes), CPL (compilation séparée)
|
||||
- années 70 : C (référence du langage impératif de bas niveau), Pascal
|
||||
(procédures), Smalltalk (programmation orientée objects), Prolog
|
||||
(programmation logique), Scheme (programmation fonctionnelle pure), Modula,
|
||||
C++, Ada, Turbo Pascal, Common Lisp, Eiffel (programmation par contrats)
|
||||
- années 80 : ML, CAML (langages fonctionnels)
|
||||
- années 90 : Perl, Python, Ruby (languages de scripting multi-paradigmes)
|
||||
Haskell (fonctionnel pur), Lua, Delphi, Java (orienté objet, machine
|
||||
virtuelle), PHP (impératif, dédié au web), Erlang (fonctionnel+
|
||||
programmation concurrente), javascript (orienté web, objets par
|
||||
prototypage), OCaml (multi-paradigme, fortement typé, orienté sécurité,
|
||||
programmation générique, fonctionnelle et objets, modulaire et fonctorielle)
|
||||
- 2009 : go (google, compilé, typage statique, objets par prototypage,
|
||||
prgrammation concurrente), Rust (fondation mozilla, multiparadigme, programmation concurrente)
|
||||
|
||||
Les langages actuellement les plus utilisés dans le monde de l'entreprise sont :
|
||||
|
||||
- javascript/NodeJS (70% du code dans le dépôt github) mais victime de son
|
||||
succès (chaos complet des librairies)
|
||||
- le go est de plus en plus utilisé, c'est **le** langage qui monte
|
||||
actuellement
|
||||
- Python, Ruby, lua, autres langages de scripting (de plus en plus utilisés)
|
||||
- PHP, Java (stagnants)
|
||||
- C, C++ (de moins en moins utilisés)
|
||||
|
||||
Approche par typologie des langages
|
||||
-----------------------------------
|
||||
|
||||
- **A0 (1954)** : possibilité de découpage de programmes en
|
||||
sous-programmes ;
|
||||
|
||||
- **ALGOL (1958)** : concept de bloc de code (pas forcément nommé) et d'imbrication
|
||||
de blocs de code ;
|
||||
|
||||
- **C (1971)** : syntaxe claire et simple, programme fortement structuré ;
|
||||
|
||||
- **C (1980)** : le **code objet**, qui consiste à essayer de faire fonctionner
|
||||
un seul jeu d'instructions sur des machines différentes. Avant, le code
|
||||
d'assemblage dépendait du processeur, donc il n'y avait pas un seul et unique
|
||||
jeu d'instructions ;
|
||||
|
||||
- **1980** : déploiement et succès des langages à objets ;
|
||||
|
||||
- **1983** : turbo pascal (Borland) qui fut le tournant du C,
|
||||
propose un IDE (Environnement de Développement Intégré).
|
||||
aujourd'hui le turbo pascal a pratiquement disparu mais pas totalement,
|
||||
il est soutenu par une communauté open source autour de **Lazarus** ;
|
||||
|
||||
- **depuis les années 90** : deux grands groupes de langages. Les langages à
|
||||
objets, et les langages fonctionnels. Les deux mondes s'interpénètrent (les
|
||||
avancées actuelles du web, les microservices (Erlang, Haskell),
|
||||
viennent du monde fonctionnel, le NoSQL, etc).
|
||||
Les grandes avancées architecturales (système d'exploitation, linux, etc...)
|
||||
viennent du monde de l'impératif.
|
||||
|
||||
|
||||
Approches par modèles de programmation
|
||||
--------------------------------------
|
||||
|
||||
- **le mécanisme d'exceptions** : il est possible de rompre l'exécution normale d'un
|
||||
programme à un endroit et de la reprendre à un autre endroit du programme prévu à
|
||||
cet effet. Ce mécanisme permet de gérer les situations exceptionnelles.
|
||||
|
||||
- **le paradigme impératif** : les entrées-sorties, les modifications physiques de
|
||||
valeurs et les structures de contrôle itératives sont possibles.
|
||||
|
||||
- **le paradigme fonctionnel** : manipule les fonctions comme étant des valeurs du
|
||||
langage. Celles-ci peuvent être utilisées en tant que paramètres d'autres fonctions
|
||||
ou être retournées comme résultat d'un appel de fonction.
|
||||
|
||||
- **le paradigme objet** : La représentation du programme colle à la réalité en
|
||||
reproduisant des entités relativement proches des objets réel. Attention, le piège
|
||||
est de croire qu'il s'agit *du* paradigme universel puisqu'il reproduit en miroir le
|
||||
réel. **C'est en fait un processus d'abstraction comme un autre**.
|
||||
|
||||
Sûreté du langage, typage
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Tri par ordre de sûreté croissant :
|
||||
|
||||
0. typage très faible (presque inexistant aujourd'hui) : 42 == "42" == 42.0...
|
||||
1. typage dynamique faible : (javascript) (possibilité de changer le prototype
|
||||
d'un objet pendant l'éxécution du programme, c'est la fête on peut faire
|
||||
n'importe quoi)
|
||||
2. typage dynamique fort inféré par le comportement (behavior, duck typing)
|
||||
(python, ruby, PHP) Le contenu de la variable détermine le choix du typage
|
||||
`var = 0 -> type int`
|
||||
3. typage statique déclaré fort (Java)
|
||||
`int var = 0 ;` (pas mal mais super lourd, pas **agile** du tout)
|
||||
4. langages à types statiques muni d'un moteur d'inférence de types (Ocaml)
|
||||
sûreté d'exécution, agilité, sécurité.
|
||||
|
||||
|
||||
La syntaxe, la lisibilité
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Importance de la lisibilité (notamment par rapport aux méthodes agiles).
|
||||
|
||||
- courte (python)
|
||||
- verbeuse (C)
|
||||
- l'importance des mots clef du langage
|
||||
- délimiteur de phrase, de blocs (parenthèses, accolades, tabulations, blocs...)
|
||||
|
||||
Langages compilés ou interprétés ?
|
||||
-----------------------------------
|
||||
|
||||
.. glossary::
|
||||
|
||||
langage compilé
|
||||
|
||||
une première passe est faite, des validations son effectuées **avant**
|
||||
la génération du code objet, cette phase est faite par le compilateur.
|
||||
|
||||
compilateur
|
||||
|
||||
programme qui transforme un langage de haut niveau en un langage de base
|
||||
niveau
|
||||
|
||||
- phase d’analyse syntaxique (source -> syntaxe abstraite)
|
||||
- phase de synthèse (syntaxe abstraite -> code objet)
|
||||
|
||||
|
||||
scripting (langage de scripting)
|
||||
|
||||
langage interprèté
|
||||
|
||||
générique (langage)
|
||||
|
||||
Langage à usage générique, qui peut être utilisé dans n'importe quel
|
||||
domaine (par opposition au DSL)
|
||||
|
||||
domain specific
|
||||
|
||||
Domain Specific Language, langage destiné à être utilisé dans un
|
||||
domaine prédéfini.
|
||||
|
||||
paradigmes
|
||||
|
||||
représentation d'une vision particulière à partir d'un modèle théorique
|
||||
|
||||
impératif
|
||||
|
||||
l'algorithme ressemble à une recette de cuisine,
|
||||
c'est-à-dire à une succession d'instructions à exécuter
|
||||
les unes à la suite des autres
|
||||
|
||||
fonctionnel
|
||||
|
||||
l'algorithme ne dépend plus de l'ordre d'exécution d'instructions
|
||||
pas de mélange entre les données et les traitements
|
||||
|
||||
objets (programmation)
|
||||
|
||||
le monde est découpé en catégories
|
||||
qui permettent de créer des objets
|
||||
|
||||
**développement par composants**
|
||||
|
||||
les objets sont organisés entre eux par composants suivant des designs patterns,
|
||||
(patrons de conception)
|
||||
|
||||
garbage collector (ramasse miettes)
|
||||
|
||||
la gestion automatique de la mémoire apparaît en 1989
|
||||
|
||||
machine virtuelle
|
||||
|
||||
portabilité du code (mais diminution en optimisation et performances)
|
||||
|
||||
JIT (just in time compiler)
|
||||
|
||||
code objet, programmes fonctionnant autour de machines virtuelles
|
||||
|
||||
|
||||
- **le typage statique** : la vérification de la compatibilité entre les types des
|
||||
paramètres formels et des paramètres d'appel est effectuée au moment de la
|
||||
compilation du programme. Dès lors, il n'est pas nécessaire de faire ces
|
||||
vérifications durant l'exécution du programme ce qui accroît son efficacité. En
|
||||
outre, la vérification de type permet d'éliminer la plupart des erreurs introduites
|
||||
par maladresse ou étourderie et contribue à la sûreté de l'exécution.
|
||||
|
||||
- **le typage dynamique** : la vérification de la compatibilité entre les types des
|
||||
paramètres formels et des paramètres d'appel est effectuée au moment de l'exécution
|
||||
ou de l'appel à certaines parties de codes du programme.
|
||||
|
||||
- **le polymorphisme paramétrique** : une fonction ou un objet qui n'explore pas la
|
||||
totalité de la structure d'un de ses arguments accepte que celui-ci ait un type non
|
||||
entièrement déterminé. Ce paramètre est alors dit polymorphe. Cette particularité
|
||||
permet de développer un code générique utilisable pour des structures de données
|
||||
différentes tant que la représentation exacte de cette structure n'a pas besoin
|
||||
d'être connue par le code en question. L'algorithme de typage est à même de faire
|
||||
cette distinction.
|
||||
|
||||
- **l'inférence de types** : le programmeur n'a besoin de donner aucune information
|
||||
de type à l'intérieur de son programme. Le langage se charge seul de déduire du code
|
||||
le type le plus général des expressions et des déclarations qui y figurent. Cette
|
||||
inférence est effectuée conjointement à la vérification, lors de la compilation du
|
||||
programme.
|
||||
|
||||
Les grands paradigmes de programmation
|
||||
---------------------------------------
|
||||
|
||||
Le paradigme des objets
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- 1962 (SIMULA) : premières notions de classes ;
|
||||
|
||||
Puis, une dizaine d'années plus tard :
|
||||
|
||||
- C++ : intégration des classes pour le C ;
|
||||
- turbo pascal : intégration des classes pour le pascal ;
|
||||
|
||||
Tous les langages actuels ont intégré des traits objets mais de manière très
|
||||
différentes :
|
||||
|
||||
- perl (1987)
|
||||
- python (1991)
|
||||
- Ruby (1993)
|
||||
|
||||
- L'implémentation des objets en python est très proche des notions initiales de
|
||||
classes issues du Smaltalk et présente une tentative très intéressante
|
||||
d'unification des objets et des types depuis python 2.2 ;
|
||||
|
||||
- Java (1995) : très grosse réussite industrielle en surfant sur la vague de la
|
||||
programmation objet, et des machines virtuelles, mais en fait et avec le recul,
|
||||
doté d'un support objet lourd et alambiqué.
|
||||
Le monde Java est lourd, avec des outils consommant beaucoup de mémoire et
|
||||
qui ne satisfont pas à la règle du KISS (Keep It Simple, Stupid) ;
|
||||
|
||||
|
||||
Il n'y a pas **une** POO (Programmation Objet), il y a des POO.
|
||||
Les implémentations objets dans les langages sont riches et variées :
|
||||
|
||||
- objets obligatoirement construits pas des classes (Java, C++, ...)
|
||||
- objets sans définition de classes (javascript, Ocaml, go, rust)
|
||||
- langages à attributs (python)
|
||||
- langages ou le type des objets est défini par leur classe (python, ruby)
|
||||
- langages ou le type des objets est différent du type de leur classe (Ocaml)
|
||||
- objets sans classes mais construits par des prototypes (javascript)
|
||||
- construction d'objets possibles objets sans classe du tout (Ocaml)
|
||||
- encapsulation des attributs des objets (Java, Ocaml, C++, PHP)
|
||||
- pas d'encapsulation des attributs (python, ruby, javascript...)
|
||||
|
||||
Le paradigme impératif
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Un programme est une suite d'états de la mémoire de l'ordinateur,
|
||||
c'est la suite logique des machines de Turing.
|
||||
La plupart des programmeur aujourd'hui raisonnent suivant ce paradigme,
|
||||
et ont une très faible visibilité par rapport aux autres paradigmes existants.
|
||||
Seuls les programmeurs cultivés sont aujourd'hui capable de raisonner
|
||||
suivant différents paradigmes, ce sont des programmeurs chevronnés et
|
||||
cultivés.
|
||||
|
||||
Le paradigme fonctionnel
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
La notion de fonction que possède sous une forme ou une autre la plupart des
|
||||
langages est empruntée aux mathématiques et non à l'électronique. D'une manière
|
||||
générale, les langages substituent des modèles formels aux conceptions purement
|
||||
calculatoires. Ils y gagnent en expressivité. Certains langages fondent leur
|
||||
paradigme de programmation sur l'abstraction entrée-traitement-sortie, donc sur le
|
||||
**mathème fonctionnel** et pas sur la boite noire électronique. La fonction
|
||||
mathématique apporte un niveau opératoire dans le traitement de l'information.
|
||||
|
||||
|
||||
Approche par fonctionnalités
|
||||
----------------------------
|
||||
|
||||
Plusieurs domaines de l'informatique on proposé/imposé des méthodologies,
|
||||
des manières de faire. Ces modèles de programmation on fortement influencé
|
||||
en retour les langages. On reconnaît aujourd'hui :
|
||||
|
||||
- Le modèle client-serveur
|
||||
- Le modèle de programmation concurrente (exécution de processus légers, threads) :
|
||||
- Le modèle de développement d'une application de bureau (MVC, ergonomie d'interface)
|
||||
- Le modèle de développement web (communiquer sur le réseau Internet, API
|
||||
REST, microservices...)
|
||||
- Le modèle de programmation système et réseau
|
||||
- le modèle **Dev Ops** et les méthodes de développement virtualisés
|
||||
- les langages présentant des **fonctionnalités agiles**
|
||||
|
||||
Conclusion
|
||||
-----------
|
||||
|
||||
Les langages de haut niveau sont caractérisés par
|
||||
des concepts tels que :
|
||||
|
||||
- déclaration de valeurs, types, expressions, portée
|
||||
- expressions, variables, instructions, structures de contrôle
|
||||
- fonctions, procédures, fermetures
|
||||
- encapsulation, modules, objets
|
||||
|
||||
=========== ============
|
||||
Paradigmes Concepts
|
||||
=========== ============
|
||||
impératif variables, procédures, modules
|
||||
objets classes, méthodes, héritage, surcharge
|
||||
fonctionnel fonctions, fermetures, modules
|
||||
logique prédicats, modules
|
||||
concurrent tâche/processus, communication
|
||||
=========== ============
|
52
algo/tronCommun/presentation.txt
Normal file
52
algo/tronCommun/presentation.txt
Normal file
@ -0,0 +1,52 @@
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
|
||||
| "**Que nul n'entre ici s'il n'est géomètre**"
|
||||
| Maxime apposée au porche d'entrée de l'École de Platon
|
||||
|
||||
|
||||
- L'accent est mis sur l'approche **algorithmique scientifique**, dite algorithmique
|
||||
algébrique. L'algorithmique est un sous-domaine de l'algèbre et des
|
||||
approches modulaires (arithmétique modulaire...)
|
||||
|
||||
- Le point de vue mathématique étant assez exigeant, **aucun formalisme fort** de
|
||||
l'algorithmique mathématique ne sera présenté. Aucun symbole mathématique donc, et
|
||||
seulement du pseudo-code.
|
||||
L'approche mathématique forte utilisant le formalisme mathématique de
|
||||
l'algorithmique algébrique est en général enseignée en France uniquement aux cours
|
||||
des grandes écoles.
|
||||
|
||||
- L'algorithmique présentée ici est donc délibérément pseudo-scientifique mais en revanche
|
||||
ouverte au **multi-paradigme**. En général l'évocation d'un algorithme en pseudo code est toujours
|
||||
réducteur car limité au style de programmation le plus à la mode actuellement, c'est-à-dire le
|
||||
**style impératif**. Nous présenterons un éventail des plus grands paradigmes de programmation
|
||||
existants. Nous nous limiterons à la **programmation impérative, fonctionnelle, modulaire,
|
||||
générique et objet**. Nous envisagerons les structures de données et les structures de contrôle
|
||||
spécifiques à chacun des styles évoqués.
|
||||
|
||||
- Et parce qu'un honnête programmeur doit avoir une vue d'ensemble de **l'état de son art**,
|
||||
nous évoquerons un panorama des différents langages existants -- historiques et contemporains --
|
||||
en les comparants les uns aux autres.
|
||||
|
||||
- Durant tout le cours, nous souhaitons proposer une pédagogie par l'exemple, et nous
|
||||
limiterons l'exposé à deux langages d'implémentation des algorithmes : le **Python** pour la programmation
|
||||
impérative modulaire et objet, et le **OCaml**, car nous évoquerons aussi certains points
|
||||
de programmation fonctionnelle et modulaire, polymorphe et teintée de généricité.
|
||||
|
||||
Intérêt
|
||||
-------
|
||||
|
||||
|
||||
| "**Il ne suffit pas d'avoir les mains propres, il faut avoir l'esprit pur.**"
|
||||
| Thalès de Milet ; Sentences - VIe s. av. J.-C.
|
||||
|
||||
L'algorithmique en tant que rapport à la vérité et à la pensée juste et vraie,
|
||||
en tant qu'art de découper un problème complexe en tâches élémentaires,
|
||||
en tant qu'énoncés de compréhension et de sémantique,
|
||||
est la seule chose vraiment profonde dans l'informatique. Le reste n'est que 0 ou 1.
|
||||
Cette notion d'algorithme est profondément enracinée dans le désir humain de
|
||||
transmettre des méthodes pour comprendre des problématiques,
|
||||
qu'il s'agisse de processus scientifiques ou mathématiques, de secrets,
|
||||
de philosophie ou de divination au sens des anciens Grecs.
|
||||
De règles linguistiques, aussi, chez les Romains.
|
||||
|
477
algo/tronCommun/programme.txt
Normal file
477
algo/tronCommun/programme.txt
Normal file
@ -0,0 +1,477 @@
|
||||
Définition d'un programme
|
||||
==========================
|
||||
|
||||
Qu'est-ce qu'un programme ?
|
||||
----------------------------
|
||||
|
||||
- Un **programme** est une suite de **phrases** ;
|
||||
- Une **phrase** est une **déclaration** ou une **expression** (*statement* en anglais) ;
|
||||
|
||||
Production d'un programme :
|
||||
|
||||
1. on écrit le code source du programme ;
|
||||
2. on demande au compilateur de le traduire en code machine : c'est la compilation du programme ;
|
||||
3. on demande à la machine d'effectuer le code machine : c'est l'exécution du programme.
|
||||
|
||||
.. important::
|
||||
|
||||
L'introduction à la compilation et les différentes phases de la compilation
|
||||
d'un programme sont des sujets qui ne seront pas traités dans ce cours.
|
||||
|
||||
Dans un programme de base, il y a deux fichiers :
|
||||
|
||||
1. un fichier contenant le code : c'est le source du programme.
|
||||
2. un fichier contenant le code machine : c'est l'exécutable.
|
||||
|
||||
Que peut faire un programme lorsqu'il est exécuté ?
|
||||
Le programme doit communiquer. S'il reste isolé, il ne pourra pas
|
||||
produire quoi que ce soit. Voici les trois moyens de communication qu'a un
|
||||
programme :
|
||||
|
||||
1. communiquer avec l'utilisateur,
|
||||
2. communiquer avec des fichiers,
|
||||
3. communiquer avec d'autres programmes.
|
||||
|
||||
Les expressions
|
||||
----------------
|
||||
|
||||
expression
|
||||
|
||||
Une expression est une valeur caculée du langage, une opération arithmétique
|
||||
qui retourne une valeur (entier, texte, valeur logique...).
|
||||
C'est donc une suite sémantiquement correcte de **valeurs de base** et **d'opérateurs**
|
||||
|
||||
Par exemple, la ligne suivante est une expression effectuant une addition::
|
||||
|
||||
5 + 6
|
||||
|
||||
Expressions à partir de types de base
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Autres exemples d'expressions :
|
||||
|
||||
- 5 est une expression de type int
|
||||
- 4.5 est une expression de type float
|
||||
- 'c' est une expression de type char
|
||||
- true est une expression de type bool
|
||||
- print ('c') est une expression de type None
|
||||
- raw_input est une expression de type string
|
||||
|
||||
Les expressions se complexifient avec la complexification des données et des traitements,
|
||||
mais le principe de l'expressivité d'un langage reste le même.
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** :
|
||||
Le parenthésage et les opérateurs booléens::
|
||||
|
||||
Variables A, B, C, D, E en Booléen
|
||||
Variable X en Entier
|
||||
Début
|
||||
Lire X
|
||||
A <- X > 12
|
||||
B <- X > 2
|
||||
C <- X < 6
|
||||
D <- (A ET B) OU C
|
||||
E <- A ET (B OU C)
|
||||
Ecrire D, E
|
||||
Fin
|
||||
|
||||
**Que valent D et E si X = 3 ?**
|
||||
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** : D sera VRAI alors que E sera FAUX
|
||||
|
||||
|
||||
|
||||
|
||||
Les déclarations
|
||||
-----------------
|
||||
|
||||
Un autre exemple d'expression :
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Exemple d'expression}
|
||||
\begin{algorithmic}[1]
|
||||
\BState \emph{sortie}: $l$ \Comment{C'est l'expression calculée renvoyée}
|
||||
\ForAll {$v \in V(G)$}
|
||||
\State $l(v) \leftarrow \infty$
|
||||
\EndFor
|
||||
\State $l(u) \leftarrow 0$
|
||||
\Repeat
|
||||
\For {$i \leftarrow 1, n$}
|
||||
\State $min \leftarrow l(v_i)$
|
||||
\For {$j \leftarrow 1, n$}
|
||||
\If {$min > e(v_i, v_j) + l(v_j)$}
|
||||
\State $min \leftarrow e(v_i, v_j) + l(v_j)$
|
||||
\State $p(i) \leftarrow v_j$
|
||||
\EndIf
|
||||
\EndFor
|
||||
\State $l(i) \leftarrow min$
|
||||
\EndFor
|
||||
\State $changed \leftarrow l \not= l’$
|
||||
\State $l \leftarrow l$
|
||||
\Until{$\neg changed$}
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
Exemple de déclarations :
|
||||
|
||||
- `a = 1`
|
||||
- `b = 'c'`
|
||||
|
||||
.. important:: Le signe égal est utilisé de deux manières
|
||||
|
||||
- lors d'une déclaration d'une expression
|
||||
- lorsque deux expressions sont équivalentes
|
||||
|
||||
Suivant les langages, il y a deux symboles différents, ou alors
|
||||
ils sont identiques.
|
||||
|
||||
Il s'agit de **renseigner** une valeur dans une expression nommée
|
||||
|
||||
- en javascript :
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
var b = "blabla" ;
|
||||
|
||||
- en python :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
b = "blabla"
|
||||
|
||||
- en java :
|
||||
|
||||
.. code-block:: java
|
||||
|
||||
String b = "A";
|
||||
|
||||
- en OCaml :
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let a = 1
|
||||
|
||||
Grâce au mécanisme d'inférence de type dans OCaml, le mot-clef **let**
|
||||
signifie ici véritablement l'instanciation d'une valeur au sens
|
||||
mathématique du terme : soit `a` l'entier tel que a soit égal à 1...
|
||||
|
||||
En OCaml comme dans tous les langages fonctionnels, tout ce que nous avons l'habitude
|
||||
d'appeler des "variables" à propos des affectations, sont en fait des **constantes**
|
||||
au sens du paradigme impératif de la programmation.
|
||||
|
||||
.. important::
|
||||
|
||||
Par voie de conséquence, le symbole ``=`` est utilisé à la fois pour la définition des objets et pour le test d'égalité.
|
||||
Pour les autres langages, on utilise `==` ou bien `===` (javascript) car
|
||||
le `=` est sémantiquement déjà utilisé...
|
||||
|
||||
Toutes ces notation, apparemment anodines, correspondent donc à des paradigmes de programmation
|
||||
|
||||
Lorsqu'on ne déclare pas les types des symboles déclarés, c'est que soit
|
||||
|
||||
- le typage est faible
|
||||
- le typage est dynamique (calcul du type en fonction du contenu de la
|
||||
variable)
|
||||
- le typage est statique et fort mais ça ne se voit pas
|
||||
(var le système les calcule automatiquement par inférence de type)
|
||||
|
||||
Assigner, allouer, affecter une chose à quelqu'un ou à une autre chose.
|
||||
|
||||
Exemples dans la langue française :
|
||||
|
||||
- Le traitement que le budget **alloue** à ces fonctionnaires.
|
||||
- Un système d'exploitation multitâche alloue le travail du processeur aux processus en attente, pour un bref laps de temps, à leur tour.
|
||||
|
||||
.. glossary::
|
||||
|
||||
affectation
|
||||
|
||||
Une affectation, aussi appelée assignation par anglicisme, est une structure qui permet d'attribuer une valeur à une variable.
|
||||
|
||||
Il s'agit d'une structure particulièrement courante en programmation impérative, et dispose souvent pour cette raison d'une notation courte et infixée,
|
||||
comme ``x = expr`` ou ``x := expr`` ou encore `x <- expr`.
|
||||
Dans certains langages, le symbole est considéré comme un opérateur d'affectation,
|
||||
et la structure entière peut alors être utilisée comme une expression.
|
||||
D'autres langages considèrent une affectation comme une instruction et ne permettent pas cet usage.
|
||||
|
||||
Voir aussi :
|
||||
|
||||
- Les déclarations de types primitifs et conversions de type
|
||||
- Les types de base::
|
||||
|
||||
Octets (8 bits) byte
|
||||
Entiers courts (16 bits) short
|
||||
Entiers (32 bits) int
|
||||
Entiers longs (64 bits) long
|
||||
Réels (32 bits) float
|
||||
Réels longs (64 bits) double
|
||||
Caractères (16 bits) char
|
||||
Booléens boolean
|
||||
|
||||
- Déclarations par lots::
|
||||
|
||||
x1 = e1, x2 = e2, ... xn = en;
|
||||
|
||||
Exercices : algorithmes sur les affectations
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Calculs d'affectation::
|
||||
|
||||
Variables A, B, C en Entier
|
||||
Début
|
||||
A <- 3
|
||||
B <- 10
|
||||
C <- A + B
|
||||
B <- A + B
|
||||
A <- C
|
||||
Fin
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction**::
|
||||
|
||||
Après La valeur des variables est :
|
||||
A <- 5 A = 5 B = ?
|
||||
B <- 2 A = 5 B = 2
|
||||
A <- B A = 2 B = 2
|
||||
B <- A A = 2 B = 2
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Calculs d'affectation
|
||||
Quelles seront les valeurs des variables A et B après exécution des instructions suivantes ?
|
||||
::
|
||||
|
||||
Variables A, B en Entier
|
||||
Début
|
||||
A <- 5
|
||||
B <- 2
|
||||
A <- B
|
||||
B <- A
|
||||
Fin
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction**::
|
||||
|
||||
Après La valeur des variables est :
|
||||
A <- 5 A = 5 B = ?
|
||||
B <- 2 A = 5 B = 2
|
||||
A <- B A = 2 B = 2
|
||||
B <- A A = 2 B = 2
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : écrire un algorithme permettant d’échanger les valeurs
|
||||
de deux variables A et B, et ce quel que soit leur contenu préalable.
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction**::
|
||||
|
||||
Début
|
||||
A <- n
|
||||
B <- p
|
||||
C <- A
|
||||
A <- B
|
||||
B <- C
|
||||
Fin
|
||||
|
||||
Il faut passer par une variable dite temporaire (la variable C)
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** :
|
||||
Que produit l’algorithme suivant ?
|
||||
|
||||
::
|
||||
|
||||
Variables A, B, C de type entier
|
||||
Début
|
||||
A <- 423
|
||||
B <- 12
|
||||
C <- A + B
|
||||
Fin
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** : dans un prompt python
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = 423
|
||||
>>> b = 12
|
||||
>>> c = a + b
|
||||
>>> c
|
||||
435
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** :
|
||||
Que produit l’algorithme suivant ?
|
||||
|
||||
::
|
||||
|
||||
Variables A, B, C de type texte
|
||||
Début
|
||||
A <- "423"
|
||||
B <- "12"
|
||||
C <- A + B
|
||||
Fin
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** : dans un prompt python
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> a = '423'
|
||||
>>> b = '12'
|
||||
>>> c = a + b
|
||||
>>> c
|
||||
'42312'
|
||||
|
||||
Interaction avec l'utilisateur
|
||||
------------------------------
|
||||
|
||||
Il est possible de communiquer de la manière suivante avec un programme :
|
||||
|
||||
- lire et écrire sur l'entrée/sortie standard
|
||||
- lire et écrire dans un fichier
|
||||
- afficher (du texte, un nombre...)
|
||||
- lire (du texte, un nombre...)
|
||||
- interagir avec les prompts
|
||||
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let x = read_int () in
|
||||
let signe =
|
||||
if x >= 0
|
||||
then " positif "
|
||||
else " négatif " in
|
||||
print_string signe
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : écrire un algorithme qui demande le prénom d'une personne
|
||||
et renvoie "bonjour, je m'appelle <Prénom>"
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** : (implémentation en python)
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# coding: utf-8
|
||||
prenom = raw_input("quel est ton prénom ? \n")
|
||||
print("bonjour, je m'appelle " + prenom.capitalize())
|
||||
|
||||
|
||||
La REPL (boucle d'interaction)
|
||||
-------------------------------
|
||||
|
||||
.. glossary::
|
||||
|
||||
REPL
|
||||
|
||||
Read Eval Print Loop : outil principal de communication avec un programme
|
||||
ou avec un système. Exemples : la console python, le prompt OCaml.
|
||||
|
||||
interface
|
||||
|
||||
outil de communication avec un programme.
|
||||
|
||||
- interface texte
|
||||
- interface graphique
|
||||
|
||||
**Exemples de REPL**
|
||||
|
||||
Le prompt python::
|
||||
|
||||
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
|
||||
[GCC 5.4.0 20160609] on linux2
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>>
|
||||
>>> dir()
|
||||
['__builtins__', '__doc__', '__name__', readline', 'rlcompleter']
|
||||
>>>
|
||||
|
||||
Le prompt ipython::
|
||||
|
||||
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
|
||||
Type "copyright", "credits" or "license" for more information.
|
||||
|
||||
IPython 2.4.1 -- An enhanced Interactive Python.
|
||||
? -> Introduction and overview of IPython's features.
|
||||
%quickref -> Quick reference.
|
||||
help -> Python's own help system.
|
||||
object? -> Details about 'object', use 'object??' for extra details.
|
||||
|
||||
In [1]:
|
||||
|
||||
Le prompt OCaml (utop)::
|
||||
|
||||
Type #utop_help for help about using utop.
|
||||
|
||||
─( 09:21:24 )─< command 0 >──
|
||||
utop #
|
||||
# let x = 1 in x + 2;;
|
||||
- : int = 3
|
||||
# let y = 1 + 2;;
|
||||
val y : int = 3
|
||||
# y * y;;
|
||||
- : int = 9
|
||||
|
||||
Construire une boucle d'interaction avec l'utilisateur en python::
|
||||
|
||||
#!/usr/bin/env python3
|
||||
error = True
|
||||
while error:
|
||||
try:
|
||||
entier = int(input('donnez un entier : '))
|
||||
error = False
|
||||
except:
|
||||
print('une valeur entiere est attendue')
|
||||
print(entier)
|
||||
|
||||
Lire et écrire dans un fichier
|
||||
------------------------------
|
||||
|
||||
Les descripteurs de fichiers (file handle)
|
||||
|
||||
Exemple en python
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> fh = file("test.txt", "w")
|
||||
>>> fh.write("un contenu exemple")
|
||||
>>> fh.close()
|
||||
>>>
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> fh.read()
|
||||
'un contenu exemple'
|
||||
>>> fh.close()
|
||||
>>>
|
||||
|
||||
Linéarisation (serialisation) de données par exemple en json
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import json
|
||||
data = dict(a='essai', b='essai2', c=range(3))
|
||||
with open('data.txt', 'w') as outfile:
|
||||
json.dump(data, outfile)
|
Reference in New Issue
Block a user