573 lines
14 KiB
Plaintext
573 lines
14 KiB
Plaintext
Définition d'un programme
|
||
==========================
|
||
|
||
Ce pourrait être dit abstraitement, mais ce serait dommage.
|
||
Construisons un programme en python
|
||
|
||
La CLI (command line interface)
|
||
---------------------------------
|
||
|
||
.. code-block:: ocaml
|
||
|
||
let echo () =
|
||
let len = Array.length Sys.argv in
|
||
if len > 1 then
|
||
begin
|
||
for i=0 to len-1 do
|
||
print_string Sys.argv.(i) ;
|
||
print_char ' ';
|
||
done
|
||
end
|
||
let _ = echo()
|
||
|
||
|
||
::
|
||
|
||
ocaml cli.ml arg1 arg2 arg3
|
||
cli.ml arg1 arg2 arg3
|
||
|
||
en python:
|
||
|
||
.. code-block:: python
|
||
|
||
import sys
|
||
print sys.argv
|
||
|
||
::
|
||
|
||
python toto.py arg1 arg2
|
||
['toto.py', 'arg1', 'arg2']
|
||
|
||
c'est plus simple...
|
||
|
||
|
||
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)
|
||
|
||
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 déclarations
|
||
-----------------
|
||
|
||
déclarations. affectations par valeur ? par référence ? Bien faire la
|
||
différence entre les deux.
|
||
|
||
**déclaration par référence**
|
||
|
||
.. code-block:: ocaml
|
||
|
||
let x = ref 1;;
|
||
print_int !x;;
|
||
x := !x + 1;;
|
||
print_int !x;;
|
||
|
||
|
||
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'
|
||
|
||
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
|
||
|
||
La séquence s'écrit avec le traditionnel point-virgule, comme
|
||
dans::
|
||
|
||
x := 1; 2 + !x
|
||
|
||
expression séquentielle::
|
||
|
||
3 * (x := 1; 2 + !x)
|
||
|
||
|
||
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}
|
||
|
||
|
||
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 instructions
|
||
----------------
|
||
|
||
Dans les langages impératifs, expressions et instructions sont deux catégories syntaxiques bien distinctes : une
|
||
conditionnelle, if-then-else ou une boucle for n'est pas acceptée en position d'expression, et
|
||
inversement certaines expressions ne sont pas autorisées en position d'instruction.
|
||
|
||
En OCaml , il n'y a pas de telle distinction expression/instruction : il n'y a
|
||
que des expressions. Ainsi on peut écrire::
|
||
|
||
1 + (if x = 0 then 2 else 3)
|
||
|
||
|
||
exemple d'expression de base::
|
||
|
||
# let x = 5;;
|
||
val x : int = 5
|
||
# 1 + (if (x == 0) then 3 else 6);;
|
||
- : int = 7
|
||
|
||
exemple de présence d'instruction dans notre expression de base::
|
||
|
||
# 1 + (if (x == 0) then (let b=5 in b) else (let a=2 in a));;
|
||
- : int = 3
|
||
|
||
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())
|
||
|
||
|
||
|
||
Pour résumer en ocaml, nous avons vu
|
||
|
||
- qu'un programme est une suite d'expressions et de déclarations ;
|
||
- que les variables introduites par le mot clé let ne sont pas modifiables ;
|
||
- qu'il n'y a pas de distinction entre expressions et instructions.
|
||
|
||
|