From d2aa28c5b365fdba869b04e3aa8c4d858efef404 Mon Sep 17 00:00:00 2001 From: 3013050 <3013050@stud.hs-mannheim.de> Date: Sat, 30 Dec 2023 01:27:14 +0100 Subject: [PATCH] Program commands Added program commands like saving, loading, exiting a file or clearing the table, added example file including formulas --- Axel/resources/zahlen.csv | 15 +- .../informatik/spreadsheet/Axel.java | 177 +++++++++--------- .../informatik/spreadsheet/Spreadsheet.java | 88 ++++++++- 3 files changed, 178 insertions(+), 102 deletions(-) diff --git a/Axel/resources/zahlen.csv b/Axel/resources/zahlen.csv index 1ec60e0..70451cd 100644 --- a/Axel/resources/zahlen.csv +++ b/Axel/resources/zahlen.csv @@ -1,4 +1,11 @@ -1,2 -3,4 -5,6 -7,8 +1,5,=SUMME(A1:B4),,,,,,,,200 +2,6,,,,,,,,, +3,7,,,,,,,,, +4,8,,=1+4*A2,,,2,,,4, +,,,,,3,3,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,,, +,,,,,,,,69,, +,,,,,,,=STABW(K1:K11),,,100 diff --git a/Axel/src/de/hs_mannheim/informatik/spreadsheet/Axel.java b/Axel/src/de/hs_mannheim/informatik/spreadsheet/Axel.java index 8246190..cb10cb8 100644 --- a/Axel/src/de/hs_mannheim/informatik/spreadsheet/Axel.java +++ b/Axel/src/de/hs_mannheim/informatik/spreadsheet/Axel.java @@ -1,5 +1,6 @@ package de.hs_mannheim.informatik.spreadsheet; +import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Scanner; @@ -13,36 +14,21 @@ import java.util.regex.Pattern; */ public class Axel { static Scanner keyboard = new Scanner(System.in); - static Spreadsheet spr = new Spreadsheet(11,11); + static Spreadsheet spr = new Spreadsheet(11, 11); + static String saveFilePath = "Axel\\resources\\zahlen.csv"; public static void main(String[] args) throws FileNotFoundException { System.out.println("Welcome to Axel (Totally not Excel)"); System.out.println(); - /* - spr.put("A1", "1"); - spr.put("A2", "1"); - spr.put("A3", "123"); - spr.put("B1", "2"); - spr.put("B2", "4"); - spr.put("B3", "1"); - spr.put("B4", "=41+A2"); - spr.put("C5", "=7*6"); - spr.put("D1", "=3/2"); - */ - - progLoad(); + spr.loadSpecialTable(); System.out.println(spr); - + // spr.saveCsv("/tmp/test.csv"); - - // DONE: You might want to put "UI loop" for entering value and formulas here resp. in some UI methods. - // TODO ME: Implement program commands - - while(true) { + while (true) { String userCommandPositionInput = userCommandPositionInput(); - if (userCommandPositionInput.charAt(0) == '*'){ + if (userCommandPositionInput.charAt(0) == '*') { executeCommand(userCommandPositionInput); System.out.println(spr); continue; @@ -60,25 +46,25 @@ public class Axel { //? User input for a program command or a position - public static String userCommandPositionInput(){ + public static String userCommandPositionInput() { System.out.println(); System.out.println("Input a command for the program or a position"); - System.out.printf("List of program commands: *exit, *save, *load or *help %nFormat for position: A1 or B14%n"); + System.out.printf("List of program commands: *clear, *load, *save, *exit or *help %nFormat for position: A1 or B14%n"); System.out.print("Input: "); String userCommandPositionInput = keyboard.nextLine(); return userCommandPositionComputation(userCommandPositionInput); } - public static String userCommandPositionComputation(String userCommandPositionInput){ + public static String userCommandPositionComputation(String userCommandPositionInput) { - if (userCommandPositionInput.isEmpty()){ + if (userCommandPositionInput.isEmpty()) { System.out.println("Input is empty!"); return userCommandPositionInput(); } //? Program command - if (userCommandPositionInput.charAt(0) == '*'){ + if (userCommandPositionInput.charAt(0) == '*') { if (!(userCommandErrorCheck(userCommandPositionInput))) { System.out.println("Invalid command!"); return userCommandPositionInput(); @@ -87,12 +73,12 @@ public class Axel { } //? Position - if (!(userPositionErrorCheck(userCommandPositionInput, spr))){ + if (!(userPositionErrorCheck(userCommandPositionInput, spr))) { System.out.println("Invalid position!"); return userCommandPositionInput(); } - if (!(userPositionBoundsErrorCheck(userCommandPositionInput, spr))){ + if (!(userPositionBoundsErrorCheck(userCommandPositionInput, spr))) { System.out.println("Position out of bounds!"); return userCommandPositionInput(); } @@ -100,35 +86,35 @@ public class Axel { return userCommandPositionInput; } - public static boolean userCommandErrorCheck(String CommandToCheck){ + public static boolean userCommandErrorCheck(String CommandToCheck) { //? true if valid - //? valid inputs are: *exit, *save, *load, *help (and all upper case variants) + //? valid inputs are: *clear, *exit, *save, *load, *help (and all upper case variants) CommandToCheck = CommandToCheck.toLowerCase(); - if (CommandToCheck.equals("*exit") || CommandToCheck.equals("*save") || CommandToCheck.equals("*load") || CommandToCheck.equals("*help")){ + if (CommandToCheck.equals("*clear") || CommandToCheck.equals("*exit") || CommandToCheck.equals("*save") || CommandToCheck.equals("*load") || CommandToCheck.equals("*help")) { return true; } return false; } - public static boolean userPositionErrorCheck(String positionToCheck, Spreadsheet spr){ + public static boolean userPositionErrorCheck(String positionToCheck, Spreadsheet spr) { //? true if valid //? valid inputs are: A1, B14, C79, E99, F1, G99, J1, M98, ... (and all lower case variants) positionToCheck = positionToCheck.toUpperCase(); //? Check if input is the right length - if (positionToCheck.length() < 2 || positionToCheck.length() > 3){ + if (positionToCheck.length() < 2 || positionToCheck.length() > 3) { return false; } //? Check if input is in the right format - if (!(Character.isLetter(positionToCheck.charAt(0)) && Character.isDigit(positionToCheck.charAt(1)))){ + if (!(Character.isLetter(positionToCheck.charAt(0)) && Character.isDigit(positionToCheck.charAt(1)))) { return false; } - if (positionToCheck.length() == 3){ - if (!(Character.isDigit(positionToCheck.charAt(2)))){ + if (positionToCheck.length() == 3) { + if (!(Character.isDigit(positionToCheck.charAt(2)))) { return false; } } @@ -136,7 +122,7 @@ public class Axel { return true; } - public static boolean userPositionBoundsErrorCheck(String positionToCheck, Spreadsheet spr){ + public static boolean userPositionBoundsErrorCheck(String positionToCheck, Spreadsheet spr) { //? true if valid positionToCheck = positionToCheck.toUpperCase(); @@ -150,7 +136,7 @@ public class Axel { //? User input for a value or a formula - public static String userValueFormulaInput(String currentPos){ + public static String userValueFormulaInput(String currentPos) { System.out.println(); System.out.printf("Input a value of a formula for the selected position: %s.%n", currentPos); System.out.printf("Format for a value: 7 or 1337 %nFormat for a formula: =7*6 or =SUMME(A1:A3)%n"); @@ -160,14 +146,14 @@ public class Axel { return userValueFormulaComputation(userCommandInput, currentPos); } - public static String userValueFormulaComputation(String userValueFormulaInput, String currentPos){ - if (userValueFormulaInput.isEmpty()){ + public static String userValueFormulaComputation(String userValueFormulaInput, String currentPos) { + if (userValueFormulaInput.isEmpty()) { System.out.println("Input is empty!"); return userValueFormulaInput(currentPos); } //? Formula - if (userValueFormulaInput.charAt(0) == '='){ + if (userValueFormulaInput.charAt(0) == '=') { if (!(userFormulaErrorCheck(userValueFormulaInput))) { System.out.println("Invalid formula!"); return userValueFormulaInput(currentPos); @@ -176,7 +162,7 @@ public class Axel { } //? Value - if (!(userValueErrorCheck(userValueFormulaInput))){ + if (!(userValueErrorCheck(userValueFormulaInput))) { System.out.println("Invalid value!"); return userValueFormulaInput(currentPos); } @@ -184,59 +170,56 @@ public class Axel { return userValueFormulaInput; } - public static boolean userFormulaErrorCheck(String formulaToCheck){ + public static boolean userFormulaErrorCheck(String formulaToCheck) { //? true if valid //? valid inputs are: =7*6, =SUM(A1:A3), =A1, =A1+A2, =A1-A2, ... (and all lower case variants) - //TODO ME: Formula format check, maybe too much work - //TODO ME: Check if formula vars are in bounds - //? remove '=' at the beginning and make everything upper case formulaToCheck = formulaToCheck.toUpperCase().substring(1); - if (formulaToCheck.startsWith("SUMME(") || formulaToCheck.startsWith("PRODUKT(") || formulaToCheck.startsWith("MITTELWERT(") || formulaToCheck.startsWith("STABW(") || formulaToCheck.startsWith("MIN(") || formulaToCheck.startsWith("MAX(")){ + if (formulaToCheck.startsWith("SUMME(") || formulaToCheck.startsWith("PRODUKT(") || formulaToCheck.startsWith("MITTELWERT(") || formulaToCheck.startsWith("STABW(") || formulaToCheck.startsWith("MIN(") || formulaToCheck.startsWith("MAX(")) { return userFormulaFunctionErrorCheck(formulaToCheck); } return userFormulaExpressionErrorCheck(formulaToCheck); } - public static boolean userFormulaFunctionErrorCheck(String functionToCheck){ + public static boolean userFormulaFunctionErrorCheck(String functionToCheck) { String[] functionCorners = spr.isolateFunctionCorners(functionToCheck); - if (functionCorners.length != 2){ + if (functionCorners.length != 2) { return false; } - for (String functionCorner: functionCorners){ - if (!(spr.isValueCellName(functionCorner).equals("cellName"))){ + for (String functionCorner : functionCorners) { + if (!(spr.isValueCellName(functionCorner).equals("cellName"))) { return false; } - if (!userPositionBoundsErrorCheck(functionCorner, spr)){ + if (!userPositionBoundsErrorCheck(functionCorner, spr)) { System.out.print("Out of bounds - "); return false; } } if (functionToCheck.startsWith("MITTELWERT(") || functionToCheck.startsWith("STABW(")) { - String[] functionBlock= spr.wholeFunctionBlock(functionToCheck); + String[] functionBlock = spr.wholeFunctionBlock(functionToCheck); boolean allEmpty = true; for (String cell : functionBlock) { - if (!cell.isEmpty()){ + if (!cell.isEmpty()) { allEmpty = false; } } - if (allEmpty){ + if (allEmpty) { System.out.print("Division by zero - "); return false; } } if (functionToCheck.startsWith("STABW(")) { - String[] functionBlock= spr.wholeFunctionBlock(functionToCheck); + String[] functionBlock = spr.wholeFunctionBlock(functionToCheck); String[] notEmptyValues = spr.extractNotEmptyCells(functionBlock); - if (notEmptyValues.length < 2){ + if (notEmptyValues.length < 2) { System.out.print("Division by zero - "); return false; } @@ -244,12 +227,12 @@ public class Axel { return true; } - public static boolean userFormulaExpressionErrorCheck(String expressionToCheck){ - + public static boolean userFormulaExpressionErrorCheck(String expressionToCheck) { + //TODO ME: Maybe not worth the time return true; } - public static boolean userValueErrorCheck(String valueToCheck){ + public static boolean userValueErrorCheck(String valueToCheck) { //? true if valid //? valid inputs are: 7, 1337, 0, , -213,... @@ -257,48 +240,64 @@ public class Axel { // String digitCheckRegex = "-?\\d+(\\.\\d+)?"; //? For integers String digitCheckRegex = "-?\\d+"; - if (!(valueToCheck.matches(digitCheckRegex))){ + if (!(valueToCheck.matches(digitCheckRegex))) { return false; } - return true; } - public static void executeCommand(String command) { - System.out.printf("Executing command: %s%n", command); - //TODO ME: - switch (command){ + public static void executeCommand(String command) throws FileNotFoundException { + switch (command) { + case "*clear": + progClear(); + break; + case "*load": progLoad(); break; + + case "*save": + progSave(); + break; + + case "*exit": + progExit(); + break; } } - private static void progLoad(){ - int rows = spr.getRowsLCount(); - int cols = spr.getColsCount(); + private static void progClear(){ + System.out.println("Are you sure you want to clear the table? (yes/no)"); + System.out.print("Input: "); + String userClearInput = keyboard.nextLine().toLowerCase(); - for (int r = 0; r < rows; r++){ - for (int c = 0; c < cols; c++){ - spr.cells[r][c].setValue(""); - } + if (userClearInput.equals("yes") || userClearInput.equals("y")){ + spr.clearTable(); + System.out.println("Table cleared!"); } - spr.put("A1", "1"); - spr.put("A2", "2"); - spr.put("A3", "3"); - spr.put("A4", "4"); - spr.put("B1", "5"); - spr.put("B2", "6"); - spr.put("B3", "7"); - spr.put("B4", "8"); - spr.put("K1", "200"); - spr.put("K11", "100"); - spr.put("J4", "4"); - spr.put("I10", "69"); - spr.put("F5", "3"); - spr.put("G4", "2"); - spr.put("G5", "3"); - } + + private static void progLoad() throws FileNotFoundException { + spr.readCsv(saveFilePath, ",", "Amogus"); + System.out.println("File loaded!"); + } + + private static void progSave() throws FileNotFoundException { + String savePath = saveFilePath; + spr.saveCsv(savePath); + System.out.println("File saved"); + } + + private static void progExit() throws FileNotFoundException { + System.out.println("Do you want to save befor you exit? (yes/no)"); + System.out.print("Input: "); + String userExitInput = keyboard.nextLine().toLowerCase(); + + if (userExitInput.equals("yes") || userExitInput.equals("y")) { + progSave(); + } + System.out.println("Goodbye!"); + } + } \ No newline at end of file diff --git a/Axel/src/de/hs_mannheim/informatik/spreadsheet/Spreadsheet.java b/Axel/src/de/hs_mannheim/informatik/spreadsheet/Spreadsheet.java index dfaebca..c3d8d78 100644 --- a/Axel/src/de/hs_mannheim/informatik/spreadsheet/Spreadsheet.java +++ b/Axel/src/de/hs_mannheim/informatik/spreadsheet/Spreadsheet.java @@ -1,10 +1,12 @@ package de.hs_mannheim.informatik.spreadsheet; import javax.naming.ldap.spi.LdapDnsProviderResult; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -24,8 +26,6 @@ public class Spreadsheet { */ public Spreadsheet(int rows, int cols) { - // TODO limit the maximum size on 99 (1..99) rows and 26 (A..Z) columns - if (rows > 99){ System.out.printf("Row size %d is bigger then 99, value will be set to 99! %n", rows); rows = 99; @@ -58,6 +58,7 @@ public class Spreadsheet { if (!value.startsWith("=")) cells[row][col].setValue(value); else { + System.out.printf("Formula: %s %n", value); cells[row][col].setFormula(value); evaluateCell(row, col); } @@ -85,24 +86,62 @@ public class Spreadsheet { /** * A method for reading in data from a CSV file. - * @param path The file to read. + * @param filePath 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. * @exception IOException If path does not exist. */ - public void readCsv(String path, char separator, String startCellName) throws FileNotFoundException { - // TODO: implement this + public void readCsv(String filePath, String separator, String startCellName) throws FileNotFoundException { + ArrayList fileRows = new ArrayList<>(); + Scanner sc = new Scanner(new File(filePath)); + + while (sc.hasNextLine()) { + fileRows.add(sc.nextLine()); + } + clearTable(); + + ArrayList formulas = new ArrayList<>(); + + for (int rowI = 0; rowI < fileRows.size(); rowI++) { + String row = fileRows.get(rowI); + String[] cells = row.split(separator); + + for (int colI = 0; colI < cells.length; colI++) { + String cellContent = cells[colI].toUpperCase(); + + if (cellContent.startsWith("=")){ + formulas.add(new int[]{rowI, colI}); + } + else { + put(rowI, colI, cellContent); + } + + } + } + + for (int[] formulaPos : formulas){ + int rowI = formulaPos[0]; + int colI = formulaPos[1]; + System.out.printf("Formula at %d-%d %n", rowI, colI); + + String row = fileRows.get(rowI); + String formulaToFill = row.split(separator)[colI]; + + put(rowI, colI, formulaToFill); + } + + sc.close(); } /** * A method for saving data to a CSV file. - * @param path The file to write. + * @param filePath The file to write. * @return Nothing. - * @exception IOException If path does not exist. + * @exception FileNotFoundException If path does not exist. */ - public void saveCsv(String path) throws FileNotFoundException { - PrintWriter out = new PrintWriter(path); + public void saveCsv(String filePath) throws FileNotFoundException { + PrintWriter out = new PrintWriter(filePath); for (Cell[] row : cells) { for (Cell cell : row) { @@ -129,6 +168,7 @@ public class Spreadsheet { private void evaluateCell(int row, int col) { String formula = cells[row][col].getFormula(); + System.out.printf("Formel in eval: %s %n", formula); String result = ""; if (formula.startsWith("SUMME(")) // e.g. SUMME(A3:A8) @@ -451,6 +491,36 @@ public class Spreadsheet { return cells[0].length; } + public void clearTable() { + int rows = getRowsLCount(); + int cols = getColsCount(); + + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + cells[r][c].setValue(""); + } + } + } + + public void loadSpecialTable(){ + clearTable(); + + put("A1", "1"); + put("A2", "2"); + put("A3", "3"); + put("A4", "4"); + put("B1", "5"); + put("B2", "6"); + put("B3", "7"); + put("B4", "8"); + put("K1", "200"); + put("K11", "100"); + put("J4", "4"); + put("I10", "69"); + put("F5", "3"); + put("G4", "2"); + put("G5", "3"); + } public String toString() { StringBuilder sb = new StringBuilder();