package de.hs_mannheim.informatik.spreadsheet; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * A simplified spreadsheet class for the PR1 programming lab at Hochschule Mannheim. * One aspect worth mentioning is that it only supports long numbers, not doubles. * * @author Oliver Hummel */ public class Spreadsheet { Cell[][] cells; /** * Constructor that creates a Spreadsheet of size rows * cols. * * @param rows number of rows * @param cols number of columns */ public Spreadsheet(int rows, int cols) { if(rows>99) rows = 99; else if(rows<1) rows = 1; if(cols < 1) cols = 1; else if(cols > 26) cols = 26; cells = new Cell[rows][cols]; for (int r = 0; r < rows; r++) for (int c = 0; c < cols; c++) cells[r][c] = new Cell(); } // ----- // retrieve or change values of cells private String get(int row, int col) { return cells[row][col].getValue(); } public String get(String cellName) { cellName = cellName.toUpperCase(); return get(getRow(cellName)-1, getCol(cellName)-1); } public String getCellName(int row, int col) { return ("" + ((char) ('A' + col))) + (row+1); } private void put(int row, int col, String value) { if (!value.startsWith("=")) cells[row][col].setValue(value); else { cells[row][col].setFormula(value); evaluateCell(row, col); } } public void put(String cellName, String value) { cellName = cellName.toUpperCase(); put(getRow(cellName)-1, getCol(cellName)-1, value); } private int getCol(String cellName) { return cellName.charAt(0) - 'A' + 1; } private int getRow(String cellName) { if(cellName.length()>2) return Integer.parseInt(""+cellName.charAt(1) + cellName.charAt(2)); return cellName.charAt(1) - '1' + 1; } // ----- // business logic /** * A method for reading in data from a CSV file. * * @param path The file to read. * @param separator The char used to split up the input, e.g. a comma or a semicolon. * @param startCellName The upper left cell where data from the CSV file should be inserted. * @return Nothing. * @throws IOException If path does not exist. */ public void readCsv(String path, char separator, String startCellName) throws FileNotFoundException { Scanner sc = new Scanner(new File(path)); ArrayList memList = new ArrayList<>(); while (sc.hasNextLine()) { memList.add(sc.nextLine()); } String[][] memArr = new String[memList.size()][]; for(int i = 0; i < memList.size(); i++) memArr[i] = (memList.get(i)).split(String.valueOf(separator)); for (int r = getRow(startCellName)-1; r < memList.size(); r++) for (int c = getCol(startCellName)-1; c < memList.get(0).length(); c++) if(c9) { substringStartCell1 = formula.substring(formula.length() - 6, formula.length() - 4); substringStartCell2 = formula.substring(formula.length() - 7, formula.length() - 5); substringStartCell3 = formula.substring(formula.length() - 8, formula.length() - 5); substringEndCell1 = formula.substring(formula.length() - 3, formula.length() - 1); substringEndCell2 = formula.substring(formula.length() - 4, formula.length() - 1); } if (formula.startsWith("SUMME("))// e.g. SUMME(A3:A8) if (formula.length() < 13) result = sum(substringStartCell1, substringEndCell1); else if (formula.length() < 14) result = sum(substringStartCell2, substringEndCell2); else if (formula.length() < 15) result = sum(substringStartCell3, substringEndCell2); else result = 0; else if (formula.startsWith("PRODUKT(")) // e.g. PRODUKT(A3:B9) if (formula.length() < 15) result = product(substringStartCell1, substringEndCell1); else if (formula.length() < 16 && !substringEndCell2.contains(":")) result = product(substringStartCell2, substringEndCell2); else if (formula.length() < 17) result = product(substringStartCell3, substringEndCell2); else result = 0; else if (formula.startsWith("MITTELWERT(")) // e.g. MITTELWERT(A3:A5) if (formula.length() < 18) result = average(substringStartCell1, substringEndCell1); else if (formula.length() < 19) result = average(substringStartCell2, substringEndCell2); else if (formula.length() < 20) result = average(substringStartCell3, substringEndCell2); else result = 0; else if (formula.startsWith("STABW(")) // e.g. STABW(C6:D8) -> Standardabweichung if (formula.length() < 13) result = standardDeviation(substringStartCell1, substringEndCell1); else if (formula.length() < 14) result = standardDeviation(substringStartCell2, substringEndCell2); else if (formula.length() < 15) result = standardDeviation(substringStartCell3, substringEndCell2); else result = 0; else if (formula.startsWith("MIN(")) // e.g. MIN(C1:H13) -> kleinster Wert if (formula.length() < 11) result = min(substringStartCell1, substringEndCell1); else if (formula.length() < 12) result = min(substringStartCell2, substringEndCell2); else if (formula.length() < 13) result = min(substringStartCell3, substringEndCell2); else result = 0; else if (formula.startsWith("MAX(")) // e.g. MAX(A1:A10) -> größter Wert if (formula.length() < 11) result = max(substringStartCell1, substringEndCell1); else if (formula.length() < 12) result = max(substringStartCell2, substringEndCell2); else if (formula.length() < 13) result = max(substringStartCell3, substringEndCell2); else result = 0; else if (!formula.isEmpty()) { try { result = calculate(formula); } catch (ArithmeticException ae) { result = 0; } } if(!cells[row][col].getFormula().isEmpty()) if(String.format("%.2f",result).substring(String.format("%.2f",result).length()-2).charAt(0)=='0'&& String.format("%.2f",result).substring(String.format("%.2f",result).length()-2).charAt(1)=='0') cells[row][col].setValue(String.format("%.0f",result)); else if(String.format("%.2f",result).substring(String.format("%.2f",result).length()-2).charAt(1)=='0') cells[row][col].setValue(String.format("%.1f",result)); else cells[row][col].setValue(String.format("%.2f",result)); } /** * Method for calculating the sum of a rectangular block of cells, such as from A1 to B3. * * @param startCellName The name of the cell in the upper left corner of the rectangle. * @param endCellName The name of the cell in the lower right corner of the rectangle. * @return The sum calculated. */ private double sum(String startCellName, String endCellName) { double result = 0; for(int r = getRow(startCellName)-1; r0) result *= Double.parseDouble(cells[r][c].getValue()); else { result = Double.parseDouble(cells[r][c].getValue()); counter++; } return result; } /** * Method for calculating the average of a rectangular block of cells, such as from A1 to B3. * * @param startCellName The name of the cell in the upper left corner of the rectangle. * @param endCellName The name of the cell in the lower right corner of the rectangle. * @return The average calculated. */ private double average(String startCellName, String endCellName) { double result = 0; int counter = 0; for(int r = getRow(startCellName)-1; r cellNames = new ArrayList<>(); double avg = 0; int counter = 0; for(int r = getRow(startCellName)-1; r copyCellNames = new ArrayList<>(cellNames); double[] frequency = new double[cellNames.size()]; Arrays.fill(frequency,1); ArrayList relativeFrequency = new ArrayList<>(); double mem = 0; for(int i = 0; i< cellNames.size(); i++) { for(int t = 0; t cellNames = new ArrayList<>(); for(int r = getRow(startCellName)-1; r Double.parseDouble(get(cellNames.get(i)))) result = Double.parseDouble(get(cellNames.get(i))); } catch(NumberFormatException n){} return result; } /** * Method to find out the highest number of a rectangular block of cells, such as from A1 to B3. * * @param startCellName The name of the cell in the upper left corner of the rectangle. * @param endCellName The name of the cell in the lower right corner of the rectangle. * @return The highest number. */ private double max(String startCellName, String endCellName){ ArrayList cellNames = new ArrayList<>(); for(int r = getRow(startCellName)-1; r inputs = new ArrayList<>(); for(int i =0; i19) sb.append(" " + String.format("%19s", cells[r][c].getValue()).substring(0,19) + " |"); else sb.append(" " + String.format("%19s", cells[r][c].getValue()) + " |"); } } sb.append(System.lineSeparator()); for (int i = 0; i < cells[0].length; i++) { sb.append("----------------------"); } sb.append("------"); sb.append(System.lineSeparator()); return sb.toString(); } /** * This method outputs the cell spreadsheet with all the formulas instead of the values. * * @return nothing. */ public String toStringShowFormula() { StringBuilder sb = new StringBuilder(); sb.append(System.lineSeparator()); sb.append(System.lineSeparator()); sb.append(" |"); for (int i = 0; i < cells[0].length; i++) { sb.append(" " + (char) ('A' + i) + " |"); } int rc = 1; for (int r = 0; r < cells.length; r++) { sb.append(System.lineSeparator()); for (int i = 0; i < cells[0].length; i++) { sb.append("----------------------"); } sb.append("------"); sb.append(System.lineSeparator()); sb.append(String.format(" " + "%2s", rc++) + " |"); for (int c = 0; c < cells[r].length; c++) { sb.append(" " + String.format("%19s", cells[r][c].getFormula()) + " |"); } } sb.append(System.lineSeparator()); for (int i = 0; i < cells[0].length; i++) { sb.append("----------------------"); } sb.append("------"); sb.append(System.lineSeparator()); return sb.toString(); } }