Blame view

rapport_finale.md 8.5 KB
23982881   [mandjemb]   update ihm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  # 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).
  
  ## 1. Analyse et conception
  
  
  ### 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
  
  class Grille {
    Map<String, Case> cases  = new HashMap<>();
    
    double getValeur(String colonne, int ligne){
      String code=colonne+ligne;
      return cases.get(code).getValeur();
    }
  }
  
  
  class Case {
    String colonne;
    int ligne;
    double valeur;
    
    double getValeur() {
      return valeur;
    }
  }
  
  ```
  
  
  #### 2. Methode getFormuleAsString
  
  ```java
  
  class Grille {
    Map<String, Case> cases = new HashMap<>();
    
    String getFormule(String colonne, int ligne) {
      String code=colonne+ligne;
      return cases.get(code).getFormuleAsString();
    }
  }
  
  
  class Case {
    String colonne;
    int ligne;
    double valeur;
    Formule formule;
    
    String getFormuleAsString() {
        if (formule != null) 
            return formule.toString();
        else
            return toString();
    }
  }
  
  // Exemple pour Addition
  class Addition {
      Case gauche;
      Case droite;
      
      String toString() {
          return gauche.toString() + "+" + droite.toString();
      }
  }
  
  ```
  
  
  #### 3. Methode getFormuleDeveloppe
  
  ```java
  class Grille{
    Map<String, Case> cases  = new HashMap<>();
    
    String getFormuleDeveloppe(String colonne, int ligne) {
      String code=colonne+ligne;
      return cases.get(code).getFormuleDeveloppe();
    }
  }
  
  class Case{
    String colonne;
    int ligne;
    double valeur;
    Formule formule;
    ArrayList<Case> utiliseDans = new ArrayList<Case>(); 
    
    String getFormuleDeveloppe() {
        if (formule != null)
            return formule.getFormuleDeveoppe();
        else
            return toString();
    }
  }
  
  Average
  class Moyenne {
      List<Case> listCases = new ArrayList<Case>();
      
      String getFormuleDeveloppe() {
          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 {
    Case gauche;
    Case droite;
  
    double eval() {
        return gauche.getValeur() * droite.getValeur();
    }
  }
  ```
  
  
  - Dans Soustraction :
  
  ```java
  class Soustraction {
    Case gauche;
    Case droite;
  
    double eval() {
        return gauche.getValeur() - droite.getValeur();
    }
  }
  
  ```
  
  - Dans Division :
  
  ```java
  class Division {
    Case gauche;
    Case droite;
  
    double eval() {
      if (droite.getValeur() != 0)
          return gauche.getValeur() / droite.getValeur();
      else
          lève une exception
    }
  }
  
  ```
  
  - Dans Moyenne :
  
  ```java
  class Moyenne {
    List<Case> listCases = new ArrayList<Case>(); 
  
    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
  class Somme {
    List<Case> listCases = new ArrayList<Case>(); 
  
    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
  class Grille {
    Map<String, Case> cases  = new HashMap<>();
    
    void setValeur(String colonne, int ligne, double value) {
      String code = colonne + ligne;
      return cases.get(code).setValeur(value);
    }
  }
  
  class Case {
    String colonne;
    int ligne;
    double valeur;
    Formule formule;
    List<Case> utiliseDans = new ArrayList<Case>(); 
    
    void setValeur(double value) {
      valeur = value;
      for(int i=0; i<utiliseDans.size(); i++)
         utiliseDans.get(i).updateValeur();
    }
  }
  
  ```
  
  #### 5. Methode setFormule
  
  ```java
  class Grille {
    Map<String, Case> cases  = new HashMap<>();
    
    void setFormule(String colonne, int ligne, Formule formule) {
      String code = colonne + ligne;
      return cases.get(code).setFormule(formula);
    }
  }
  
  
  class Case {
    String colonne;
    int ligne;
    double valeur;
    Formule formule;
    List<Case> utiliseDans = new ArrayList<Case>();
    
    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 {
      Case gauche;
      Case droite;
      
      boolean creerCycle(Case case) {
          if (gauche != case && droite != case) {
              if (gauche.isFormula() && droite.isFormula())
                  return gauche.getFormule().creerCycle(case) && droite.getFormule().creerCycle(case);
              else
                  return false;
          }
          
          return true;
      }
  }
  
  ```
  
  ### 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é