mise en place des cours algo + poo
This commit is contained in:
216
algo/poo/cours/Makefile
Normal file
216
algo/poo/cours/Makefile
Normal file
@ -0,0 +1,216 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# User-friendly check for sphinx-build
|
||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
||||
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
|
||||
endif
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " applehelp to make an Apple Help Book"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " xml to make Docutils-native XML files"
|
||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
@echo " coverage to run coverage check of the documentation (if enabled)"
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
.PHONY: html
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
.PHONY: dirhtml
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
.PHONY: singlehtml
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
.PHONY: pickle
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
.PHONY: json
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
.PHONY: htmlhelp
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
.PHONY: qthelp
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Algorithmique.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Algorithmique.qhc"
|
||||
|
||||
.PHONY: applehelp
|
||||
applehelp:
|
||||
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
|
||||
@echo
|
||||
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
|
||||
@echo "N.B. You won't be able to view it unless you put it in" \
|
||||
"~/Library/Documentation/Help or install it in your application" \
|
||||
"bundle."
|
||||
|
||||
.PHONY: devhelp
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/Algorithmique"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Algorithmique"
|
||||
@echo "# devhelp"
|
||||
|
||||
.PHONY: epub
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
.PHONY: latex
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
.PHONY: latexpdf
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
.PHONY: latexpdfja
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
.PHONY: text
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
.PHONY: man
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
.PHONY: texinfo
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
.PHONY: info
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
.PHONY: gettext
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
.PHONY: changes
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
.PHONY: linkcheck
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
.PHONY: doctest
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
||||
@echo "Testing of coverage in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/coverage/python.txt."
|
||||
|
||||
.PHONY: xml
|
||||
xml:
|
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
.PHONY: pseudoxml
|
||||
pseudoxml:
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
BIN
algo/poo/cours/_static/cesi.jpg
Normal file
BIN
algo/poo/cours/_static/cesi.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
291
algo/poo/cours/algo.txt
Normal file
291
algo/poo/cours/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.
|
83
algo/poo/cours/annexes/agile.txt
Normal file
83
algo/poo/cours/annexes/agile.txt
Normal file
@ -0,0 +1,83 @@
|
||||
La planification agile
|
||||
========================
|
||||
|
||||
Le mode itératif
|
||||
-----------------
|
||||
|
||||
- livrer des versions successives et utilisables qui convergent vers
|
||||
la version finale
|
||||
|
||||
- ne pas perdre d'énergie à maintenir des specs détaillées non nécessaires
|
||||
|
||||
- de nouvelles orientations fonctionnelles sont possibles, même tard
|
||||
|
||||
- les specs détaillées sont écrites "juste à temps"
|
||||
|
||||
|
||||
La planification agile
|
||||
-----------------------
|
||||
|
||||
- chaque livraison est un projet qui est planifié en tant que tel
|
||||
- utiliser l'expérience acquise pour affiner les estimations
|
||||
- préservation de l'écologie du projet au quotidien (code, tests...)
|
||||
|
||||
La confiance, feedback
|
||||
-----------------------
|
||||
|
||||
- livraisons régulières
|
||||
- progrès visibles par tous (pas d'effet tunnel)
|
||||
- pilotage du projet par choix du contenu des livraisons
|
||||
- investissement du Product Owner
|
||||
- chercher la collaboration plutôt que la confrontation
|
||||
|
||||
L'agilité
|
||||
----------
|
||||
|
||||
- le projet n'est pas joué d'avance
|
||||
- cultiver la souplesse
|
||||
- révolution douce
|
||||
- sortir de la confrontation, jouer le "nous collectif"
|
||||
mettre tout le monde sur le mme pont et amener tout le monde à bon port
|
||||
|
||||
Les outils agiles
|
||||
------------------
|
||||
|
||||
- planification par itérations de 4 semaines
|
||||
- entrepot de source partagé
|
||||
- intégration continue
|
||||
- tests automatisés
|
||||
- pair programming sur points cruciaux
|
||||
- sprints
|
||||
- extranet :
|
||||
|
||||
- hitoires utilisateurs
|
||||
- test cases
|
||||
- gestion du backolog et des tickets
|
||||
- suivi de l'avancement
|
||||
- documentation
|
||||
|
||||
Le product owner
|
||||
-----------------
|
||||
|
||||
idéalement,
|
||||
|
||||
- connaissance du métier à informatiser
|
||||
- fibre projet
|
||||
- dispo à 100%
|
||||
|
||||
Les tests
|
||||
---------
|
||||
|
||||
- automatiser
|
||||
- viser l'exhaustivité
|
||||
- tester une cible mouvante
|
||||
- migrer les tests d'une release à l'autre
|
||||
|
||||
Questions importantes en environnement agile
|
||||
----------------------------------------------
|
||||
|
||||
- quelle durée d'itération ?
|
||||
- comment découper en itérations ?
|
||||
- que faire lorsque le product owner se retrouve sur le chemin critique ?
|
||||
- la planification est faite en mode "juste à temps" et "juste assez"
|
||||
- on ne s'échine plus à blâmer, au contraire on cherche à gagner ensemble
|
19
algo/poo/cours/annexes/exercices.txt
Normal file
19
algo/poo/cours/annexes/exercices.txt
Normal file
@ -0,0 +1,19 @@
|
||||
Exercices complémentaires
|
||||
--------------------------
|
||||
|
||||
+ **Manipulation de chaînes de caractères**:
|
||||
(création, accès à un caractère, concaténation), listes (création, ajout
|
||||
d’un élément, suppression d’un élément, accès à un élément, extraction d’une partie de liste), tableaux à une ou plusieurs dimensions.
|
||||
|
||||
+ traitement des chaines de caractères
|
||||
+ s.replace()
|
||||
+ s1 + s2
|
||||
+ un exemple de regexp simple
|
||||
|
||||
+ **Fichiers** :
|
||||
notion de chemin d’accès, lecture et écriture de données numériques ou de type chaîne de caractères depuis ou vers un fichier.
|
||||
On encourage l’utilisation de fichiers en tant que supports de données ou de résultats avant divers traitements, par exemple graphiques.
|
||||
|
||||
+ **Piles**
|
||||
Algorithmes de manipulation : fonctions 'push' et 'pop'. On utilise des listes
|
||||
(ou tableaux à 1 dimension) pour leur implantation.
|
10
algo/poo/cours/annexes/index.txt
Normal file
10
algo/poo/cours/annexes/index.txt
Normal file
@ -0,0 +1,10 @@
|
||||
Annexes
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
exercices
|
||||
surete
|
||||
agile
|
||||
scrum
|
176
algo/poo/cours/annexes/scrum.txt
Normal file
176
algo/poo/cours/annexes/scrum.txt
Normal file
@ -0,0 +1,176 @@
|
||||
scrum
|
||||
=====
|
||||
|
||||
.. glossary::
|
||||
|
||||
scrum
|
||||
|
||||
Scrum est une méthode agile pour la gestion de projets
|
||||
Le terme Scrum est emprunté au rugby et signifie mêlée.
|
||||
Ce processus s'articule en effet autour d'une équipe soudée,
|
||||
qui cherche à atteindre un but, comme c'est le cas en rugby
|
||||
pour avancer avec le ballon pendant une mêlée.
|
||||
|
||||
|
||||
Scrum définit trois rôles principaux :
|
||||
|
||||
- le responsable de produit -- Product Manager,
|
||||
- le faciliteur -- ScrumMaster
|
||||
- le développeur
|
||||
|
||||
et bien sûr, l'équipe (auto-gérée).
|
||||
|
||||
Des intervenants peuvent s'intégrer également au projet
|
||||
de façon plus ponctuelle.
|
||||
|
||||
responsable de produit
|
||||
|
||||
Le responsable de produit (Product Manager) est le représentant des
|
||||
clients et utilisateurs.
|
||||
C'est lui qui définit l'ordre dans lequel les fonctionnalités
|
||||
seront développées et qui prend les décisions importantes
|
||||
concernant l'orientation du projet.
|
||||
|
||||
Le terme responsable n'est d'ailleurs pas à prendre au sens hiérarchique
|
||||
du terme, mais dans le sens de l'orientation.
|
||||
|
||||
équipe, développement
|
||||
|
||||
outes les décisions sont prises ensemble et personne ne donne d'ordre
|
||||
à l'équipe sur sa façon de procéder
|
||||
|
||||
facilitateur
|
||||
|
||||
est chargé de protéger l'équipe de tous les éléments perturbateurs
|
||||
|
||||
planification
|
||||
--------------
|
||||
|
||||
Scrum utilise une planification à trois niveaux :
|
||||
|
||||
- release/projet
|
||||
- sprint
|
||||
- quotidien -- ScrumMeeting
|
||||
|
||||
quotidien
|
||||
|
||||
Au quotidien, une réunion, le ScrumMeeting (pas plus de 15 min)
|
||||
permet à l'équipe et au ScrumMaster de faire un point d'avancement sur
|
||||
les tâches et sur les difficultés rencontrées.
|
||||
répondre à trois questions :
|
||||
* Qu'est-ce que j'ai fait hier ?
|
||||
* Qu'est-ce que je compte faire aujourd'hui ?
|
||||
* Quelles difficultés est-ce que je rencontre ?
|
||||
|
||||
sprint
|
||||
|
||||
Scrum est un processus itératif : les itérations sont appelées des sprints
|
||||
et durent en théorie 30 jours calendaires.
|
||||
En pratique, les itérations durent généralement entre 2 et 4 semaines.
|
||||
Chaque sprint possède un but et on lui associe une liste d'items
|
||||
de fonctionnalités à réaliser.
|
||||
Ces items sont décomposés par l'équipe en tâches élémentaires
|
||||
de quelques heures, les items de fonctionnalités de sprint.
|
||||
|
||||
Pendant un sprint, les items de fonctionnalités de sprint à réaliser
|
||||
ne peuvent pas être changés.
|
||||
Les changements éventuels seront éventuellement réalisés
|
||||
dans les sprints suivants.
|
||||
|
||||
releases
|
||||
|
||||
pour améliorer la lisibilité du projet,
|
||||
on regroupe généralement des itérations en releases.
|
||||
En effet, comme chaque sprint doit aboutir à la livraison
|
||||
d'un produit partiel, une release permet de marquer la livraison
|
||||
d'une version aboutie, susceptible d'être mise en exploitation
|
||||
|
||||
gestion des besoins
|
||||
-------------------
|
||||
|
||||
tâches (backlog de sprint)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Lorsqu'on démarre un sprint, on choisit quels items des fonctionnalités
|
||||
seront réalisés dans ce sprint.
|
||||
|
||||
L'équipe décompose ensuite chaque item en liste de tâches élémentaires
|
||||
(techniques ou non), chaque tâche étant estimée en heures
|
||||
et ne devant pas durer plus de 2 jours.
|
||||
On constitue ainsi le backlog de sprint.
|
||||
|
||||
Les items de backlog de produit sont les fonctionnalités qui deviendront
|
||||
les items du baclog d'un sprint.
|
||||
Ces fonctionnalités sont estimées en points relatifs, sans unité.
|
||||
|
||||
planning poker
|
||||
|
||||
façon ludique et efficace de produire des estimations
|
||||
sur la complexité des fonctionnalités à développer
|
||||
|
||||
pour évaluer les scénarios utilisateurs (user stories)
|
||||
du carnet de produit (product backlog).
|
||||
|
||||
à la fin d'un sprint :
|
||||
|
||||
- revue de sprint
|
||||
- rétrospective de sprint
|
||||
|
||||
comprendre ce qui n'a pas bien marché dans le sprint,
|
||||
les erreurs commises et de prendre des décisions pour s'améliorer
|
||||
|
||||
mise en oeuvre
|
||||
--------------
|
||||
|
||||
Scrum peut être mis en pratique avec trois fois rien : deux listes suffisent.
|
||||
La liste des items du backlog de produit et la liste des items du backlog
|
||||
de sprint. La saisie et la mise à jour des données est simplement
|
||||
un peu moins agréable.
|
||||
|
||||
glossaire
|
||||
---------
|
||||
|
||||
Directeur de produit (Product Owner) (responsable produit)
|
||||
|
||||
personne responsable de produire et maintenir à jour le backlog de produit.
|
||||
C'est lui qui en détermine les priorités et qui prend les décisions
|
||||
concernant l'orientation du projet.
|
||||
|
||||
ScrumMaster (facilitateur)
|
||||
|
||||
membre de l'équipe dont l'objectif principal est de la protéger
|
||||
des perturbation extérieures.
|
||||
Il est complètement transparent pour la communication entre l'équipe
|
||||
et les clients et n'a aucun pouvoir hiérarchique sur l'équipe.
|
||||
C'est en revanche un facilitateur pour les problèmes non techniques
|
||||
de l'équipe.
|
||||
|
||||
Backlog de produit (Product Backlog) (fonctionnalités)
|
||||
|
||||
liste des fonctionnalités qui devront être réalisées par le logiciel.
|
||||
|
||||
Backlog de sprint (Sprint Backlog) (tâches)
|
||||
|
||||
liste des tâches à accomplir pendant un sprint.
|
||||
Elles correspondent à la réalisation des items de backlog
|
||||
du produit affectés au sprint.
|
||||
|
||||
Mêlée quotidienne (Daily Scrum) (quotidien)
|
||||
|
||||
réunion quotidienne de 15 minutes qui a pour but de faire le point
|
||||
sur ce qui a été fait depuis la dernière mêlée,
|
||||
ce qui est prévu de faire jusqu'à la prochaine
|
||||
et quelles sont les embûches rencontrées durant le travail.
|
||||
|
||||
Sprint (sprint)
|
||||
|
||||
nom d'une itération dans Scrum.
|
||||
Cette itération dure 30 jours calendaires en théorie,
|
||||
mais en pratique on utilise plutôt entre 2 et 4 semaines.
|
||||
Pendant une itération, l'équipe doit développer une liste d'items
|
||||
du backlog de produit qui a été définie au début de ce sprint.
|
||||
|
||||
Graphique d'avancement (Burndown Chart) (avancement)
|
||||
|
||||
graphique qui montre la tendance du reste à faire total de jour en jour
|
||||
(pour les sprints) ou de sprint en sprint (pour les releases).
|
93
algo/poo/cours/annexes/surete.txt
Normal file
93
algo/poo/cours/annexes/surete.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Outils de sureté d'un programme
|
||||
--------------------------------------
|
||||
|
||||
La preuve de programme
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Le niveau maximum de sûreté d'exécution d'un programme est la preuve. Qu'est-ce que la preuve
|
||||
formelle d'un programme ? Selon la définition de Wikipédia, ce sont "des techniques permettant de
|
||||
raisonner rigoureusement, à l'aide de logique mathématique, sur des programmes informatiques ou
|
||||
du matériel électroniques, afin de démontrer leur validité par rapport à une certaine
|
||||
spécification." Bref c'est un raisonnement logique sur un programmme qui permet d'être sûr que le
|
||||
programme est valide et ne va pas planter.
|
||||
|
||||
La preuve de programme est très peu utilisée dans l'industrie, car très coûteuse et très
|
||||
difficile à mettre en place. Elle quand même utilisée, mais dans des secteurs où le risque doit
|
||||
absolument être évacué et où il n'y a aucun droit à l'erreur. Par exemple, le secteur médical
|
||||
(informatique en bloc opératoire), militaire (peu d'informations nous parviennent dans ce
|
||||
domaine), l'aviation civile (le logiciel Astrée pour Airbus), la fusée Ariane (depuis le bug qui
|
||||
avait fait crasher Ariane 5 ces questions sont prises très au sérieux), et le milieu bancaire
|
||||
(surtout le domaine des décisions boursières : un programme chargé de lancer des décisions
|
||||
d'achat ou de vente à la bourse qui comporte un bug peut en quelque centièmes de secondes faire
|
||||
perdre des millions, voire des milliards d'euros à une banque. Le programme ne doit tout simplement pas
|
||||
bugger).
|
||||
|
||||
Le model checking
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Le model checking, l'analyse statique et l'interprétation abstraite procèdent d'une méthodologie
|
||||
moins lourde de validation des programmes. Ces méthodes analysent exhaustivement l'évolution du
|
||||
système lors de ses exécutions possibles et permetent de dire si globalement, dans un contexte
|
||||
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é.
|
||||
|
||||
Les tests d'acceptation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
Les Outils de linting (validation)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- 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.
|
||||
Les tests permettent de solder la dette technique plus facilement.
|
||||
|
||||
**avoir le courage de payer une dette technique, et affronter une dette technique
|
||||
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
|
||||
cher à payer.
|
||||
|
||||
Les méthodologies agiles
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
La manière dont le code est produit importe énormément. Par exemple, une
|
||||
méthodologie ou le **refactoring** (réécriture de code) est permis et même conseillé
|
||||
a plus de chance de produire du code organisé.
|
||||
|
||||
Les méthodologies agiles produisent en général du code mieux organisé. Ce sont les
|
||||
méthodes de travail les plus en vogue aujourd'hui, elles mettent l'accent sur :
|
||||
|
||||
- Du logiciel fonctionnel plutôt que de la documentation exhaustive
|
||||
- La réponse au changement plutôt que le suivi d'un plan
|
||||
- Le logiciel fonctionnel est la principale mesure d'avancement
|
||||
- Une attention continue à l'excellence technique et à une bonne
|
||||
conception améliore l'agilité
|
||||
- La simplicité est essentielle (il est facile de faire, il est
|
||||
difficile de faire simple)
|
||||
|
||||
Le principe de base de la méthodologie Scrum par exemple est de focaliser l'équipe de façon
|
||||
itérative sur un ensemble de fonctionnalités à réaliser, dans des itérations de durée fixe de une
|
||||
à quatre semaines, appelées **sprints**. Chaque sprint possède un but à atteindre, défini par le
|
||||
responsable de produit, à partir duquel sont choisies les fonctionnalités à implémenter dans ce
|
||||
sprint. Un sprint aboutit toujours sur la livraison d'un produit partiel fonctionnel. Pendant ce
|
||||
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.
|
79
algo/poo/cours/apercu.txt
Normal file
79
algo/poo/cours/apercu.txt
Normal file
@ -0,0 +1,79 @@
|
||||
Aperçu des algorithmes fondamentaux
|
||||
===================================
|
||||
|
||||
Les algorithmes sont partout. Absolument partout aujourd'hui.
|
||||
Il n'est pas un domaine de nos activités qui ne soit liés à tel ou tel algorithme.
|
||||
|
||||
En mathématiques
|
||||
-----------------
|
||||
|
||||
- l'algèbre (étude des structures de données)
|
||||
- l'arithmétique modulaire (théorie des nombres)
|
||||
- la géométrie (affine, algébrique, invariants topologiques...)
|
||||
- les diagrammes (diagrammes de Venn...)
|
||||
- les colorisation d'une carte
|
||||
- comportements stochastiques
|
||||
|
||||
En informatique
|
||||
----------------
|
||||
|
||||
- les algorithmes sur la manipulation des structures de données
|
||||
Exemple : les algorithmes de tri, de recherche dans un arbre...
|
||||
- les parcours de graphes (chemins le plus court, voyageur de commerce...)
|
||||
- la cryptologie (code gray)
|
||||
- les stratégies de jeux
|
||||
|
||||
Tirés du monde réel
|
||||
--------------------
|
||||
|
||||
- les jeux (casse-tête, dominos, échiquiers...)
|
||||
- énigmes, logique et paradoxes
|
||||
- problèmes de raisonnements. Il n'existe pas beaucoup de méthodes
|
||||
ou de moyens simples pour traiter et résoudre les énoncés de logique de raisonnement.
|
||||
- La "marche de l'ivrogne" : processus de progression discrète (pas à pas)
|
||||
dont l'étape suivante est lié à l'état présent et pas du tout à la mémoire du passé proche.
|
||||
Il revêt seulement un caractère de type probabilité (stochastique) dit markovien.
|
||||
- algorithmes de colonies de fourmis (chemins optimal pour arriver à la nourriture)
|
||||
|
||||
Le voyageur de commerce
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Le problème du voyageur de commerce, consiste en la recherche d’un trajet minimal permettant à un
|
||||
voyageur de visiter n villes. En règle générale on cherche à minimiser le temps de parcours total ou la
|
||||
distance totale parcourue.
|
||||
|
||||
Il suffit de construire tous les chemins possibles et de calculer leurs longueurs.
|
||||
Avec ``n`` villes il y a ``(n-1)!/2`` chemins possibles.
|
||||
Avec 36 villes on trouve : 5166573983193072464833325668761600000000,
|
||||
si le nombre de villes augmente, ça devient vite rédibitoire.
|
||||
|
||||
Résolution par
|
||||
|
||||
- algorithme de parcours de graphes
|
||||
- algorithme glouton
|
||||
- algorithmes génétiques
|
||||
|
||||
Les algorithmes génétiques s’appuient sur un principe de sélection des individus d’une population qui présen-
|
||||
tent des caractéristiques se rapprochant au mieux de ce que l’on recherche; cette population évoluant par
|
||||
ailleurs selon des critères d’évolution génétique à choisir. Dans le contexte du problème du voyageur de
|
||||
commerce, un individu est une tournée, un chemin et une population un ensemble de tournées. Il s’agit
|
||||
maintenant de dé...nir un critère de sélection ainsi que des règles d’évolution de la population.
|
||||
|
||||
- approches métaheuristiques (exemples: colonies de fourmis)
|
||||
|
||||
Exemple de résolution
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Algorithme du voyageur de commerce}\label{commerce}
|
||||
\begin{algorithmic}[1]
|
||||
|
||||
\BState \emph{Données} : $L$ \Comment{Liste des villes à parcourir avec les distances entre les villes}
|
||||
\BState \emph{Données} : $L'$ \Comment{Liste du parcours des villes à effectuer}
|
||||
\State \emph{début}
|
||||
\BState ...
|
||||
\State \emph{fin}
|
||||
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
61
algo/poo/cours/cesar.py
Normal file
61
algo/poo/cours/cesar.py
Normal file
@ -0,0 +1,61 @@
|
||||
# coding: utf-8
|
||||
minuscules = 'abcdefghijklmnopqrstuvwxyz'
|
||||
majuscules = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
||||
def rotation(chaine, x):
|
||||
"""
|
||||
Effectue une rotation de x caractères vers la droite:
|
||||
>>> rotation('abcde', 2)
|
||||
'cdeab'
|
||||
"""
|
||||
return chaine[x:] + chaine[:x]
|
||||
|
||||
def index(c, chaine):
|
||||
"""
|
||||
Trouve l'index de c dans la chaine:
|
||||
>>> index('n', 'bonjour')
|
||||
2
|
||||
"""
|
||||
for i in range(len(chaine)):
|
||||
if (c == chaine[i]):
|
||||
return i
|
||||
return -1
|
||||
|
||||
def chiffre_minuscules(chaine, x):
|
||||
"""
|
||||
Chiffre une chaîne composée de minuscules
|
||||
>>> chiffre_minuscules('bonjour', 3)
|
||||
'erqmrxu'
|
||||
"""
|
||||
r = rotation(minuscules, x)
|
||||
resultat = ''
|
||||
for lettre in chaine:
|
||||
resultat = resultat + r[index(lettre, minuscules)]
|
||||
return resultat
|
||||
|
||||
def chiffre(chaine, x):
|
||||
"""
|
||||
Chiffre une chaîne quelconque
|
||||
>>> chiffre('Bonjour les amis!', 3)
|
||||
'Erqmrxu ohv dplv!'
|
||||
"""
|
||||
r_min = rotation(minuscules, x)
|
||||
r_maj = rotation(majuscules, x)
|
||||
resultat = ''
|
||||
for lettre in chaine:
|
||||
if lettre in minuscules:
|
||||
resultat = resultat + r_min[index(lettre, minuscules)]
|
||||
elif lettre in majuscules:
|
||||
resultat = resultat + r_maj[index(lettre, majuscules)]
|
||||
else:
|
||||
resultat = resultat + lettre
|
||||
return resultat
|
||||
|
||||
#############################################################################
|
||||
# Programme principal
|
||||
#############################################################################
|
||||
print(chiffre_minuscules('bonjour', 3))
|
||||
print(chiffre('Bonjour les amis!', 3))
|
||||
print(chiffre('Erqmrxu ohv dplv!', 23))
|
||||
print(chiffre('Eudyr, yrxv dyhc ilql fhw hahuflfh!', 23))
|
||||
|
17
algo/poo/cours/code/factorielle.ml
Normal file
17
algo/poo/cours/code/factorielle.ml
Normal file
@ -0,0 +1,17 @@
|
||||
let rec fact = function
|
||||
|1 -> 1
|
||||
| n -> n * fact (n-1) ;;
|
||||
|
||||
let print_fact n =
|
||||
Printf.printf "factorielle %i = %i\n" n (fact n)
|
||||
|
||||
let main () =
|
||||
begin
|
||||
print_fact 5 ;
|
||||
print_newline () ;
|
||||
exit 0 ;
|
||||
end
|
||||
|
||||
let _ = main ()
|
||||
|
||||
|
12
algo/poo/cours/code/factorielle.py
Normal file
12
algo/poo/cours/code/factorielle.py
Normal file
@ -0,0 +1,12 @@
|
||||
def factorielle(n):
|
||||
if (n > 1):
|
||||
r = n*factorielle(n-1)
|
||||
else:
|
||||
r = 1
|
||||
return r
|
||||
|
||||
def print_fact(n):
|
||||
print "factorielle {} = {}\n".format(5, factorielle(5))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print_fact(5)
|
370
algo/poo/cours/conf.py
Normal file
370
algo/poo/cours/conf.py
Normal file
@ -0,0 +1,370 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Algorithmique documentation build configuration file, created by
|
||||
# sphinx-quickstart on Thu Mar 16 16:07:00 2017.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx.ext.pngmath', 'sphinx.ext.ifconfig',
|
||||
]
|
||||
|
||||
# ajout des cours avec solution des exercices ou non
|
||||
def setup(app):
|
||||
app.add_config_value('correction', False, 'env')
|
||||
app.add_config_value('exercice', False, 'env')
|
||||
|
||||
exercice = False
|
||||
correction = False
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.txt'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Algorithmique Approfondie'
|
||||
copyright = u'2017, Gwen'
|
||||
author = u'Gwen'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = u'1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = u'1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = 'fr'
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
today_fmt = '%d/%m/%Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
default_role = 'literal'
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'alabaster'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (relative to this directory) to use as a favicon of
|
||||
# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
html_show_sphinx = False
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
html_show_copyright = False
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Language to be used for generating the HTML full-text search index.
|
||||
# Sphinx supports the following languages:
|
||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
||||
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
|
||||
#html_search_language = 'en'
|
||||
|
||||
# A dictionary with options for the search language support, empty by default.
|
||||
# Now only 'ja' uses this config value
|
||||
#html_search_options = {'type': 'default'}
|
||||
|
||||
# The name of a javascript file (relative to the configuration directory) that
|
||||
# implements a search results scorer. If empty, the default will be used.
|
||||
#html_search_scorer = 'scorer.js'
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'Algorithmiquedoc'
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
'papersize': 'a4paper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
'preamble': """\usepackage{amsmath}
|
||||
\usepackage{algorithm}
|
||||
\usepackage[noend]{algpseudocode}
|
||||
\makeatletter
|
||||
\def\BState{\State\hskip-\ALG@thistlm}
|
||||
\makeatother
|
||||
|
||||
"""
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'ProgrammationOrienteeObjet.tex', u'Cours de programmation orientée objet',
|
||||
u'INFAL26', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
latex_logo = '_static/cesi.jpg'
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = False
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'algorithmique', u'Algorithmique Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'Algorithmique', u'Algorithmique Documentation',
|
||||
author, 'Algorithmique', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
|
||||
|
||||
# -- Options for Epub output ----------------------------------------------
|
||||
|
||||
# Bibliographic Dublin Core info.
|
||||
epub_title = project
|
||||
epub_author = author
|
||||
epub_publisher = author
|
||||
epub_copyright = copyright
|
||||
|
||||
# The basename for the epub file. It defaults to the project name.
|
||||
#epub_basename = project
|
||||
|
||||
# The HTML theme for the epub output. Since the default themes are not
|
||||
# optimized for small screen space, using the same theme for HTML and epub
|
||||
# output is usually not wise. This defaults to 'epub', a theme designed to save
|
||||
# visual space.
|
||||
#epub_theme = 'epub'
|
||||
|
||||
# The language of the text. It defaults to the language option
|
||||
# or 'en' if the language is not set.
|
||||
#epub_language = ''
|
||||
|
||||
# The scheme of the identifier. Typical schemes are ISBN or URL.
|
||||
#epub_scheme = ''
|
||||
|
||||
# The unique identifier of the text. This can be a ISBN number
|
||||
# or the project homepage.
|
||||
#epub_identifier = ''
|
||||
|
||||
# A unique identification for the text.
|
||||
#epub_uid = ''
|
||||
|
||||
# A tuple containing the cover image and cover page html template filenames.
|
||||
#epub_cover = ()
|
||||
|
||||
# A sequence of (type, uri, title) tuples for the guide element of content.opf.
|
||||
#epub_guide = ()
|
||||
|
||||
# HTML files that should be inserted before the pages created by sphinx.
|
||||
# The format is a list of tuples containing the path and title.
|
||||
#epub_pre_files = []
|
||||
|
||||
# HTML files that should be inserted after the pages created by sphinx.
|
||||
# The format is a list of tuples containing the path and title.
|
||||
#epub_post_files = []
|
||||
|
||||
# A list of files that should not be packed into the epub file.
|
||||
epub_exclude_files = ['search.html']
|
||||
|
||||
# The depth of the table of contents in toc.ncx.
|
||||
#epub_tocdepth = 3
|
||||
|
||||
# Allow duplicate toc entries.
|
||||
#epub_tocdup = True
|
||||
|
||||
# Choose between 'default' and 'includehidden'.
|
||||
#epub_tocscope = 'default'
|
||||
|
||||
# Fix unsupported image types using the Pillow.
|
||||
#epub_fix_images = False
|
||||
|
||||
# Scale large images.
|
||||
#epub_max_image_width = 0
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#epub_show_urls = 'inline'
|
||||
|
||||
# If false, no index is generated.
|
||||
#epub_use_index = True
|
294
algo/poo/cours/control.txt
Normal file
294
algo/poo/cours/control.txt
Normal file
@ -0,0 +1,294 @@
|
||||
Les structures de contrôle
|
||||
==========================
|
||||
|
||||
L'instruction de saut
|
||||
----------------------
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Exemple de saut conditionnel}\label{saut}
|
||||
\begin{algorithmic}[1]
|
||||
\Procedure{Euclide}{} \Comment{c'est l'algorithme d'Euclide}
|
||||
\State $\textit{stringlen} \gets \text{length of }\textit{string}$
|
||||
\State $i \gets \textit{patlen}$
|
||||
\BState \emph{top}:
|
||||
\If {$i > \textit{stringlen}$} \Return false
|
||||
\EndIf
|
||||
\State $j \gets \textit{patlen}$
|
||||
\BState \emph{loop}: \Comment{C'est le label (l'étiquette)} \label{etiquette}
|
||||
\If {$\textit{string}(i) = \textit{path}(j)$}
|
||||
\State $j \gets j-1$.
|
||||
\State $i \gets i-1$.
|
||||
\State \textbf{goto} \emph{loop}. \label{goto}
|
||||
\State \textbf{close};
|
||||
\EndIf
|
||||
\State $i \gets
|
||||
i+\max(\textit{delta}_1(\textit{string}(i)),\textit{delta}_2(j))$.
|
||||
\State \textbf{goto} \emph{top}. \Comment{C'est l'instruction de saut}
|
||||
\EndProcedure
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
Ligne \ref{etiquette}, le bloc `loop` est aussi un label (une étiquette),
|
||||
c'est-à-dire une marque posée qu'il est possible de retrouver dans le programme. \\
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
Ligne \ref{goto}, l'instruction \texttt{goto} (aller à ) est le saut vers le label. \\
|
||||
|
||||
Description générique d'une instruction de saut::
|
||||
|
||||
Instruction 1
|
||||
Saut Label1
|
||||
Instruction 2
|
||||
...
|
||||
Label1:
|
||||
Instruction n
|
||||
|
||||
.. important:: les sauts conditionnels sont à éviter, même s'ils sont implémentés
|
||||
dans le langage cible, car c'est le meilleur moyen d'aboutir à
|
||||
du **code spaghetti**.
|
||||
|
||||
L'instruction de branchement conditionnel
|
||||
------------------------------------------
|
||||
|
||||
On appelle structure conditionnelle les instructions qui permettent de tester si une condition est vraie ou non.
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Exemple d'instruction de test}
|
||||
\begin{algorithmic}[1]
|
||||
\BState \emph{entrée}: $quality\gets 0$ \Comment{C'est cette valeur qui sera testée}
|
||||
\BState \emph{locale}: $a\gets ""$
|
||||
\BState \emph{sortie}: $a$ \Comment{La sortie est la valeur de $a$}
|
||||
\BState \emph{corps}:
|
||||
\If{$quality\ge 9$}
|
||||
\State $a\gets perfect$
|
||||
\ElsIf{$quality\ge 7$}
|
||||
\State $a\gets good$
|
||||
\ElsIf{$quality\ge 5$}
|
||||
\State $a\gets medium$
|
||||
\ElsIf{$quality\ge 3$}
|
||||
\State $a\gets bad$
|
||||
\Else
|
||||
\State $a\gets unusable$
|
||||
\EndIf
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Compacter l'algorithme suivant en une seule condition de test::
|
||||
|
||||
Si il fait trop chaud Alors
|
||||
Si il ne pleut pas Alors
|
||||
Ouvrir la fenêtre
|
||||
Sinon
|
||||
Fermer la fenêtre
|
||||
Finsi
|
||||
Sinon
|
||||
Fermer la fenêtre
|
||||
Finsi
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
::
|
||||
|
||||
Si il fait trop chaud ET il ne pleut pas Alors
|
||||
Ouvrir la fenêtre
|
||||
Sinon
|
||||
Fermer la fenêtre
|
||||
Finsi
|
||||
|
||||
|
||||
L'instruction switch
|
||||
--------------------
|
||||
|
||||
L'instruction switch permet de faire plusieurs tests de valeurs sur le contenu d'une même variable.
|
||||
Ce branchement conditionnel simplifie beaucoup le test de plusieurs valeurs d'une variable.
|
||||
|
||||
Les instructions d'itérations (boucles)
|
||||
---------------------------------------
|
||||
|
||||
.. important:: Toutes les boucles concernent le paradigme de programmation impératif
|
||||
et ne sont pas valides dans le paradigme de programmation fonctionnel
|
||||
(puisque l'ordre d'évaluation importe)
|
||||
|
||||
- arrêt conditionnel (break)
|
||||
- passage d'un pas (continue)
|
||||
|
||||
Répéter ... jusqu'à
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Exemple de répéter ... jusqu'à}
|
||||
\begin{algorithmic}[1]
|
||||
\BState \emph{locales}: $i \gets 1$ \Comment{déclaration et initialisation de i}
|
||||
\Repeat \Comment{c'est le label de début du répéter}
|
||||
\State $i \gets \textit{i+1}$
|
||||
\Until{i == 100} \Comment{condition de fin de la boucle}
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
La boucle **pour** (for)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Exemple de boucle for}
|
||||
\begin{algorithmic}[1]
|
||||
\BState \emph{locales}: $sum\gets 0$
|
||||
\For{$i\gets 1, n$}
|
||||
\State $sum\gets sum+i$
|
||||
\EndFor
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Ecrire un algorithme qui demande successivement 20 nombres à l’utilisateur,
|
||||
et qui lui dise ensuite quel était le plus grand parmi ces 20 nombres
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
::
|
||||
|
||||
Variables N, i, PG en Entier
|
||||
Debut
|
||||
PG <- 0
|
||||
Pour i <- 1 à 20
|
||||
Ecrire "Entrez un nombre : "
|
||||
Lire N
|
||||
Si i = 1 ou N > PG Alors
|
||||
PG <- N
|
||||
FinSi
|
||||
Ecrire "Le nombre le plus grand était : ", PG
|
||||
Fin
|
||||
|
||||
|
||||
.. attention:: ne jamais manipuler le compteur dans une boucle
|
||||
|
||||
::
|
||||
|
||||
Variable Truc en Entier
|
||||
Début
|
||||
Pour Truc <- 1 à 15
|
||||
Truc <- Truc * 2
|
||||
Ecrire "Passage numéro : ", Truc
|
||||
Truc Suivant
|
||||
Fin
|
||||
|
||||
La boucle tant que (while)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Exemple de boucle while}
|
||||
\begin{algorithmic}[1]
|
||||
\BState \emph{locales}: $sum\gets 0$
|
||||
\State $i\gets 1$
|
||||
\While{$i\le n$}
|
||||
\State $sum\gets sum+i$
|
||||
\State $i\gets i+1$
|
||||
\EndWhile
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Ecrire un algorithme de validation d'une entrée utilisateur
|
||||
|
||||
::
|
||||
|
||||
"Voulez vous un café ? (O/N)"
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** : deux solutions possibles, une
|
||||
|
||||
::
|
||||
|
||||
Variable Rep en Caractère
|
||||
Début
|
||||
Rep <- ""
|
||||
Ecrire "Voulez vous un café ? (O/N)"
|
||||
TantQue Rep <> "O" et Rep <> "N"
|
||||
Lire Rep
|
||||
Si Rep <> "O" et Rep <> "N" Alors
|
||||
Ecrire "Saisie Erronée, Recommencez"
|
||||
FinSi
|
||||
FinTantQue
|
||||
Fin
|
||||
|
||||
::
|
||||
|
||||
Variable Rep en Caractère
|
||||
Début
|
||||
Ecrire "Voulez vous un café ? (O/N)"
|
||||
Lire Rep
|
||||
TantQue Rep <> "O" et Rep <> "N"
|
||||
Ecrire "Vous devez répondre par O ou N. Recommencez"
|
||||
Lire Rep
|
||||
FinTantQue
|
||||
Ecrire "Saisie acceptée"
|
||||
Fin
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : "C'est plus, C'est moins", c'est-à-dire Ecrire un algorithme qui demande à l’utilisateur
|
||||
un nombre compris entre a et b jusqu’à ce que la réponse convienne.
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
::
|
||||
|
||||
Variable N en Entier
|
||||
Debut
|
||||
N <- 0
|
||||
Ecrire "Entrez un nombre entre 10 et 20"
|
||||
TantQue N < 10 ou N > 20
|
||||
Lire N
|
||||
Si N < 10 Alors
|
||||
Ecrire "Plus grand !"
|
||||
SinonSi N > 20 Alors
|
||||
Ecrire "Plus petit !"
|
||||
FinSi
|
||||
FinTantQue
|
||||
Fin
|
||||
|
||||
Et les autres boucles : répéter... jusqu'à, etc...
|
||||
|
||||
.. raw:: latex
|
||||
|
||||
\begin{algorithm}
|
||||
\caption{Exemple de boucle répéter}
|
||||
|
||||
\begin{algorithmic}[1]
|
||||
\State $sum\gets 0$
|
||||
\State $i\gets 1$
|
||||
\Repeat
|
||||
\State $sum\gets sum+i$
|
||||
\State $i\gets i+1$
|
||||
\Until{$i>n$}
|
||||
\end{algorithmic}
|
||||
\end{algorithm}
|
577
algo/poo/cours/donnees.txt
Normal file
577
algo/poo/cours/donnees.txt
Normal file
@ -0,0 +1,577 @@
|
||||
Les structures de données
|
||||
===========================
|
||||
|
||||
.. glossary::
|
||||
|
||||
ATD
|
||||
|
||||
Abstract Data Type, structure de données abstraites.
|
||||
La représentation des données est forcément un choix.
|
||||
Il est impossible de rendre compte globalement d'un élément du réel,
|
||||
il faut en faire une interprétation abstraite.
|
||||
|
||||
**Exemple**:
|
||||
|
||||
- Un être humain peut être représenté par les données présentes dans sa
|
||||
carte d'identité. Mais un être humain n'est pas sa carte d'identité.
|
||||
- Un être humain peut être représenté par les données présentes dans ses préférences
|
||||
de surf sur internet. Mais un être humain **n'est pas** l'ensemble de ses logs de surf sur le net.
|
||||
|
||||
Les séquences
|
||||
-------------
|
||||
|
||||
Les types séquences (listes)
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# 4::1::5::8::1::[];;
|
||||
- : int list = [4 ;1 ;5 ;8 ;1]
|
||||
|
||||
|
||||
Un ensemble de valeurs portant le même nom de variable et repérées par un nombre, s’appelle un tableau, ou encore une liste, ou une variable indicée.
|
||||
Le nombre qui, au sein d’un tableau, sert à repérer chaque valeur s’appelle l’indice.
|
||||
Chaque fois que l’on doit désigner un élément du tableau, on fait figurer le nom du tableau, suivi de l’indice de l’élément.
|
||||
|
||||
**manipulation** :
|
||||
|
||||
- `insert()`
|
||||
- `append()`
|
||||
- `remove()`
|
||||
- `find()`
|
||||
- `print()`
|
||||
- ...
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
zoo = ['bear', 'lion', 'panda', 'zebra']
|
||||
print(zoo)
|
||||
|
||||
# But these list elements are not
|
||||
biggerZoo = ['bear', 'lion', 'panda', 'zebra', ['chimpanzees', 'gorillas', 'orangutans', 'gibbons']]
|
||||
print(biggerZoo)
|
||||
|
||||
- Lists Versus Tuples : types mutables, immutables
|
||||
- Lists Versus Sets : non ordonné, collection simple
|
||||
|
||||
- Recherche dans une liste, recherche du maximum dans une liste
|
||||
- Recherche d’un mot dans une chaîne de caractères.
|
||||
|
||||
Algorithme de la longueur d'une liste
|
||||
--------------------------------------
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# let rec longueur l =
|
||||
match l with
|
||||
[] -> 0
|
||||
| ::s -> 1 + (longueur s);;
|
||||
|
||||
Cette fonction est prédéfinie en Ocaml : `List.length`
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : écrire un algorithme qui déclare et
|
||||
remplisse un tableau de 7 valeurs numériques en les mettant toutes à zéro.
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
::
|
||||
|
||||
Tableau Truc(6) en Numérique
|
||||
Variable i en Numérique
|
||||
Debut
|
||||
Pour i <- 0 à 6
|
||||
Truc(i) <- 0
|
||||
i Suivant
|
||||
Fin
|
||||
|
||||
exemple d'implémentation en python
|
||||
|
||||
.. code-block: python
|
||||
|
||||
>>> liste = []
|
||||
>>> for i in range(6):
|
||||
... liste.append(i)
|
||||
...
|
||||
>>> liste
|
||||
[0, 1, 2, 3, 4, 5]
|
||||
>>>
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Calcul du premier élément maximal dans une liste,
|
||||
proposer une implémentation en python qui renvoie le maximum et
|
||||
la position du max dans la liste.
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
.. code-block: python
|
||||
|
||||
def max_list(L) :
|
||||
k = len(L)
|
||||
max, x = L[0], 0
|
||||
i = 1
|
||||
while i < k :
|
||||
if max < L[i]:
|
||||
max = L[i]
|
||||
x = i
|
||||
i = i + 1
|
||||
return max, x
|
||||
|
||||
couple = max_list([4,5,6,9,12,5,10,3,18,5,6,7])
|
||||
print ’Max de L est ’, couple[0]
|
||||
print ’et se trouve à la position ’, couple[1]
|
||||
|
||||
Exemple de généricité : ce code fonctionne avec une chaîne de caractères.
|
||||
|
||||
.. code-block: python
|
||||
|
||||
couple = max_list(’totovaaumarche’)
|
||||
print ’Max de L est ’, couple[0]
|
||||
print ’et se trouve à la position ’, couple[1]
|
||||
|
||||
.. glossary::
|
||||
|
||||
Matrice
|
||||
|
||||
Tableaux de dimension multiple, c'est un tableau de tableau
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Écrivez un algorithme remplissant un tableau de 6 sur 13, avec des zéros.
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
implémentation en python
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> matrice = []
|
||||
>>> for i in range(12):
|
||||
... matrice.append([0 for i in range(5)])
|
||||
...
|
||||
>>> from pprint import pprint
|
||||
>>> pprint(matrice)
|
||||
[[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0]]
|
||||
>>>
|
||||
|
||||
Algorithmes de tri
|
||||
------------------
|
||||
|
||||
On désigne par "tri" l'opération consistant à ordonner un ensemble d'éléments en fonction de clés sur lesquelles est définie une relation d'ordre.
|
||||
|
||||
Les algorithmes de tri ont une grande importance pratique.
|
||||
Ils sont fondamentaux dans certains domaines (exemples : map-reduce en database non relationnelle).
|
||||
|
||||
L'étude du tri est également intéressante en elle-même, c'est un des domaines de l'algorithmique très étudié et connu.
|
||||
|
||||
Tri par insertion
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Cet algorithme de tri suit de manière naturelle la structure récursive des
|
||||
listes. Soit l une liste à trier :
|
||||
|
||||
- si l est vide alors elle est déjà triée
|
||||
- sinon, l est de la forme x::s et on trie récursivement la suite s et on obtient une liste triée s’
|
||||
on insert x au bon endroit dans s’ et on obtient une liste triée
|
||||
|
||||
Description de l'algorithme
|
||||
|
||||
- la fonction inserer permet d’insérer un élément x dans une liste l
|
||||
- si la liste l est triée alors x est inséré au bon endroit
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# let rec inserer x l =
|
||||
match l with
|
||||
[] -> [x]
|
||||
| y::s -> if x<=y then x::l else y::(inserer x s);;
|
||||
val inserer : ’a -> ’a list -> ’a list
|
||||
# inserer 5 [3 ;7 ;10];;
|
||||
- : int list = [3 ; 5 ; 7 ; 10]
|
||||
|
||||
Tri rapide
|
||||
~~~~~~~~~~~~
|
||||
|
||||
soit une liste l à trier :
|
||||
|
||||
- si l est vide alors elle est triée
|
||||
- sinon, choisir un élément p de la liste (le premier par exemple)
|
||||
nommé le **pivot**
|
||||
- partager l en deux listes g et d contenant les autres éléments de l
|
||||
qui sont plus petits (resp. plus grands) que la valeur du pivot p
|
||||
- trier récursivement g et d, on obtient deux listes g’ et d’ triées
|
||||
|
||||
.. code-block:: ocaml
|
||||
:caption: fonction de partage d'une liste
|
||||
|
||||
#let rec partage p l =
|
||||
match l with
|
||||
[] -> ([] , [])
|
||||
|x::s -> let g,d = partage p s in
|
||||
if x<=p then (x::g , d) else (g , x::d) ;;
|
||||
val partage : ’a -> ’a list -> ’a list * ’a list = <fun>
|
||||
# partage 5 [1 ;9 ;7 ;3 ;2 ;4];;
|
||||
- : int list * int list = ([1 ; 3 ; 2 ; 4], [9 ; 7])
|
||||
|
||||
.. code-block:: ocaml
|
||||
:caption: algorithme de tri rapide
|
||||
|
||||
# let rec tri rapide l =
|
||||
match l with
|
||||
[] -> []
|
||||
| p::s -> let g , d = partage p s in
|
||||
(tri rapide g)@[p]@(tri rapide d) ;;
|
||||
val tri rapide : ’a list -> ’a list = <fun>
|
||||
# tri rapide [5 ; 1 ; 9 ; 7 ; 3 ; 2 ; 4];;
|
||||
- : int list = [1 ; 2 ; 3 ; 4 ; 5 ; 7 ; 9]
|
||||
|
||||
|
||||
Définition d'un itérateur
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> l = range(10)
|
||||
>>> for i in l:
|
||||
... print l[i]
|
||||
...
|
||||
0
|
||||
...
|
||||
8
|
||||
9
|
||||
>>> l.__iter__()
|
||||
<listiterator object at 0x7f78bb450410>
|
||||
|
||||
|
||||
Les listes chaînées
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
typedef struct list{
|
||||
int elt ;
|
||||
struct list* suivant ;
|
||||
} ;
|
||||
|
||||
|
||||
**Outils de manipulation** :
|
||||
|
||||
- `next()`
|
||||
- `pointer()`
|
||||
- `insert(l, a)`
|
||||
- `remove(a, n)`
|
||||
|
||||
|
||||
Les piles
|
||||
----------
|
||||
|
||||
**manipulation**
|
||||
|
||||
- `insert()` : insérer un élément à la fin de la pile
|
||||
- `dequeue()` : (remove and return) : retirer un élément du haut de la pile
|
||||
- FIFO : "first in first out"
|
||||
|
||||
|
||||
Traduction d'une structure de données dans une autre
|
||||
-----------------------------------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> listOfStrings = ['One', 'Two', 'Three']
|
||||
>>> strOfStrings = ' '.join(listOfStrings)
|
||||
>>> print(strOfStrings)
|
||||
One Two Three
|
||||
>>>
|
||||
>>> # List Of Integers to a String
|
||||
... listOfNumbers = [1, 2, 3]
|
||||
>>> strOfNumbers = ''.join(str(n) for n in listOfNumbers)
|
||||
>>> print(strOfNumbers)
|
||||
123
|
||||
>>>
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> l = [('host1', '10.1.2.3', '6E:FF:56:A2:AF:18'), ('host3', '10.1.2.5', '6E:FF:56:A2:AF:19')]
|
||||
>>> result = []
|
||||
>>> for hostname, ip, macaddress in l:
|
||||
... result.append(dict(hostname=hostname, ip=ip, macaddress=macaddress))
|
||||
...
|
||||
>>> result
|
||||
[{'hostname': 'host1', 'ip': '10.1.2.3', 'macaddress': '6E:FF:56:A2:AF:18'},
|
||||
{'hostname': 'host3', 'ip': '10.1.2.5', 'macaddress': '6E:FF:56:A2:AF:19'}]
|
||||
>>>
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Proposer un algorithme de traduction de cette structure de donnée
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
[
|
||||
{
|
||||
'address': '192.168.0.0',
|
||||
'mask': '255.255.255.0',
|
||||
'dynamicRanges': [
|
||||
{ 'low': '192.168.0.5', 'high': '192.168.0.12', 'only_unknown': True },
|
||||
{ 'low': '192.168.0.50', 'high': '192.168.0.55', 'only_unknown': False },
|
||||
],
|
||||
},
|
||||
{
|
||||
'address': '192.168.0.0',
|
||||
'mask': '255.255.255.0',
|
||||
'dynamicRanges': [
|
||||
{ 'low': '192.168.0.12', 'high': '192.168.0.45', 'only_unknown': True },
|
||||
{ 'low': '192.168.0.8', 'high': '192.168.0.35', 'only_unknown': False },
|
||||
],
|
||||
},
|
||||
{
|
||||
'address': '192.168.0.1',
|
||||
'mask': '255.255.255.0',
|
||||
'dynamicRanges': [
|
||||
{ 'low': '192.168.0.5', 'high': '192.168.0.12', 'only_unknown': True },
|
||||
{ 'low': '192.168.0.50', 'high': '192.168.0.55', 'only_unknown': False },
|
||||
],
|
||||
},
|
||||
|
||||
]
|
||||
|
||||
En cette structure de données :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
[
|
||||
{
|
||||
address: '192.168.0.0',
|
||||
mask: '255.255.255.0',
|
||||
dynamicRanges: [
|
||||
{ low: '192.168.0.5', high: '192.168.0.12', only_unknown: true },
|
||||
{ low: '192.168.0.50', high: '192.168.0.55', only_unknown: false },j
|
||||
], [
|
||||
{ low: '192.168.0.12', high: '192.168.0.45', only_unknown: true },
|
||||
{ low: '192.168.0.8', high: '192.168.0.35', only_unknown: false },
|
||||
],
|
||||
},
|
||||
{
|
||||
'address': '192.168.0.1',
|
||||
'mask': '255.255.255.0',
|
||||
'dynamicRanges': [
|
||||
{ 'low': '192.168.0.5', 'high': '192.168.0.12', 'only_unknown': True },
|
||||
{ 'low': '192.168.0.50', 'high': '192.168.0.55', 'only_unknown': False },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from pprint import pprint
|
||||
pprint(l)
|
||||
[{'address': '192.168.0.0',
|
||||
'dynamicRanges': [{'high': '192.168.0.12',
|
||||
'low': '192.168.0.5',
|
||||
'only_unknown': True},
|
||||
{'high': '192.168.0.55',
|
||||
'low': '192.168.0.50',
|
||||
'only_unknown': False}],
|
||||
'mask': '255.255.255.0'},
|
||||
{'address': '192.168.0.0',
|
||||
'dynamicRanges': [{'high': '192.168.0.45',
|
||||
'low': '192.168.0.12',
|
||||
'only_unknown': True},
|
||||
{'high': '192.168.0.35',
|
||||
'low': '192.168.0.8',
|
||||
'only_unknown': False}],
|
||||
'mask': '255.255.255.0'}]
|
||||
>>> newdata = []
|
||||
>>> for i in l:
|
||||
... if i['address'] not in [j['address'] for j in newdata]:
|
||||
... newdata.append(i)
|
||||
... else:
|
||||
... for k in newdata:
|
||||
... if k['address'] == i['address']:
|
||||
... k['dynamicRanges'].extend(i['dynamicRanges'])
|
||||
...
|
||||
>>> pprint(newdata)
|
||||
[{'address': '192.168.0.0',
|
||||
'dynamicRanges': [{'high': '192.168.0.12',
|
||||
'low': '192.168.0.5',
|
||||
'only_unknown': True},
|
||||
{'high': '192.168.0.55',
|
||||
'low': '192.168.0.50',
|
||||
'only_unknown': False},
|
||||
{'high': '192.168.0.45',
|
||||
'low': '192.168.0.12',
|
||||
'only_unknown': True},
|
||||
{'high': '192.168.0.35',
|
||||
'low': '192.168.0.8',
|
||||
'only_unknown': False}],
|
||||
'mask': '255.255.255.0'},
|
||||
{'address': '192.168.10.0',
|
||||
'dynamicRanges': [{'high': '192.168.0.12',
|
||||
'low': '192.168.0.5',
|
||||
'only_unknown': True},
|
||||
{'high': '192.168.0.55',
|
||||
'low': '192.168.0.50',
|
||||
'only_unknown': False}],
|
||||
'mask': '255.255.255.0'}]
|
||||
>>>
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**Exercice** : Proposer un algorithme qui permette de récupérer la liste
|
||||
des adresses IP disponibles
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
{
|
||||
"local": {
|
||||
"leases": [
|
||||
{
|
||||
"mac": "02:00:c0:a8:00:66",
|
||||
"name": "pcxubuntu",
|
||||
"address": "192.168.0.200"
|
||||
},
|
||||
{
|
||||
"mac": "02:00:c0:a8:00:67",
|
||||
"name": "pcxubuntu",
|
||||
"address": "192.168.0.201"
|
||||
},
|
||||
{
|
||||
"mac": "02:00:c0:a8:00:68",
|
||||
"name": "pcxubuntu",
|
||||
"address": "192.168.0.202"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
.. ifconfig:: correction
|
||||
|
||||
**Correction** :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> l = {
|
||||
... "local": {
|
||||
... "leases": [
|
||||
... {
|
||||
... "mac": "02:00:c0:a8:00:66",
|
||||
... "name": "pcxubuntu",
|
||||
... "address": "192.168.0.200"
|
||||
... },
|
||||
... {
|
||||
... "mac": "02:00:c0:a8:00:67",
|
||||
... "name": "pcxubuntu",
|
||||
... "address": "192.168.0.201"
|
||||
... },
|
||||
... {
|
||||
... "mac": "02:00:c0:a8:00:68",
|
||||
... "name": "pcxubuntu",
|
||||
... "address": "192.168.0.202"
|
||||
... }
|
||||
... ]
|
||||
... }
|
||||
... }
|
||||
>>> leases = l["local"]["leases"]
|
||||
>>> from pprint import pprint
|
||||
>>> pprint(leases)
|
||||
[{'address': '192.168.0.200', 'mac': '02:00:c0:a8:00:66', 'name': 'pcxubuntu'},
|
||||
{'address': '192.168.0.201', 'mac': '02:00:c0:a8:00:67', 'name': 'pcxubuntu'},
|
||||
{'address': '192.168.0.202', 'mac': '02:00:c0:a8:00:68', 'name': 'pcxubuntu'}]
|
||||
>>> addresses = [lease['address'] for lease in leases]
|
||||
>>> addresses
|
||||
['192.168.0.200', '192.168.0.201', '192.168.0.202']
|
||||
>>>
|
||||
|
||||
|
||||
|
||||
Structures de données complexes
|
||||
-------------------------------
|
||||
|
||||
Les types produits nommés
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
On les appelle enregistrements, dictionnaires ou tables de hachage.
|
||||
|
||||
::
|
||||
|
||||
algorithme monAlgorithme
|
||||
// déclaration d'un enregistrement
|
||||
enregistrement Personne
|
||||
chaine nom;
|
||||
chaine prenom;
|
||||
entier age;
|
||||
réel taille;
|
||||
finenregistrement
|
||||
...
|
||||
Personne[50] t;
|
||||
début
|
||||
// Initialisation
|
||||
t[0].nom <- "Duchmol";
|
||||
t[0].prenom <- "Robert";
|
||||
t[0].age <- 24;
|
||||
t[0].taille <- 1.80;
|
||||
...
|
||||
fin
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# type adresse = { rue : string ; ville : string ; cp : int};;
|
||||
# type fiche = {
|
||||
nom : string ;
|
||||
prenom : string ;
|
||||
adresse : adresse ;
|
||||
date naissance : int * int * int ;
|
||||
tel fixe : string ;
|
||||
portable : string
|
||||
};;
|
||||
# let v1 = { a = 1 ; b = false ; c = 'r'};;
|
||||
|
||||
|
||||
|
||||
|
||||
- les sommes (constructeurs)
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
# type couleur = Pique | Coeur | Carreau | Trefle;;
|
||||
# let v = (Pique , Coeur);;
|
||||
val v : couleur * couleur = (Pique , Coeur)
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
type nombre =
|
||||
Ent of int | Reel of float | Cplx of float × float
|
||||
Ent, Reel, Cplx sont les constructeurs du type.
|
||||
|
||||
Autres structures de données complexes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- arbres
|
||||
- graphes
|
||||
- dates
|
||||
|
||||
- le parcours de graphes
|
||||
- les calculs de dates
|
588
algo/poo/cours/fonctions.txt
Normal file
588
algo/poo/cours/fonctions.txt
Normal file
@ -0,0 +1,588 @@
|
||||
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
|
||||
>>>
|
198
algo/poo/cours/fondement.txt
Normal file
198
algo/poo/cours/fondement.txt
Normal file
@ -0,0 +1,198 @@
|
||||
Présentation de l'art de programmer
|
||||
====================================
|
||||
|
||||
Qu'est-ce que la programmation ?
|
||||
--------------------------------
|
||||
|
||||
programmation
|
||||
|
||||
Description d’un calcul (traitement) dans
|
||||
un langage compréhensible par la machine
|
||||
(langage de programmation)
|
||||
|
||||
Le processus d'abstraction
|
||||
--------------------------
|
||||
|
||||
Débuter en programmation n'est pas une chose aisée. Aujourd'hui, la tendance est au
|
||||
"bas niveau". Souvent, on se jette dans le grand bain :
|
||||
|
||||
- soit en s'approchant au maximum de la machine (admin système et réseau, noyau
|
||||
linux, langage C)
|
||||
|
||||
- soit en faisant du dev web côté backend, ce qui ramène à une administration réseau
|
||||
de bas niveau (microservices, monde nodeJS/javascript, etc...)
|
||||
|
||||
Soit on suit un cursus scolaire traditionnel qui commence souvent par une
|
||||
explication du fonctionnement d'une machine abstraite de bas niveau, puis en
|
||||
allant de plus en plus haut, mais étant sous-entendu qu'il faut rester connecté au
|
||||
bas niveau (comprendre comment ça se passe derrière la scène).
|
||||
|
||||
Dans ces deux cas, il est sous-entendu qu'on apprend plus de choses et plus rapidement en mettant
|
||||
les mains dans le cambouis, ce qui est vrai bien sûr. Mais cela sous-entend qu'un développeur doit
|
||||
rester le nez dans le guidon. Qu'il doit être un expert de son domaine en accumulant des technologies
|
||||
sans aucun recul. Bien sûr il se doit d'être un expert du système dans lequel il évolue
|
||||
(connaissance du système d'exploitation, binding avec le C, du ramasse miette (garbage
|
||||
collector), interaction avec les différentes librairies, gestion et optimisation de la mémoire,
|
||||
architecture par microservices, threads...) mais il doit aussi être capable de prendre du recul.
|
||||
|
||||
L'approche algorithmique (algorithmique de pseudo code, algorithmique algébrique et modulaire)
|
||||
est un véritable moyen pour le programmeur de prendre du recul : elle commence par se placer du
|
||||
côté de l'esprit humain et de ses capacités de compréhension et d'abstraction, elle autorise une
|
||||
pensée rationnelle sur l'art de programmer et permet au programmeur d'effectuer les bons choix,
|
||||
en connaissance de sa discipline.
|
||||
|
||||
Le lien est fait ensuite avec le plus bas niveau grâce une implémentation effective
|
||||
des langages à partir des paradigmes de rationalisation de la penseée (modules,
|
||||
objects, généricité, polymorphisme paramétrique...) et d'un outil de communication
|
||||
avec la machine qu'on appelle compilateur (dont la description est en dehors de
|
||||
l'objectif de ce cours).
|
||||
|
||||
La tendance générale de l'évolution des langages est de se libérer de ces
|
||||
contraintes de bas niveau, un peu comme en sciences physiques où les lois physiques
|
||||
dépendent de l'échelle d'en dessous (du niveau microscopique/quantique) mais qu'à
|
||||
l'échelle du dessus, on n'a pas affaire à des effets de bas niveau (pas d'effets
|
||||
quantiques à un niveau macroscopique en général). Ce processus d'évolution est vrai
|
||||
aussi dans le monde de la technique informatique lui-même (modèle OSI, comment est
|
||||
construite une trame IP, indépendances de chaque couche (transport, payload) entre
|
||||
elles). Même la tendance système est à la virtualisation qui accentue encore la
|
||||
tendance à s'affranchir du bas niveau (le niveau système), le séparer nettement du
|
||||
haut niveau (le niveau applicatif).
|
||||
|
||||
Il apparaît régulièrement de nouveaux langages. Comment s'orienter ? Quel(s)
|
||||
langage(s) choisir pour un projet de développement ? Au delà de leurs disparités, la
|
||||
conception et la genèse de chacun d'eux procèdent d'une motivation partagée : la
|
||||
volonté d'abstraire.
|
||||
|
||||
- **s'abstraire de la machine** : un langage de programmation permet de
|
||||
négliger l'aspect *mécanique* de l'ordinateur. On oublie le modèle du
|
||||
microprocesseur, jusqu'au système d'exploitation sur lequel sera exécuté
|
||||
le programme.
|
||||
|
||||
- **abstraire les erreurs** : Il s'agit ici de garantir la sûreté d'exécution; un
|
||||
programme ne doit pas se terminer brutalement ou devenir incohérent en cas d'erreur.
|
||||
Un des moyens pour y parvenir est le typage des programmes et la mise
|
||||
en oeuvre d'un mécanisme d'exceptions.
|
||||
|
||||
- **abstraire le mode opératoire** : Il s'agit de choisir une représentation, un
|
||||
paradigme d'implémentation qui est indépendant du domaine considéré (paradigme
|
||||
objet, modulaire, générique, composants...)
|
||||
|
||||
- **abstraire les composants** : Les langages de programmation donnent la
|
||||
possibilité de découper une application en différents composants logiciels, plus ou
|
||||
moins indépendants et autonomes. La modularité permet une structuration de plus haut
|
||||
niveau de l'ensemble d'une application complexe. Les langages à objets constituent
|
||||
une autre approche de la réutilisabilité permettant la réalisation très rapide de
|
||||
prototypes.
|
||||
|
||||
Description des niveaux d'abstraction par rapport à la machine
|
||||
---------------------------------------------------------------
|
||||
|
||||
Les langages de haut niveau simplifient le travail du
|
||||
programmeur là où les langages de bas niveau permettent de produire un code
|
||||
plus efficace.
|
||||
|
||||
- **niveau 0** : le langage machine. Illisible, c'est une suite d'optcode.
|
||||
impossible de coder dans ce langage.
|
||||
|
||||
- **niveau 1** : langage d'assemblage. Il reste très dépendant de la machine
|
||||
et aujourd'hui il est rare d'en faire, sauf si on code un bootloader par exemple,
|
||||
la gestion de l'accès à la mémoire est en réel (le mode protégé n'apparaît que après).
|
||||
Il faut gérer les ressources,le langage est très optimisé mais presque impossible
|
||||
à maintenir et rendre générique. Aujourd'hui plus personne ne code en assembleur.
|
||||
|
||||
- **niveau 2** : langages dits de **bas niveau** : (exemple : le C, le C++)
|
||||
indépendance par rapport à la machine, grande structuration mais très verbeux
|
||||
|
||||
- **niveau 3** : langages dits de **haut niveau** : le raisonnement dans ces
|
||||
langages ne dépent plus de la machine, et ils implémentent des paradigmes de
|
||||
programmation indépendant de l'état de la mémoire de l'ordinateur,
|
||||
ils sont indépendant même du système d'exploitation.
|
||||
|
||||
Qu'est-ce qu'une machine ?
|
||||
---------------------------
|
||||
|
||||
Une machine, ce truc apparemment si complexe, est en fait
|
||||
un assemblage de bric et de brac.
|
||||
|
||||
L'assemblage des connecteurs permet de simuler un additionneur,
|
||||
en prenant en compte les propriétés de **reste euclidien**
|
||||
de l'addition.
|
||||
|
||||
La structure électronique est composée de :
|
||||
|
||||
- un ordonnanceur.
|
||||
- le stockage d'un **état**.
|
||||
- une pile d'instruction
|
||||
|
||||
.. glossary::
|
||||
|
||||
adressage
|
||||
|
||||
Dès lors qu'on dispose de ces bases électronique au dessus du processeur,
|
||||
un langage d'assemblage est possible, c'est le langage de calcul sur les registres.
|
||||
|
||||
registre
|
||||
|
||||
machines ont un espace mémoire et un espace de calcul (registres)
|
||||
|
||||
Un ordinateur, c'est très très stupide, mais ça permet de disposer de :
|
||||
|
||||
- une mémoire très grande et ordonnée,
|
||||
- une capacité à effectuer inlassablement des tâches répétitives
|
||||
- une grande rapidité de calcul
|
||||
|
||||
Apprendre à programmer, c'est-à-dire être capable de
|
||||
contrôler la machine.
|
||||
|
||||
.. important:: Apprendre à programmer, c'est-à-dire apprendre à penser de manière structurée,
|
||||
pour pouvoir accessoirement ensuite communiquer avec une machine.
|
||||
|
||||
Compilateur
|
||||
-----------
|
||||
|
||||
Schématiquement, un compilateur est un programme qui traduit un
|
||||
programme d’un langage source vers un langage cible, en signalant
|
||||
d’éventuelles erreurs.
|
||||
|
||||
Quand on parle de compilation, on pense typiquement à la traduction d’un
|
||||
langage de haut niveau (C, Java, Caml, ...) vers le langage machine d’un
|
||||
processeur (Intel Pentium, PowerPC, ...)
|
||||
|
||||
- xml (libre office, word) -> postscript (imprimante)
|
||||
- postcript -> image
|
||||
- syntaxe wiki -> html (Wikipédia...)
|
||||
|
||||
compilation graphique
|
||||
|
||||
passer une description, ça donne un dessin genre ocaml Quilt < mon_dessin.txt
|
||||
passer par une api qui permet de causer avec une interface
|
||||
|
||||
**transpiler** : transformation d'un langage de haut niveau vers un autre
|
||||
langage de haut niveau.
|
||||
|
||||
- cofee script, typescript -> javascript
|
||||
- (babel) javascript -> javascript ES 6
|
||||
- python -> javascript
|
||||
|
||||
Un compilateur traduit un programme P en un programme Q tel que
|
||||
pour toute entrée x , la sortie de `Q(x)` soit la même que celle de `P(x)`
|
||||
|
||||
Un interprète est un programme qui, étant donné un programme `P` et une
|
||||
entrée x , calcule la sortie s de `P(x)`
|
||||
|
||||
Le compilateur fait un travail complexe une seule fois, pour produire un
|
||||
code fonctionnant pour n’importe quelle entrée
|
||||
L’interprète effectue un travail plus simple, mais le refait sur chaque entrée
|
||||
Autre différence : le code compilé est généralement bien plus efficace que
|
||||
le code interprété
|
||||
|
||||
Typiquement, le travail d’un compilateur se compose d’une phase d’analyse
|
||||
|
||||
- reconnaît le programme à traduire et sa signification
|
||||
- signale les erreurs et peut donc échouer (erreurs de syntaxe, de portée, de typage, etc.)
|
||||
|
||||
Puis d’une phase de synthèse
|
||||
|
||||
- production du langage cible
|
||||
- utilise de nombreux langages intermédiaires
|
||||
- n’échoue pas
|
19
algo/poo/cours/index.txt
Normal file
19
algo/poo/cours/index.txt
Normal file
@ -0,0 +1,19 @@
|
||||
Introduction à l'algorithmique
|
||||
================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
presentation
|
||||
fondement
|
||||
langage
|
||||
algo
|
||||
programme
|
||||
fonctions
|
||||
control
|
||||
donnees
|
||||
apercu
|
||||
modularite
|
||||
modules
|
||||
tp
|
||||
annexes/index
|
335
algo/poo/cours/langage.txt
Normal file
335
algo/poo/cours/langage.txt
Normal file
@ -0,0 +1,335 @@
|
||||
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
|
||||
=========== ============
|
200
algo/poo/cours/modularite.txt
Normal file
200
algo/poo/cours/modularite.txt
Normal file
@ -0,0 +1,200 @@
|
||||
La programmation structurée
|
||||
=============================
|
||||
|
||||
Un langage de programmation doit permettre la programmation structurée.
|
||||
|
||||
.. important:: La structuration et l'organisation modulaire sert à maintenir de grands programmes,
|
||||
Elles sont une nécessité
|
||||
|
||||
Structuration d'un programme
|
||||
-----------------------------
|
||||
|
||||
La réalisation d'applications importantes oblige le programmeur ou l'équipe de
|
||||
développement à se poser des questions d'organisation et de structuration.
|
||||
Aujourd'hui, on dispose de deux grands modèles d'organisation dont les avantages et les
|
||||
particularités sont distincts.
|
||||
|
||||
L'écriture des vrais programmes consiste à les structurer pour les présenter
|
||||
comme un assemblage de briques qui s'emboîtent naturellement.
|
||||
Ce problème se révèle fondamental dès que la taille des programmes devient conséquente.
|
||||
Si on ne prend pas garde au bon découpage des programmes en modules indépendants,
|
||||
on se retrouve rapidement débordé par un grand nombre de variables,
|
||||
et il devient quasiment impossible de réaliser un programme correct.
|
||||
|
||||
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).
|
||||
|
||||
Conception descendante
|
||||
-----------------------
|
||||
|
||||
Une vision **centripète** : du général au particulier.
|
||||
|
||||
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.
|
||||
|
||||
On met des *trous* dans les algorithmes de plus haut niveau,
|
||||
c'est-à-dire des phrases en langage naturel.
|
||||
|
||||
.. ifconfig: exercice
|
||||
|
||||
**Exercice** : **Calculer la date du lendemain**
|
||||
|
||||
.. ifconfig: correction
|
||||
|
||||
- l'algorithme de plus bas niveau
|
||||
|
||||
::
|
||||
|
||||
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
|
||||
|
||||
- les algorithmes de plus bas niveau
|
||||
|
||||
::
|
||||
|
||||
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.
|
||||
|
||||
Algorithme vague
|
||||
--------------------
|
||||
|
||||
L'algorithme vague, c'est quand on pense l'algorithme en se plaçant du côté de
|
||||
l'implémentation en premier. On a le nez dans le guidon, la vue d'ensemble est
|
||||
difficile.
|
||||
|
||||
Voici, tiré du monde réel, un exemple d'algorithme vague
|
||||
("ce que doit faire une fonction"), placé dans un bout de code
|
||||
(souvent la **docstring** d'une fonction).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def upsert_route(*args, **kwargs):
|
||||
"""
|
||||
Create or modify an existant DHCP route
|
||||
param tuple (id or null, machine name, IP, MAC Adress)
|
||||
return True or False with error message
|
||||
"""
|
||||
# si id présent alors modification sinon ajout
|
||||
# récupère la liste des réservations en cours
|
||||
# y cherche la variable sur la base de l'ID
|
||||
# modifie les valeurs
|
||||
# applique la nouvelle conf DHCP
|
||||
|
||||
return True
|
||||
|
||||
Voici un autre bout de code avec l'algorithme en commentaire,
|
||||
et l'implémentation effective de l'algorithme
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def del_route(*args, **kwargs):
|
||||
"""
|
||||
Delete an existant DHCP route
|
||||
param tuple (id, machine name, IP, MAC Adress)
|
||||
return True or False with error message
|
||||
"""
|
||||
# récupère la liste des réservations en cours
|
||||
# y cherche la variable sur l'id donné en paramètre
|
||||
# supprime l'entrée avec vérification que les données fournies
|
||||
# sont bien dans l'enregistrement à supprimer
|
||||
# applique la nouvelle conf DHCP
|
||||
route_to_del = (1, "host2","10.1.2.4","6E:FF:56:A2:AF:17")
|
||||
routes = get_routes()
|
||||
if route_to_del in routes:
|
||||
c = creole_loader(load_extra=True, rw=True)
|
||||
c_id = c.dhcp.dhcp.id_dhcp.id_dhcp.index(route_to_del[0])
|
||||
if c.dhcp.dhcp.id_dhcp.macaddress[c_id]==route_to_del[2]
|
||||
and c.dhcp.dhcp.id_dhcp.ip[c_id]==route_to_del[1]:
|
||||
c.dhcp.dhcp.id_dhcp.id_dhcp.pop(c_id)
|
||||
config_save_values(c, MODNAME)
|
||||
return True
|
||||
return False
|
||||
|
||||
Les deux grands paradigmes
|
||||
---------------------------
|
||||
|
||||
La modularité
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Les données et les traitements sont regroupés au sein d'une même entité à deux
|
||||
facettes : d'un côté le code proprement dit, de l'autre son interface. La
|
||||
communication entre modules s'effectue via leur interface. La description d'un
|
||||
type peut être masquée en n'apparaissant pas dans l'interface du module. Ces
|
||||
types de données abstraits facilitent les modifications d'implantation à
|
||||
l'intérieur d'un module sans affecter les autres modules qui s'en servent. De
|
||||
plus, les modules peuvent être paramétrés par d'autres modules augmentant
|
||||
ainsi leur réutilisabilité.
|
||||
|
||||
Le paradigme objet
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Les descriptions des traitements et des données sont regroupées dans des
|
||||
entités appelées **classes**; un objet est une instance (valeur) d'une classe.
|
||||
La communication entre objets est réalisée par envoi de message, l'objet
|
||||
receveur détermine à l'exécution (liaison retardée) le traitement
|
||||
correspondant au message. En cela, la programmation objet est dirigée par
|
||||
les données. La structuration d'un programme provient des relations entre
|
||||
classes, en particulier l'héritage permet de définir une classe par extension
|
||||
d'une autre.
|
||||
|
||||
En programmation objet, un **programme** est une collection d’objets qui communiquent
|
||||
entre eux par **message**, le **résultat** est un message envoyé à un objet particulier
|
||||
|
||||
Comparaison entre les deux paradigmes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Il y a dualité entre ces deux modèles.
|
||||
|
||||
- On ne peut pas augmenter les composants d'un type dans un module (pas
|
||||
d'extensibilité des données), mais on peut ajouter de nouveaux traitements
|
||||
(extensibilité des traitements) sur ces données.
|
||||
|
||||
- En objet, on peut ajouter des sous-classes à une classe (extensibilité des
|
||||
données) pour traiter des nouveaux cas, mais on ne peut pas ajouter de nouveaux
|
||||
traitements visibles de la classe ancêtre (pas d'extensibilité des traitements).
|
||||
|
||||
**La combinaison des deux paradigmes offre de nouvelles extensibilités pour les
|
||||
traitements et les données.**
|
313
algo/poo/cours/modules.txt
Normal file
313
algo/poo/cours/modules.txt
Normal file
@ -0,0 +1,313 @@
|
||||
La programmation modulaire
|
||||
===========================
|
||||
|
||||
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 d’emploi du module, avec en plus un principe de masquage
|
||||
des informations (partie publique, partie secrète)
|
||||
|
||||
|
||||
Signatures, type abstrait et langage de modules : la programmation modulaire
|
||||
permet d'aller très loin dans la programmation structurée.
|
||||
|
||||
|
||||
Définir des fonctions dans un fichier séparé
|
||||
--------------------------------------------
|
||||
|
||||
Les fonctions peuvent être définies dans un fichier et le programme dans un
|
||||
autre fichier séparé. Dans ce cas, pour pouvoir être exécuté directement avec
|
||||
la commande python `nomfichierprogramme.py`, le fichier du programme doit
|
||||
importer d’abord les fonctions du fichier dans lequel les fonctions sont
|
||||
définies.
|
||||
|
||||
1. Fichier de fonctions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Fichier foncmaxliste.py
|
||||
# Recherche le premier élément maximal dans une liste ou
|
||||
#dans une chaine de caractères
|
||||
def max_list(L) :
|
||||
k = len(L)
|
||||
max, x = L[0], 0
|
||||
i = 1
|
||||
while i < k :
|
||||
if max < L[i]:
|
||||
max = L[i]
|
||||
x = i
|
||||
i = i + 1
|
||||
return max, x
|
||||
|
||||
2. Fichier de programme
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Pour utilser les fonctions définies dans d’autres fichiers, le fichier de
|
||||
programme doit commencer par les instructions qui importent ces fichiers de
|
||||
fonctions ou directement les fonctions de ces fichiers. Dans la syntaxe
|
||||
ci-dessous, on importe une ou toutes les fonctions du fichier `foncmaxlist.py`.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Fichier progmaxlist.py
|
||||
from foncmaxliste import max_list
|
||||
# ou plus simple:
|
||||
# from foncmaxliste import *
|
||||
print max_list([4,5,6,9,12,5,10,3,18,5,6,7])
|
||||
couple = max_list([4,5,6,9,12,5,10,3,18,5,6,7])
|
||||
print ’Max de L est ’, couple[0]
|
||||
print ’et se trouve à la position ’, couple[1]
|
||||
print max_list(’totovaaumarche’)
|
||||
couple = max_list(’totovaaumarche’)
|
||||
print ’Max de L est ’, couple[0]
|
||||
print ’et se trouve à la position ’, couple[1]
|
||||
|
||||
Au lieu d’importer les fonctions, on peut importer le fichier qui définit les
|
||||
fonctions avec la syntaxe qui suit. Dans ce cas, le fichier de programme sera
|
||||
changé comme suit :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Fichier prog2maxlist
|
||||
import foncmaxliste
|
||||
print foncmaxliste.max_list([4,5,6,9,12,5,10,3,18,5,6,7])
|
||||
# la syntaxe indiquant le chemin d’acces a la fonction max_list utiliser ‘‘.’’
|
||||
couple = foncmaxliste.max_list([4,5,6,9,12,5,10,3,18,5,6,7])
|
||||
print ’Max de L est ’, couple[0]
|
||||
print ’et se trouve à la position ’, couple[1]
|
||||
print foncmaxliste.max_list(’totovaaumarche’)
|
||||
couple = foncmaxliste.max_list(’totovaaumarche’)
|
||||
print ’Max de L est ’, couple[0]
|
||||
print ’et se trouve à la position ’, couple[1]
|
||||
|
||||
L’exécution directe du premier fichier de programme::
|
||||
|
||||
python prog max list.py
|
||||
|
||||
L’exécution directe du seconde fichier de programme::
|
||||
|
||||
python prog2 max list.py
|
||||
|
||||
Définition de l'implémentation d'un module
|
||||
-------------------------------------------
|
||||
|
||||
Tout fichier qui contient au moins une définition d’une fonction ou d’une
|
||||
variable est appelé un module (une bibliothèque). Le nom du module est le nom
|
||||
du fichier enlevé le suffixe `.py`. Ainsi, un fichier de programme qui contient
|
||||
au moins une définition d’une fonction ou un fichier qui ne contient que des
|
||||
définition de fonctions sont des modules. On peut importer un module ou des
|
||||
fonctions ou variables d’un module dans un programme, comme nous avons vu dans
|
||||
les exemples ci-dessus.
|
||||
|
||||
.. important:: on peut importer un module, ou bien lancer un module en tant que
|
||||
programme executable
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
Pour faciliter la programmation, Python définit un certain nombre de **modules internes**,
|
||||
appelés les builtins (la librairie standard).
|
||||
|
||||
Par exemple :
|
||||
|
||||
– Lors de l’ouverture d’une session interactive, on est dans un module interne nommé
|
||||
main . Toutes les variables définies par affectation au niveau de ce module sont valides
|
||||
globalement dans la session.
|
||||
|
||||
– D’autres modules internes sont string, math, random
|
||||
|
||||
Dans une session de travail sous l’interpréteur Python, la première importation d’un mo-
|
||||
dule qui, à part des fonctions qu’elle définit, contient des instruction de programme fait
|
||||
exécuter ces instructions. Dans la même session, les importations suivantes ne font pas
|
||||
exécuter ces instructions. Pour les exécuter, on utilise la fonction reload(nomdumodule)
|
||||
(sans sufffixe .py).
|
||||
|
||||
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
|
||||
|
||||
Le langages des modules
|
||||
-------------------------
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
module type PILE = (* signature (interface) du module *)
|
||||
sig
|
||||
type ’a t
|
||||
val create : unit -> ’a t
|
||||
val push : ’a -> ’a t -> unit
|
||||
val pop : ’a t -> ’a
|
||||
end
|
||||
|
||||
(* implémentation du module *)
|
||||
module Pile : PILE = (* le module est restreint
|
||||
par la signature PILE *)
|
||||
struct
|
||||
type ’a t = ’a list ref
|
||||
let create () = ref []
|
||||
let push x p = p := x::!p
|
||||
let pop p = match !p with [...]
|
||||
let rec print p = match p with [...]
|
||||
end
|
||||
|
||||
- `struct .. end` introduit une collection de définitions, valeurs, types ou modules.
|
||||
C'est une **structure**.
|
||||
|
||||
- `module Nom = struct .. end` permet de donner un nom à cette structure et
|
||||
c'est ça un module. C'est une structure nommée.
|
||||
|
||||
- `sig ... end` introduit une signature de module : une interface pour un module.
|
||||
|
||||
On restreint souvent une structure par une signature pour "cacher" certaines
|
||||
définitions. Une signature de module fournit une **interface** entre l'extérieur
|
||||
et l'intérieur d'un module.
|
||||
|
||||
En dehors du module, on accède à ses composants grâce à la notation pointée
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
let p = Pile.create()
|
||||
Pile.push 45 p
|
||||
|
||||
Les foncteurs
|
||||
--------------
|
||||
|
||||
Si un langage possède un langage de modules, on peut aller plus loin : on peut
|
||||
considérer un module comme étant une expression de base du langage.
|
||||
|
||||
- La signature d'un module peut être considérée comme le type du module
|
||||
- La structure du module peut être considéré comme sa valeur
|
||||
|
||||
Quel est l'intérêt ? On peut alors définir des **foncteurs**.
|
||||
|
||||
foncteur
|
||||
|
||||
"fonction" d'une structure vers une autre structure.
|
||||
On peut ainsi paramétrer un module par un autre module.
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
module Nom (M1 :S1 ) (M2 :S2 ) (M3 :S3 ) ... =
|
||||
struct
|
||||
...
|
||||
end
|
||||
|
||||
On applique un foncteur à des paramètres modules, pour
|
||||
obtenir un nouveau module :
|
||||
|
||||
.. code-block:: ocaml
|
||||
|
||||
module M = F (Titi) (Toto)
|
||||
|
||||
|
||||
Contrainte de type par signature
|
||||
------------------------------------
|
||||
|
||||
::
|
||||
|
||||
module M =
|
||||
struct
|
||||
type t = int * int * int ;;
|
||||
let make d m y = d, m, y ;;
|
||||
end ;;
|
||||
|
||||
let d = M.make 8 5 8 ;;
|
||||
|
||||
module type S =
|
||||
sig
|
||||
type t ;;
|
||||
val make : int -> int -> int -> t ;;
|
||||
end ;;
|
||||
|
||||
module MS = (M:S) ;;
|
||||
|
||||
MS.make 5 1 2 ;;
|
||||
|
||||
Type et signature
|
||||
------------------
|
||||
|
||||
::
|
||||
|
||||
# module type A = sig
|
||||
val a: int -> int
|
||||
end ;;
|
||||
module type A = sig val a : int -> int end
|
||||
# module B = struct
|
||||
let a x = x + 1 ;;
|
||||
end;;
|
||||
module B : sig val a : int -> int end
|
||||
# module C = (B:A) ;;
|
||||
module C : A
|
||||
|
||||
# C.a 2 ;;
|
||||
- : int = 3
|
||||
#
|
||||
|
||||
Module auquel on impose une signature
|
||||
-----------------------------------------
|
||||
|
||||
|
||||
::
|
||||
|
||||
module type DATE = sig
|
||||
type t
|
||||
val make: int -> t
|
||||
val get_year: t -> int
|
||||
val get_month: t -> int
|
||||
end ;;
|
||||
|
||||
module MR = struct
|
||||
type t = int * int
|
||||
let make x y = (x, y)
|
||||
let get_month (x, y) = x
|
||||
let get_year (x, y) = y
|
||||
end ;;
|
||||
|
||||
module date = (MR:DATE) ;;
|
10
algo/poo/cours/presentation.txt
Normal file
10
algo/poo/cours/presentation.txt
Normal file
@ -0,0 +1,10 @@
|
||||
Avant propos
|
||||
============
|
||||
|
||||
Introduction
|
||||
~~~~~~~~~~~~
|
||||
|
||||
|
||||
.. FIXME : définir la position et les objectifs
|
||||
|
||||
FIXME
|
476
algo/poo/cours/programme.txt
Normal file
476
algo/poo/cours/programme.txt
Normal file
@ -0,0 +1,476 @@
|
||||
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)
|
101
algo/poo/cours/tp.txt
Normal file
101
algo/poo/cours/tp.txt
Normal file
@ -0,0 +1,101 @@
|
||||
Travaux Pratiques
|
||||
=================
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**travaux pratiques :**
|
||||
|
||||
Ecrire un algorithme qui renvoie le résultat d’une mini-calculatrice. Cette
|
||||
méthode aura
|
||||
comme paramètre deux nombres et une chaîne de caractère qui vaudra « + », « -
|
||||
», « * »,
|
||||
« / ».
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**travaux pratiques :**
|
||||
|
||||
|
||||
Ecrire un algorithme qui renvoie si deux mots (chaîne de caractères) passés en
|
||||
paramètre
|
||||
sont des anagrammes l’un de l’autre. (Lettres identiques mais dans un ordre
|
||||
différent)
|
||||
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**travaux pratiques :**
|
||||
|
||||
ascii art (ligne d'étoiles)
|
||||
|
||||
Concevoir un algorithme qui, pour un caractère imprimable et un nombre n
|
||||
donnés, imprime une barre
|
||||
horizontale de n de ces caractères.
|
||||
|
||||
``****************``
|
||||
|
||||
2. Modifier l’algorithme pour l’impression d’une barre double.
|
||||
|
||||
::
|
||||
|
||||
****************
|
||||
****************
|
||||
|
||||
3. Modifier l’algorithme pour l’impression d’une barre d’épaisseur quelconque
|
||||
donnée.
|
||||
4. (optionnel) Transformer les algorithmes ci-dessus en fonctions.
|
||||
5. Écrire un programme Java implémentant la dernière version de l’algorithme
|
||||
(épaisseur quelconque).
|
||||
|
||||
3.3
|
||||
Triangle de nombres
|
||||
Concevoir un algorithme qui imprime pour n donné::
|
||||
|
||||
1
|
||||
1 2
|
||||
1 2 3
|
||||
1 2 3 4
|
||||
1 2 3 4 5
|
||||
...........
|
||||
.............
|
||||
...............
|
||||
1 2 3 4 5 6 ... n
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**travaux pratiques :**
|
||||
|
||||
code de césar : faire un programme pour chiffrer et déchiffrer par décalage
|
||||
|
||||
exemples : Effectue une rotation de x caractères vers la droite::
|
||||
|
||||
>>> print(chiffre('bonjour', 3))
|
||||
erqmrxu
|
||||
>>> print(chiffre('Bonjour les amis!', 3))
|
||||
Erqmrxu ohv dplv!
|
||||
>>> print(chiffre('Erqmrxu ohv dplv!', 23))
|
||||
Bonjour les amis!
|
||||
|
||||
.. ifconfig:: exercice
|
||||
|
||||
**travaux pratiques :**
|
||||
|
||||
::
|
||||
|
||||
écrire “Entrer un numéro de mois”
|
||||
mois <- lire
|
||||
selon que mois est
|
||||
cas 1 : écrire “janvier (31 jours)”
|
||||
cas 2 : écrire “février (28 ou 29 jours)”
|
||||
cas 3 : écrire “mars (31 jours)”
|
||||
cas 4 : écrire “avril (30 jours)”
|
||||
cas 5 : écrire “mai (31 jours)”
|
||||
cas 6 : écrire “juin (30 jours)”
|
||||
cas 7 : écrire “juillet (31 jours)”
|
||||
cas 8 : écrire “août (31 jours)”
|
||||
cas 9 : écrire “septembre (30 jours)”
|
||||
cas 10 : écrire “octobre (31 jours)”
|
||||
cas 11 : écrire “novembre (30 jours)”
|
||||
cas 12 : écrire “décembre (31 jours)”
|
||||
défaut : écrire “numéro invalide”
|
||||
fselon
|
Reference in New Issue
Block a user