23982881
[mandjemb]
update ihm
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# RAPPORT FINALE
> ANDJEMBE Maksoudath, TANIEL Rémi
Le but du projet est de réaliser un tableur "basique" mais facilement
extensible, l'application sera divisée en 2 parties :
* le kernel
* la partie graphique
Le kernel s'occupera de toutes les opérations de notre grid, les cases
ne pourront contenir que des réels ou des formules(opération binaire ou
des fonctions acceptant des plages de cases).
|
08cc28cc
[mandjemb]
update ihm
|
14
|
## 1. ANALYSE ET CONCEPTION
|
23982881
[mandjemb]
update ihm
|
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
### SCHEMA UML
Voici le schéma UML de notre application, les classes et méthodes
abstraites sont en italique :
![UML](uml.png)
### PSEUDO-JAVA CREATION GRILLE,CASES
Voici un exemple de création d'une grid et de l'ajout / modification /
affichage de plusieurs types de case :
```java
class Application {
public static void main(String[] args) {
Grille g = new Grille();
g.createCase("b",1); //Ajout case vide
g.createCase("a",1,100.0); //Ajout case avec valeur
g.createCase("a",2,50.0); //Ajout case avec valeur
g.createCase("a",3,new Addition(g.getCase("a",2),g.getCase("a",1))); //Ajout case avec operation binaire
List<Case> plageCase1 = new ArrayList<Case>(); // Crée une liste de case
plageCase1.add(g.getCase("a",1));
plageCase1.add(g.getCase("a",2));
plageCase1.add(g.getCase("a",3));
g.createCase("a",4,new Somme(plageCase1)); //Ajout case avec fonctions
g.setValeur("b",1,100); //Met la valeur de b1 à 100
List<Case> plageCase2 = new ArrayList<Case>(); // Crée une liste de case
plageCase1.add(g.getCase("a",4));
plageCase1.add(g.getCase("a",2));
plageCase1.add(g.getCase("a",3));
g.setFormule("b",2,new Moyenne(plageCase2)); //Met la formule dans b2
g.getValeur("a",1); //Affichera 100.0
g.getValeur("a",4); //Affichera (100+50+150)=100
g.getFormuleAsString("b",2); //Affichera MOYENNE(a4,a2,a3)
g.getFormuleDeveloppe("b",2);
}
}
```
### CHOIX STRUCTURE DE DONNÉES
Nous devons choisir une structure de donnée pour stocker les cases dans
notre grid, nous savons déjà que nous allons utiliser ne collection
pour les stocker,voici celles que nous connaissons:
- des tableaux
- des listes
- des maps
- des sets
D'après le schéma UML ci-dessus, nous allons donc utiliser une `HashMap`
pour stocker les cases de notre grid :
* Pour rechercher une case et, effectuer des opérations dessus ce sera
plus facile, la clé de la Map sera une chaine de caractère (String) qui
représente la coordonnée de cette case (c'est-à-dire la concaténation
du nom de ligne et de l'indice de la colonne, exemple "A1", "B9", etc...)
Une case peut etre utilisée dans plusieurs autres cases, on ne sait
pas le nombre d'autres cases où elle sera utilisée, on stockera donc
cette donée dans une `ArrayList` de `Case`.
Certaines fonctions (`Moyenne`, `Somme`) utilise également une plage de case, pour stocker ces cases,
nous allons également une `ArrayList` de `Case`.
### METHODES ESSENTIELLES EN PSEUDO-JAVA
#### 1. Methode getValeur
```java
|
882d59f8
mandjemb
Rapport
|
95
|
class Grid {
|
23982881
[mandjemb]
update ihm
|
96
97
|
Map<String, Case> cases = new HashMap<>();
|
882d59f8
mandjemb
Rapport
|
98
99
|
double getValue(String column, int line){
return cases.getCell(column, line).getValue();
|
23982881
[mandjemb]
update ihm
|
100
101
102
103
|
}
}
|
882d59f8
mandjemb
Rapport
|
104
105
106
107
|
class Cell {
String column;
int line;
double value;
|
23982881
[mandjemb]
update ihm
|
108
|
|
882d59f8
mandjemb
Rapport
|
109
110
|
double getValue() {
return value;
|
23982881
[mandjemb]
update ihm
|
111
112
113
114
115
116
|
}
}
```
|
882d59f8
mandjemb
Rapport
|
117
|
#### 2. Methode getFormuleAsString (acceder au contenu)
|
23982881
[mandjemb]
update ihm
|
118
119
120
|
```java
|
882d59f8
mandjemb
Rapport
|
121
|
class Grid {
|
23982881
[mandjemb]
update ihm
|
122
123
|
Map<String, Case> cases = new HashMap<>();
|
882d59f8
mandjemb
Rapport
|
124
125
|
String getFormuleAsString(String column, int line) {
return this.getCell(column, line).toString();
|
23982881
[mandjemb]
update ihm
|
126
127
128
129
|
}
}
|
882d59f8
mandjemb
Rapport
|
130
131
132
133
134
|
class Cell {
String column;
int line;
double value;
Formula formula;
|
23982881
[mandjemb]
update ihm
|
135
136
|
String getFormuleAsString() {
|
882d59f8
mandjemb
Rapport
|
137
138
|
if (formula != null)
return formula.toString();
|
23982881
[mandjemb]
update ihm
|
139
140
141
142
143
144
145
|
else
return toString();
}
}
// Exemple pour Addition
class Addition {
|
882d59f8
mandjemb
Rapport
|
146
147
|
Cell leftCell;
Cell rightCell;
|
23982881
[mandjemb]
update ihm
|
148
149
|
String toString() {
|
882d59f8
mandjemb
Rapport
|
150
|
return leftCell.toString() + "+" + rightCell.toString();
|
23982881
[mandjemb]
update ihm
|
151
152
153
154
155
156
|
}
}
```
|
882d59f8
mandjemb
Rapport
|
157
|
#### 3. Methode getDevelopedFormula
|
23982881
[mandjemb]
update ihm
|
158
159
|
```java
|
882d59f8
mandjemb
Rapport
|
160
|
class Grid{
|
23982881
[mandjemb]
update ihm
|
161
162
|
Map<String, Case> cases = new HashMap<>();
|
882d59f8
mandjemb
Rapport
|
163
164
|
String getDevelopedFormula(String column, int line) {
return this.getCell(column,line).getFormuleDeveloppe();
|
23982881
[mandjemb]
update ihm
|
165
166
167
168
|
}
}
class Case{
|
882d59f8
mandjemb
Rapport
|
169
170
171
172
173
|
String column;
int line;
double value;
Formula formula;
List<Cell> usedIn = new ArrayList<>();
|
23982881
[mandjemb]
update ihm
|
174
|
|
882d59f8
mandjemb
Rapport
|
175
176
177
|
String getDevelopedFormula() {
if (formula != null)
return formula.getFormuleDeveoppe();
|
23982881
[mandjemb]
update ihm
|
178
179
180
181
182
183
|
else
return toString();
}
}
Average
|
882d59f8
mandjemb
Rapport
|
184
185
|
class Average {
List<Cell> listCases = new ArrayList<Cell>();
|
23982881
[mandjemb]
update ihm
|
186
|
|
882d59f8
mandjemb
Rapport
|
187
|
String getDevelopedFormula() {
|
23982881
[mandjemb]
update ihm
|
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
return Average + listCases.stream().map(c -> c.getFormuleDeveloppe()).collect((Collectors).joining(", ")) + ")";
}
}
```
#### 4. Methode eval()
- Dans Addition :
```java
class Addition {
Case gauche;
Case droite;
double eval() {
return gauche.getValeur() + droite.getValeur();
}
}
```
- Dans Multiplication :
```java
class Multiplication {
|
882d59f8
mandjemb
Rapport
|
215
216
|
Cell gauche;
Cell droite;
|
23982881
[mandjemb]
update ihm
|
217
218
219
220
221
222
223
224
225
226
227
228
|
double eval() {
return gauche.getValeur() * droite.getValeur();
}
}
```
- Dans Soustraction :
```java
class Soustraction {
|
882d59f8
mandjemb
Rapport
|
229
230
|
Cell gauche;
Cell droite;
|
23982881
[mandjemb]
update ihm
|
231
232
233
234
235
236
237
238
239
240
241
242
|
double eval() {
return gauche.getValeur() - droite.getValeur();
}
}
```
- Dans Division :
```java
class Division {
|
882d59f8
mandjemb
Rapport
|
243
244
|
Cell gauche;
Cell droite;
|
23982881
[mandjemb]
update ihm
|
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
double eval() {
if (droite.getValeur() != 0)
return gauche.getValeur() / droite.getValeur();
else
lève une exception
}
}
```
- Dans Moyenne :
```java
|
882d59f8
mandjemb
Rapport
|
259
260
|
class Average {
List<Cell> listCases = new ArrayList<Cell>();
|
23982881
[mandjemb]
update ihm
|
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
|
double eval() {
double val=0;
if (listCases.size() != 0)
for(int i=0; i<listCases.size(); i++)
val += listCases.get(i).getValeur();
return val / listCases.size();
else
lève une exception
}
}
```
- Dans Somme :
```java
|
882d59f8
mandjemb
Rapport
|
278
279
|
class Sum {
List<Cell> listCases = new ArrayList<Cell>();
|
23982881
[mandjemb]
update ihm
|
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
|
double eval() {
double val=0;
if (listCases.size() != 0)
for(int i=0; i<listCases.size(); i++)
val += listCases.get(i).getValeur();
return val;
else
lève une exception
}
}
```
#### 5. Methode setValeur
```java
|
882d59f8
mandjemb
Rapport
|
297
|
class Grid {
|
23982881
[mandjemb]
update ihm
|
298
299
300
301
302
303
304
305
|
Map<String, Case> cases = new HashMap<>();
void setValeur(String colonne, int ligne, double value) {
String code = colonne + ligne;
return cases.get(code).setValeur(value);
}
}
|
882d59f8
mandjemb
Rapport
|
306
|
class Cell {
|
23982881
[mandjemb]
update ihm
|
307
308
309
310
|
String colonne;
int ligne;
double valeur;
Formule formule;
|
882d59f8
mandjemb
Rapport
|
311
|
List<Cell> utiliseDans = new ArrayList<Cell>();
|
23982881
[mandjemb]
update ihm
|
312
313
314
315
316
317
318
319
320
321
322
323
324
|
void setValeur(double value) {
valeur = value;
for(int i=0; i<utiliseDans.size(); i++)
utiliseDans.get(i).updateValeur();
}
}
```
#### 5. Methode setFormule
```java
|
882d59f8
mandjemb
Rapport
|
325
326
|
class Grid {
Map<String, Cell> cases = new HashMap<>();
|
23982881
[mandjemb]
update ihm
|
327
328
329
330
331
332
333
334
|
void setFormule(String colonne, int ligne, Formule formule) {
String code = colonne + ligne;
return cases.get(code).setFormule(formula);
}
}
|
882d59f8
mandjemb
Rapport
|
335
|
class Cell {
|
23982881
[mandjemb]
update ihm
|
336
337
338
339
|
String colonne;
int ligne;
double valeur;
Formule formule;
|
882d59f8
mandjemb
Rapport
|
340
|
List<Cell> utiliseDans = new ArrayList<Cell>();
|
23982881
[mandjemb]
update ihm
|
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
|
void updateValeur() {
valeur = formule.eval();
}
void setFormule(Formule formula) {
if (!formula.creerCycle(this))
formule = formula;
updateValeur();
for(int i=0; i<utiliseDans.size(); i++)
utiliseDans.get(i).updateValeur();
else
lève une exception
}
}
BinaryOperation
class OperationBinaire {
|
882d59f8
mandjemb
Rapport
|
359
360
|
Cell gauche;
Cell droite;
|
23982881
[mandjemb]
update ihm
|
361
362
|
boolean creerCycle(Case case) {
|
882d59f8
mandjemb
Rapport
|
363
364
365
366
367
368
369
370
|
Si la case gauche ne contient pas de formule et la case de droite contient une
rechercher si la case est dans la formule de la case de droite
Si la case gauche contient une formule et la case de droite n'en contient pas
rechercher si la case est dans la formule de la case de gauche
Si la case gauche et la droite contiennent des formules
rechercher si la case est dans les deux formule
|
23982881
[mandjemb]
update ihm
|
371
|
|
882d59f8
mandjemb
Rapport
|
372
373
374
375
376
377
378
379
380
381
382
383
384
|
Si les deux cases n'ont pas de formules
rechercher si la case est égale à case gauche ou droite
}
}
Function
class Fonction {
List<Cell> listCells;
boolean creerCycle(Case case) {
Si la case n'est pas dans listCells
Pour toute les cases dans listCells qui contiennent des formules, regarder si la case est dans la formule
|
23982881
[mandjemb]
update ihm
|
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
|
}
}
```
### LISTE DE TESTS
Afin de s'assurer de la maintenabilité de notre code et de la qualité de
celui-ci, nous allons réaliser plusieurs tests sur les différentes méthodes
que nous allons programmé dans notre application, voici quelques
exemples :
- Création d'une case avec une valeur fixe
- Création d'une case avec une formule d' `Opération binaire` et une
fonction comme `Moyenne`
- Modification d'une case avec une valeur sans qu'elle soit utilisée dans
une autre case
- Modification d'une case avec une valeur utilisée dans une autre case
- Vérification qu'une erreur se lève lors de la création des 2 types
de cycles (direct et indirect)
- Renvoie de la formule dévéloppée d'une case avec une formule assez compliqué
|
08cc28cc
[mandjemb]
update ihm
|
406
407
408
|
## 2. STRUCTURE DU PROJET
|
3d82806c
[mandjemb]
rapp
|
409
|
|
e4ef4371
[mandjemb]
mm
|
410
411
|
### PACKAGES,CLASSES,FICHIERS DE DONNÉES
|
08cc28cc
[mandjemb]
update ihm
|
412
413
414
|
L'implémentation du projet peut se résumer comme suit :
![PACKAGE](package.png)
|
e4ef4371
[mandjemb]
mm
|
415
416
417
418
419
420
421
|
Le schéma ci-dessus nous montre que, l'implémentation est composé de 5 package (representant 5 repertoires) contenant des classes ( chaque classe est un fichier d'extension java).
### MODES D'UTILISATION
|
882d59f8
mandjemb
Rapport
|
422
|
** Commande de compilation**:
|
e4ef4371
[mandjemb]
mm
|
423
424
425
|
find src -not \( -path src/kernel/test -prune \) -name \*.java |xargs -i javac -d bin {} -cp src/
|
882d59f8
mandjemb
Rapport
|
426
427
428
429
|
** Commande d'exécution**:
java bin/app/Main
|
3d82806c
[mandjemb]
rapp
|
430
431
432
|
## 3. BILAN
Au cours de ce projet les actions suivantes ont été faites :
|
e4ef4371
[mandjemb]
mm
|
433
|
|
882d59f8
mandjemb
Rapport
|
434
435
436
437
438
439
440
441
442
443
444
445
446
447
|
### Le noyeau
- La gestion des cycles aussi bien direct qu'indirects.
- La modification d'une case par des valeurs ou des formules et dans ce dernier cas la vérification qu'aucun cycle n'est créée.
- La gestion de la langue (en francais et en anglais).
- De supprimer une case que si elle existe et, n'est pas utilisée par d'autres cases.
- De sérialiser l'état d'une grille après avoir effectué des actions.
### L'interface graphique
L'interface graphique implementée permet d'effectuer les actions suivantes :
- Créer une case à partir de d'une valeure.
- Créer une case en saisissant une formule (aussi bien français qu'en anglais).
|
13e51102
mandjemb
img
|
448
449
450
451
452
453
|
Par exemple, on crée la case A10=SOMME(A1,A2,B2)
![CASE](rapport_image/case_f.PNG)
![CASE](rapport_image/case_fv.PNG)
|
1b85b400
mandjemb
update rf
|
454
|
- Emettre une erreur lorsque l'on saisit du texte au lieu d'un double ou une formule incorrecte.
|
13e51102
mandjemb
img
|
455
456
|
![CASE](rapport_image/erreur_s.PNG)
|
1b85b400
mandjemb
update rf
|
457
458
|
- Emettre une erreur indiquant qu'un cycle est généré.
- Emettre une erreur indiquant qu'on ne peut pas supprimer une case utilisé par d'autres cases.
|
13e51102
mandjemb
img
|
459
460
|
![CASE](rapport_image/erreur_sup.PNG)
|
882d59f8
mandjemb
Rapport
|
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
|
### Les tests
Plusieurs tests ont été réalisés au cours de ce projet notamment celles permettant de :
- Créer une ou plusieurs cases
- Mettre à jour une case avec une valeur ou formule
- Créer une exception lorsqu'un cycle est créee
- Créer une exception lorsqu'on utilise une case pas encore créée
- Effectuer le re-calcul des cases qui dependent d'une case quand elle est modifiée
- Supprimer une case que si elle n'est pas utilisée par d'autres cases
## Conclusion
|
2cc93bf1
mandjemb
update rf
|
476
|
En résumé, ce projet de programmation par objet (PPO) avait pour but de développer les actions que l'on peut faire avec un classeur Excel usuel.Il était divisé en deux parties :
|
882d59f8
mandjemb
Rapport
|
477
|
- La première, créée un noyeau avec differentes méthodes permettant d'effectuer et vérifier des actions comme la création, modification d'une case avec des valeurs, opérations usuelles ou formules.
|
fe6de1ca
mandjemb
update rf
|
478
|
- La deuxième, de créer un interface.
|
882d59f8
mandjemb
Rapport
|
479
480
|
Ces deux parties ont été réalisées ainsi que des tests permettant de fonctionner le fonctionnement.
ce projet nous a donc été bénéfique car, il nous a permis de pouvoir mettre en pratique nos connaisances tout en developpant des nouvelles.
|
fe6de1ca
mandjemb
update rf
|
481
|
Aussi, concernant les améliorations possibles , l'on pourrait envisager de pouvoir ajouter dans l'interface une option permettant de choisir la langue étant donné qu'actuellement l'on fait un choix d'affichage dans une langue et l'utilisateur ne peut la modifier mais, peut rentrer le nom de d'une fonction dans les deux langues, sera fonctionnera.
|