Licence 1 MASS - Introduction à Java et à l'algorithmique Sébastien Verel
verel@i3s.unice.fr www.i3s.unice.fr/∼verel
Équipe ScoBi - Université de Nice Sophia-Antipolis
13 février 2012
Travail de la semaine passée
Installer processing (done.)
Travailler à partir des objectifs du cours
Travailler les exemples du cours (réussir à extraire l'archive !) Travailler les exercices des TP 01, 02 et 03
Créer des variations d'exemples et d'exercices (lesquels ?) Explorer les exemples de Processing
Objectifs de la séance 4
1 Connaître le principe de séparation de code
2 Ecrire correctement une méthode java
3 Comprendre et calculer le résultat d'un algorithme donné
4 Modier un algorithme donné
5 Utiliser une partie d'algorithme donné
6 Corriger un algorithme donné Question principale du jour :
Comment écrire réutiliser les algorithmes pour moins se fatiguer ?
Sébastien Verel Séparation de codes et méthodes
Choses encore mystérieuses
Vous avez écrit depuis quelques temps ce genre de programme : float moyenne(int n) {
float a, m int i;
m = 0;
for(i = 0; i < n; i++) {
a = lire("taper un nombre ");
m = m + a;
}
m = m / n;
return m;
}
D'ailleurs méthode "lire"
import javax.swing.JOptionPane;
/*****************************************
* Lit un nombre entier au clavier
** entree :
* - message : message d'invite
** sortie :
* - nombre de type int
*****************************************/
int lire(String message) {
String str = JOptionPane.showInputDialog(null, message);
return Integer.parseInt(str) ; }
Sébastien Verel Séparation de codes et méthodes
Choses encore mystérieuses
void deviner(int n) { int rep;
rep = n - 1;
while (rep != n) {
rep = lire("Proposer un nombre entier");
}
println("Gagné !");
}
Choses encore mystérieuses
float u100() { float u = 1;
for(int i = 0; i < 101; i++) u = 0.5 * u + 2;
return u;
}
void setup() { println(u100());
}
Sébastien Verel Séparation de codes et méthodes
Choses encore mystérieuses
void setup() { size(500, 200);
smooth();
strokeWeight(20.0);
stroke(0, 100);
x = 0;
}
void draw() { background(226);
point(x, height / 2);
x = x + 1;
}
Choses mystèrieuses
"coeur" du programme : facile ( !)
"décoration autour du coeur" : surement ou (pour l'instant) float moyenne(int n) {
float a, m int i;
...return m;
}
ou encore
void deviner(int n) { int rep;
...}
Sébastien Verel Séparation de codes et méthodes
De même plus généralement
But
Donner un sens plus précis à la "décoration"
Algorithme moyenne(n : entier) : réel début
variable m, a : réel variable i : entier ...retourner m n
Les éléments du "décors"
1. Fonctions
Comment les dénir ? Comment les utiliser ? 2. Valeur nale
Comment la dénir ? quels types utiliser ? 3. Paramètres
A quoi servent-ils ? comment les utiliser ? 4. Variables locales/globales
Comment les utiliser ?
Principe deSéparation de code
Sébastien Verel Séparation de codes et méthodes
Plan
1 Fonctions et valeurs nales Fonctions
Valeurs nales
2 Paramètrer les algorithmes Paramètres
Variables locales
3 Séparation de code
Une situation
void setup() {
println("La répétition est la base de l'arpentissage.");
println("L'entrainement assure la réussite.");
println();
println("Quoi qu'on en dise");
println();
println("La répétition est la base de l'apprentissage.");
println("L'entrainement assure la ruéssite.");
println();
println("J'insiste encore une fois");
println();
println("La répétition est la base de l'apprentissage.");
println("L'entrainement assure réussite.");
println();
println("Je vous remercie de votre attention.");
}
Sébastien Verel Séparation de codes et méthodes
Analyse de la situation
3 fois le même morceaux de code
println("La répétition est la base de l'arpentissage.");
println("L'entrainement assure la réussite.");
Des erreurs dans les 3 parties
Dicile de modier la partie de code commune
Impossible (ou très incertain) de réutiliser le morceau de code
Solution
Centraliser en un seul endroit le morceaux de code en commun
Une meilleure situation
void texteImportant() {
println("La répétition est la base de l'arpentissage.");
println("L'entrainement assure la réussite.");
}
void setup() { texteImportant();
println();
println("Quoi qu'on en dise");
println();
texteImportant();
println();
println("J'insiste encore une fois");
println();
texteImportant();
println();
println("Je vous remercie de votre attention.");
}
Sébastien Verel Séparation de codes et méthodes
Une meilleure situation corrigée
void texteImportant() {
println("La répétition est la base de l'apprentissage.");
println("L'entrainement assure la réussite.");
}
void setup() { texteImportant();
println();
println("Quoi qu'on en dise");
println();
texteImportant();
println();
println("J'insiste encore une fois");
println();
texteImportant();
println();
println("Je vous remercie de votre attention.");
}
Les fonctions sans valeur nale
En processing,
void nomFonction() {
... block d'instructions ...
}
De manière générale en algorithmique, Algorithme nomFonction() : rien début
... morceau d'algorithme ...
n
Remarques
nomFonction : peut être remplacer par n'importe quel nom, Dans un même programme, il ne peut y avoir 2 fonctions portant le même nom (sauf si elles n'ont pas les mêmes paramètres),
Pas de valeur nale à la fonction : type 'void' qui signie rien, vide.
Sébastien Verel Séparation de codes et méthodes
Exemple de valeur nale
int nombreHabitants() { return 63136180;
}
void setup() {
int nbFemmes = nombreHabitants() / 2;
float densite = nombreHabitants() / 670 922.0;
println("Il y a à peu près " + nbFemmes + " en France.");
print("La densité de population en France ");
println("est de l'ordre de " + densite + " au km2.");
}
Mêmes avantages qu'auparavant
Valeur nale : déclarée par le type avant le nom de la fonction Valeur nale : dénie par l'instruction 'return'
Les fonctions avec valeur nale
En processing,
type nomFonction() {
... block d'instructions ...
return valeur ; }
De manière générale en algorithmique, Algorithme nomFonction() : type début
... morceau d'algorithme ...
retourner valeur n
Remarques
'type' peut être remplacé par n'importe quel type
'valeur' est une valeur de type 'type' (variable, constante, ou expression)
Après l'exécution de l'instruction 'return', l'exécution de la fonction est stoppée
Sébastien Verel Séparation de codes et méthodes
En Java : une seule valeur nale
Attention : 1 seule valeur nale return x, y ; // impossible !
Il faudrait utiliser des types composés : voir plus tard...
Problématique
calculer la moyenne de 10 notes calculer la moyenne de 20 notes calculer la moyenne de 100 notes calculer la moyenne de 3 notes calculer la moyenne de 0 notes
Sébastien Verel Séparation de codes et méthodes
Problématique
Algorithme moyenne() : réel m←0
pour i de 1 à 10 faire
a← lire("entrere une note") m←m+a
n pour m←m/10 retourner m n
Mauvaise idée
1 situation particulière =1 algorithme Généraliser
Introduire un nombre n à xer au moment de l'exécution.
Problématique : proposition
Algorithme moyenne() : réel n←10
variable m : entier m←0
pour i de 1 à n faire
a← lire("entrer une note") m←m+a
n pour m←m/n retourner m n
Mieux puisqu'un seul changement à faire
Mais toujours : 1 situation particulière = 1 algorithme
Sébastien Verel Séparation de codes et méthodes
Problématique
Généraliser
Introduire un nombre n à xer au moment de l'exécution de l'algorithme.
Algorithme moyenne() : réel variable m : entier
m←0
pour i de 1 à n faire
a← lire("entrer une note") m←m+a
n pour m←m/n retourner m
Fixer la valeur de n à l'exécution
2 solutions possibles :
Demander la valeur de n dansl'algorithme "moyenne" : n ← lire("Taper le nombre de nombres")
mauvaise solution
algorithme "moyenne" eectue deux choses :
demander le nombre de notes ET calculer la moyenne.
Mettre n en paramètre de l'algorithme "moyenne" : Algorithme moyenne(n : entier) : réel
Sébastien Verel Séparation de codes et méthodes
Vers la solution
Algorithme moyenne(n : entier) : réel m←0
pour i de 1 à n faire
a← lire("entrer une note") m←m+a
n pour m←m/n retourner m n
Autre problème
Ecrire un algo qui détermine le plus gros gâteau (en kg) parmi 3 (...)
si a < b alors si b < c alors
retourner c sinon
retourner b sinonn si
si a < c alors retourner c sinon
retourner a n sin si
n
Sébastien Verel Séparation de codes et méthodes
Autre problème
2 possiblités d'algorithme
Algorithme plusGros( ) : réel début
variable a, b, c : réel
a ←lire("poids A") b←lire("poids B") c ←lire("poids C") si a < b alors
si b < c alors retourner c sinon
retourner b sinonn si
si a < c alors retourner c sinon
retourner a n sin si
Autre problème
2 possiblités d'algorithme
Algorithme plusGros(a : réel, b : réel, c : réel) : réel début
si a < b alors si b < c alors
retourner c sinon
retourner b sinonn si
si a < c alors retourner c sinon
retourner a n sin si
n
Sébastien Verel Séparation de codes et méthodes
Algorithme plusGros à préfèrer
Second algorithme : meilleur puisqu'il correspond à notre attente : Seulement déterminer le plus gros gâteau (en kg) à partir de données.
et non réaliser en plus la tache de saisie de ces poids
Quand utiliser un (des) paramètre(s) ?
Questions à se poser ?
L'algorithme doit-il résoudre un ensemble de problèmes dépendant de paramètres ?
Peut-on généraliser l'algorithme à l'aide de variables ? La résolution du problème nécessite-t-elle des données externes ?
Si oui à moins une des questions :
−→utiliser un algorithme paramètré à l'aide de variables
Sébastien Verel Séparation de codes et méthodes
Comment écrire un algorithme paramètré ?
Algorithme nomAlgo(nom1 : type1,nom2 : type2,nom3 : type3,... ) : type début
n...
nom1,nom2,nom3 sont des noms de variables type1, type2, type3 sont les types des variables correspondantes (booléen, entier, réel, mot,...)
Exemple
Calculer la longueur de l'hypothénuse d'un triangle rectangle Algorithme hypothenuse(a : réel, b : réel) : réel
début n...
Sébastien Verel Séparation de codes et méthodes
Traduire en java
Calculer la longueur de l'hypothénuse d'un triangle rectangle
Algorithme hypothenuse(a : réel, b : réel) : réel début
retourner sqrt(a2+b2) n
Paramètres eectifs et formels
Algorithme hypothenuse(a : réel, b : réel) : réel début
n...
Les valeurs des paramètres sont xés lors de l'exécution : c ← hypothenuse(3,4)
a et b sont des Paramètres formels : ils représentent des nombres quelconques.
3 et 4 sont des Paramètres eectifs : valeurs des paramètres réellement utilisés.
Sébastien Verel Séparation de codes et méthodes
En Java...
type nomAlgo(type1 nom1, type2 nom2, type3 nom3,...) { ...
}
nom1,nom2,nom3 sont des noms de variables qui sont de type type1 ,type2, type3
Autant de variables que nécessaire Sans paramètre :
type nomAlgo() { ...}
Commentaires
Nécessaire pour :
clarier l'utilisation de vos fonctions sans connaitre leur fonctionnement
indiquer la signication des variables paramètres éviter les erreurs
/*****************************************
* Lit un nombre entier au clavier
** entree :
* - message : message d'invite
** sortie :
* - nombre de type int correspondant à la valeur saisie
*****************************************/
int lire(String message) {
String str = JOptionPane.showInputDialog(null, message);
return Integer.parseInt(str) ; }
Sébastien Verel Séparation de codes et méthodes
En Processing
Processing simplication orientée graphique de java Fonctions setup et draw :
fonctions exécutées automatiquement par Processing Fonctions "événementielles" (keypressed, onMouse, etc.) : exécutées lors de l'apparition de l'événement
Lorsqu'on dénit ses propres fonctions,
la dénition de la méthode setup est nécessaire
Utilisation de variables dans un algorithme
Enregistrer des résultats intermédiares au cours d'un algorithme : Algorithme moyenne(n : entier) : réel
début
variable m, a : réel variable i : entier ...
retourner m n
m, a et i sont desvariables localesà l'algorithme.
Remarque :
Toute variable utilisée dans un algorithme doit être déclarée.
Sébastien Verel Séparation de codes et méthodes
Portée des variables locales
les variables locales (m, a et i) ne sont accessibles que dans cet algorithme, c'est-à-dire entre début et n.
Algorithme moyenne(n : entier) : réel début
variable m, a : réel variable i : entier ...
retourner m n
moyenne(5) m← m+3
Cette dernière ligne n'a pas de sens, m n'existe pas à l'extérieur de l'algorithme.
Porté des variables locales
Les valeurs des variables locales n'altèrent pas les valeurs des variables portant le même nom à l'extérieur de l'algorithme.
variable m : réel m← 2
moyenne(5) m← m+3 écrire(m)
Sébastien Verel Séparation de codes et méthodes
Variables locales et paramètres
Les variables déclarées en paramètre des algorithmes sont des variables locales à l'algorithme avec les mêmes propriétés.
Remarques dans ce cours :
valeurs initiales des variables en paramètre : celles données eectivement en exécutant l'algorithme (passage par valeur) impossible de modier la valeur d'une variable par l'exécution d'un algorithme (pas de passage par adresse)
En Java...
void deviner(int n) { int rep;
rep = n - 1;
while (rep != n) {
rep = lire("Proposer un nombre entier");
}
println("Gagné !");
}
variables déclarées et accessibles seulement entre{et } de la méthode
Sébastien Verel Séparation de codes et méthodes
Variable globale Java (Processing)
Une méthode de processingpeut modierla valeur d'une variable déclarée à l'extérieure de la méthode
int n = 5;
void plus1() { n = n + 1;
}
void setup() { plus1();
print(n);
}
n a pour valeur 6
On parle alors devariable globalepar opposition à variable locale.
Variable globale Java
Eviter les variables globales pour éviter les modications malheureuses et inattendues
Il vaut mieux écrire : int plus1(int n)
return n + 1 ; }
void setup() { int n = 5;
n = plus1(n);
print(n);
}
Sébastien Verel Séparation de codes et méthodes
En Java : commentaires !
/*****************************************
* Lit un nombre entier au clavier
** entree :
* - message : message d'invite
** sortie :
* - nombre correspondant à la valeur saisie
*****************************************/
int lire(String message) {
String str = JOptionPane.showInputDialog(null, message);
return Integer.parseInt(str) ; }
Quoi t'est-ce ?
Maintenant nous avons des algorithmes avec : des données en entrée,
une valeur nale de sortie un traitement local bien déni
Méthode analytique (diviser pour régner)
Découper le "gros" problème, et donc le code, en fonctions indépendantes simples
Résolution de l'ensemble du problème par l'assemblage des fonctions : création de "gros" algorithmes
Sébastien Verel Séparation de codes et méthodes
Avantages à séparer le code en plusieurs sous-algorithmes ?
Suit la méthode de Descartes de la résolution de problème Limitations des erreurs :
plus un algorithme est court moins il y a d'erreurs Algorithmes plus faciles à écrire :
Conception descendante (du générale au particulier) Algorithmes réutilisables :
plus facile à adapter, à reprendre pour d'autre algorithme (bibliothèque)
Factorisation de l'algorithme :
ne pas écrire beaucoups de fois les mêmes algorithmes
Démarche analytique (rappels)
Préceptes de la méthode
l'évidence :
" Le premier était de ne recevoir jamais aucune chose pour vraie que je ne la connusse évidemment être telle ; c'est-à-dire, d'éviter soigneusement la précipitation et la prévention, et de ne comprendre rien de plus en mes jugements que ce qui se présenterait si clairement et si distinctement à mon esprit, que je n'eusse aucune occasion de le mettre en doute. "
l'analyse :
"Le second, de diviser chacune des dicultés que
j'examinerais, en autant de parcelles qu'il se pourrait, et qu'il serait requis pour les mieux résoudre. "
Sébastien Verel Séparation de codes et méthodes
Démarche analytique (rappels)
Préceptes de la méthode
la synthèse et le raisonnement :
"Le troisième, de conduire par ordre mes pensées, en
commençant par les objets les plus simples et les plus aisés à connaître, pour monter peu à peu comme par degrés jusques à la connaissance des plus composés, et supposant même de l'ordre entre ceux qui ne se précèdent point naturellement les uns les autres."
le dénombrement :
"Et le dernier, de faire partout des dénombrements si entiers et des revues si générales, que je fusse assuré de ne rien omettre.
"
Sous-algorithme
Un sous-algorithme est un algorithme.
Algorithme monAlgo(paramètres) : type début
...
retourner valeur n
Sébastien Verel Séparation de codes et méthodes
Exemple
Calcul de la somme de deux nombres entiers taper au clavier Algorithme somme( ) : entier
début
variable a, b : entier a← saisir10() b ← saisir10() retourner a+b n
Exemple
Saisir d'un entier taper au clavier compris entre 0 et 10 Algorithme saisir10( ) : entier
début
variable a : entier
a← lire("Taper un nombre") tant que a<0 ? ? 10<a faire
a← lire("nombre incorrect, veuillez retaper un nombre entre 0 et 10")
n tant que retourner a n
Sébastien Verel Séparation de codes et méthodes
Exemple
Saisir d'un entier taper au clavier compris entre 0 et 10 Algorithme saisir10( ) : entier
début
variable a : entier
a← lire("Taper un nombre") tant que a<0 ou 10<a faire
a← lire("nombre incorrect, veuillez retaper un nombre entre 0 et 10")
n tant que retourner a n
Exemple : mieux
Saisir d'un entier taper au clavier compris entre deux bornes Algorithme saisir(inf : entier, sup : entier) : entier
début
variable a : entier
a← lire("taper un nombre") tant que a<inf OU sup<a faire
écrire("nombre incorrect, veuillez retaper un nombre entre ", inf, " et ", sup)
a← lire("taper un nombre") n tant que
retourner a n
Sébastien Verel Séparation de codes et méthodes
Exemple : traduire en JAVA
int saisir(int inf, int sup) { int a ;
a = lire("taper un nombre");
while ( a < inf || a < sup) {
println("nombre incorrect, veuillez retaper un nombre entre " + inf + " et " + sup);
a = lire("taper un nombre");
}
return a;
}
Exemple : traduire en JAVA
/*****************************************
* Lit un nombre entier au clavier comprise
* dans un interval
** entree :
* - inf : borne inférieure de l'interval
* - sup : borne supérieure de l'interval
** sortie :
* - nombre correspondant à la valeur saisie
* appartenant à [inf, sup]
*****************************************/
int saisir(int inf, int sup) { int a ;
a = lire("taper un nombre");
while ( a < inf && a < sup) {
println("nombre incorrect, veuillez retaper un nombre entre " + inf + " et " + sup);
a = lire("taper un nombre");
}
return a;
}
Sébastien Verel Séparation de codes et méthodes
Exemple de réutilisation
Petit jeu où l'on doit deviner un nombre mystère entre 0 et 100
Algorithme deviner(n : entier) : rien début
variable a : entier a←0
tant que a6=n faire
a← lire("Taper un nombre") si a<n alors
écrire(trop petit) sinon
écrire(trop grand) n si
n tant que écrire("gagné") n
Exemple de réutilisation
Petit jeu où l'on doit deviner un nombre mystère
Algorithme deviner(n : entier) : rien début
variable a : entier a←0
tant que a6=n faire a← saisir(0, 100) si a<n alors
écrire(trop petit) sinon
écrire(trop grand) n si
n tant que écrire("gagné") n
Sébastien Verel Séparation de codes et méthodes
Correction de Point avec séparation de code
// abscisse du point int x ;
// deplacement du point int delta ;
// initilisation de l'abscisse et de l'écran void setup() {
// mise en forme de l'cran size(500, 200);
background(255);
smooth();
strokeWeight(20.0);
stroke(0, 100);
// initialisation de l'abscisse x = 0;
// initialisation du deplacement delta = 2;
Correction de Point avec séparation de code
// dessin et mouvement du point void draw() {
// efface l'écran background(255);
// dessin du point point(x, height / 2);
// modification de l'abscisse x = x + delta;
// sortie de l'ecran verificationBorne();
}
Sébastien Verel Séparation de codes et méthodes
Correction de Point avec séparation de code
// Verifie que la balle est dans les bornes de l'espace void verificationBorne() {
if (x > width - 1) { x = width - 1;
delta = - delta ; }
if (x < 0) { x = 0;
delta = - delta;
} }
Objectifs de la séance 4
1 Connaître le principe de séparation de code
2 Ecrire correctement une méthode java
3 Comprendre et calculer le résultat d'un algorithme donné
4 Modier un algorithme donné
5 Utiliser une partie d'algorithme donné
6 Corriger un algorithme donné Question principale du jour :
Comment écrire decouper les algorithmes pour mieux régner ?
Sébastien Verel Séparation de codes et méthodes