diff --git a/.Rhistory b/.Rhistory new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/.Rhistory diff --git a/essai.ser b/essai.ser index a851fdf..249ca48 100644 Binary files a/essai.ser and b/essai.ser differ diff --git a/rapport_finale.md b/rapport_finale.md new file mode 100644 index 0000000..6547b05 --- /dev/null +++ b/rapport_finale.md @@ -0,0 +1,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 plageCase1 = new ArrayList(); // 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 plageCase2 = new ArrayList(); // 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 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 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 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 utiliseDans = new ArrayList(); + + String getFormuleDeveloppe() { + if (formule != null) + return formule.getFormuleDeveoppe(); + else + return toString(); + } +} + +Average +class Moyenne { + List listCases = new ArrayList(); + + 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 listCases = new ArrayList(); + + double eval() { + double val=0; + + if (listCases.size() != 0) + for(int i=0; i listCases = new ArrayList(); + + double eval() { + double val=0; + if (listCases.size() != 0) + for(int i=0; i 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 utiliseDans = new ArrayList(); + + void setValeur(double value) { + valeur = value; + for(int i=0; i 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 utiliseDans = new ArrayList(); + + void updateValeur() { + valeur = formule.eval(); + } + + void setFormule(Formule formula) { + if (!formula.creerCycle(this)) + formule = formula; + updateValeur(); + for(int i=0; i sumList = new ArrayList<>(); diff --git a/src/ihm/TablooProto.java b/src/ihm/TablooProto.java index 39a93b8..4a66491 100644 --- a/src/ihm/TablooProto.java +++ b/src/ihm/TablooProto.java @@ -4,28 +4,38 @@ package ihm; * TablooProto.java requires no other files. * */ - -import kernel.Grid; -import kernel.exception.CellNotFoundException; -import kernel.exception.InvalidIntervalException; - -import javax.swing.*; +import java.awt.Color; +import java.awt.Component; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; import javax.swing.table.AbstractTableModel; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.TableColumn; -import java.awt.*; +import java.awt.Dimension; +import java.awt.GridLayout; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.ObjectInputStream; -import java.util.Collections; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableColumn; + +import kernel.Grid; +import kernel.exception.CellNotFoundException; +import kernel.exception.InvalidIntervalException; public class TablooProto extends JPanel { + /** + * + */ private static final long serialVersionUID = 1L; // Fourni: ne rien changer. - public TablooProto() throws ClassNotFoundException, IOException { + public TablooProto() throws FileNotFoundException, ClassNotFoundException, IOException { super(new GridLayout(1, 0)); // modele de donnees @@ -90,15 +100,19 @@ public class TablooProto extends JPanel { private static final long serialVersionUID = 1L; // TODO // remplacer ce tableau en dur du prototype par la grille serialisee: - // noyau.Grille calc; - Grid calc; + kernel.Grid calc; + //String[][] calc; - MyTableModel() throws ClassNotFoundException, IOException { + MyTableModel() throws FileNotFoundException, IOException, ClassNotFoundException { // TODO: remplacer cette initialisation par le chargement de la grille serialisee - File fichier = new File("essai.ser") ; + File fichier = new File("grille.ser") ; ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fichier)) ; calc = (Grid)ois.readObject() ; ois.close(); + //calc = new String[this.getRowCount()][this.getColumnCount()]; + //for (int ligne =0; ligne < calc.length; ligne++) + //for (int colonne=0; colonne < calc[ligne].length; colonne++) + //calc[ligne][colonne] = ""; } @Override @@ -106,17 +120,14 @@ public class TablooProto extends JPanel { public int getColumnCount() { // TODO: remplacer par le nbre de colonnes de la grille // + 1 pour la colonne 0 consacrée aux numeros de ligne) - //return Collections.max(calc.getTotalColumn())+1; - return 10; + return calc.getTotalColumn()+1; } @Override // Standard: doit retourner le nbre de lignes de la JTable public int getRowCount() { // TODO: remplacer par le nbre de lignes de la grille - return Collections.max(calc.getTotalLine())+1; - //return 10; - + return calc.getTotalLine(); } // Standard: doit renvoyer le nom de la colonne a afficher en tete @@ -150,12 +161,11 @@ public class TablooProto extends JPanel { try { return "" + calc.getDevelopedFormula(this.getColumnName(col), row+1)+"="+calc.getValue(this.getColumnName(col), row+1); } catch (CellNotFoundException e) { - + // TODO Auto-generated catch block } } - return 0; - + return ""; } // Standard. @@ -202,7 +212,7 @@ public class TablooProto extends JPanel { calc.createCell(this.getColumnName(col), row+1, Double.parseDouble((String)value)); } catch (InvalidIntervalException e) { // TODO Auto-generated catch block - e.printStackTrace(); + } } // Ne pas modifier : @@ -214,7 +224,7 @@ public class TablooProto extends JPanel { // Exécution de l'interface graphique a partir d'un terminal. // TODO: parametrer le tout par un fichier de grille serialisee. - public static void main(String[] args) throws ClassNotFoundException, IOException { + public static void main(String[] args) throws FileNotFoundException, ClassNotFoundException, IOException { // TODO: parametrer le tableur par un fichier de grille serialisee // a charger comme modele de donnees. TablooProto tableur = new TablooProto(); diff --git a/src/kernel/Cell.java b/src/kernel/Cell.java index b1b9f03..27503a4 100644 --- a/src/kernel/Cell.java +++ b/src/kernel/Cell.java @@ -10,7 +10,7 @@ import java.util.List; public class Cell implements Serializable { private static final long serialVersionUID = 1L; - private static final int MAX_LIGNES = 20; + private String column; private int line; @@ -18,10 +18,9 @@ public class Cell implements Serializable { private Formula formula; private List usedIn = new ArrayList<>(); - public Cell(String column, int line, double value) throws InvalidIntervalException { - column = column.toUpperCase(); - if (!validateInterval(column, line)) - throw new InvalidIntervalException(); + public Cell(String column, int line, double value) { + + this.column = column; this.line = line; @@ -29,10 +28,8 @@ public class Cell implements Serializable { } public Cell(String column, int line, Formula formula) - throws CreateCycleException, InvalidIntervalException { - column = column.toUpperCase(); - if (!validateInterval(column, line)) - throw new InvalidIntervalException(); + throws CreateCycleException { + this.column = column; this.line = line; @@ -96,7 +93,5 @@ public class Cell implements Serializable { } } - private boolean validateInterval(String column, int line) { - return line >= 1 && line <= MAX_LIGNES && column.compareTo("A") >= 0 && column.compareTo("Z") <= 0; - } + } diff --git a/src/kernel/Grid.java b/src/kernel/Grid.java index 2a7249f..7e3f39a 100644 --- a/src/kernel/Grid.java +++ b/src/kernel/Grid.java @@ -13,26 +13,32 @@ import java.util.Map; public class Grid implements Serializable { private static final long serialVersionUID = 1L; - + private static final int MAX_LIGNES = 20; + private static final String MAX_COLONNES = "Z"; private Map cells = new HashMap<>(); public static LanguageEnum language = LanguageEnum.FR; - private List listLine = new ArrayList<>(); - private List listColumn = new ArrayList<>(); + public void createCell(String column, int line, double value) throws InvalidIntervalException { + column = column.toUpperCase(); + + if (!validateInterval(column, line)) + throw new InvalidIntervalException(); String id = this.getCellId(column, line); Cell cell = new Cell(column, line, value); - this.cells.put(id, cell); - this.saveDifferentLineColumn(column, line); + } public void createCell(String column, int line, Formula formula) throws CreateCycleException, InvalidIntervalException { + column = column.toUpperCase(); + + if (!validateInterval(column, line)) + throw new InvalidIntervalException(); String id = this.getCellId(column, line); Cell cell = new Cell(column, line, formula); - this.cells.put(id, cell); - this.saveDifferentLineColumn(column, line); + } public void setValue(String column, int line, double value) throws CellNotFoundException { @@ -77,18 +83,28 @@ public class Grid implements Serializable { return column + line; } - private void saveDifferentLineColumn(String column, int line) { - if (!this.listLine.contains(line)) - this.listLine.add(line); - if (!this.listColumn.contains((int) column.charAt(0))) - this.listColumn.add((int) column.charAt(0) - (int) 'A' + 1); + + public int getTotalColumn() { + return MAX_COLONNES.charAt(0) - (int) 'A' + 1; + //return convertStringToInt(MAX_COLONNES); + } + + public int getTotalLine() { + return MAX_LIGNES; } - public List getTotalColumn() { - return listColumn; + private boolean validateInterval(String column, int line) { + return line >= 1 && line <= MAX_LIGNES && convertStringToInt(column)>=convertStringToInt("A") && convertStringToInt(column)<=convertStringToInt(MAX_COLONNES); } - public List getTotalLine() { - return listLine; + private int convertStringToInt(String str){ + int ascii=0; + for(int i = 0; i < str.length(); i++){ // while counting characters if less than the length add one + char character = str.charAt(i); // start on the first character + ascii = ascii+(int) character; + + } + return ascii; } + } -- libgit2 0.21.2