From 444fd831c6b85101afc5969013bc8c99a9b46e55 Mon Sep 17 00:00:00 2001 From: Olli Hiekkaranta Date: Mon, 17 Oct 2016 11:45:30 +0300 Subject: [PATCH 1/2] add some logic and test --- src/Spreadsheet.java | 128 +++++++++++++++++++++++++++++++++++-- tests/SpreadsheetTest.java | 98 +++++++++++++++++++++++++++- 2 files changed, 218 insertions(+), 8 deletions(-) diff --git a/src/Spreadsheet.java b/src/Spreadsheet.java index e4f120b..eff5a22 100644 --- a/src/Spreadsheet.java +++ b/src/Spreadsheet.java @@ -1,18 +1,136 @@ +import java.util.ArrayList; +import java.util.HashMap; public class Spreadsheet { + + private static final String error = "#Error"; + private static final String circular = "#Circular"; + + private HashMap spreadSheet = new HashMap(); + private ArrayList nodes = new ArrayList(); public String get(String cell) { - // to be implemented - return null; + String val = spreadSheet.get(cell); + if (val != null) { + if (isValidString(val)) { + val = stripStringTags(val); + } + else if (isFormula(val)) { + val = handleFormula(cell, val); + } + } + else if (val != circular) { + nodes.remove(cell); + } + return val; + } + + private String handleFormula(String cell, String val) { + if (isValidCalculation(val.substring(1))) { + System.err.println("calc"); + val = calculate(val.substring(1)); + } + else if (isReference(val.substring(1))) { + if (!nodes.contains(cell)) { + nodes.add(cell); + } + else { + val = circular; + } + } + if (val != circular) { + val = evaluate(val.substring(1)); + } + return val; + } + + private boolean isFormula(String val) { + if (val.startsWith("=")) { + return true; + } + return false; + } + + private String stripStringTags(String val) { + val = val.replace("'", ""); + return val; } public void set(String cell, String value) { - // to be implemented + if (isValidInteger(value) || isValidString(value) || isFormula(value) || isValidCalculation(value)) { + spreadSheet.put(cell, value); + } + else { + spreadSheet.put(cell, error); + } } + private boolean isValidString(String value) { + if (value.startsWith("'") && value.endsWith("'")) { + return true; + } + return false; + } + + private boolean isValidInteger(String value) { + try { + Integer.parseInt(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + public String evaluate(String cell) { - // to be implemented - return null; + String val = cell; + if (isValidString(val)) { + val = stripStringTags(val); + } + else if (isValidInteger(val)) { + // + } + else if (isReference(val)) { + val = this.get(val); + } + else { + return error; + } + return val; + } + + private String calculate(String cell) { + String[] values = cell.split("[-+*/%]"); + int result = 0; + for (int i = 0; i < values.length; i++) { + System.err.println(values[i]); + result += Integer.parseInt(this.get(values[i])); + } + return Integer.toString(result); + } + + private boolean isValidCalculation(String cell) { + String[] values = cell.split("[-+*/%]"); + if (values.length > 1) { + for (int i = 0; i < values.length; i++) { + if (!isValidInteger(this.get(values[i]))) { + return false; + } + } + return true; + } + else { + return false; + } + } + + private boolean isReference(String cell) { + if (isValidInteger(cell) || isValidString(cell)) { + return false; + } + if (Character.isLetter(cell.charAt(0)) && Character.isDigit(cell.charAt(1))) { + return true; + } + return false; } } diff --git a/tests/SpreadsheetTest.java b/tests/SpreadsheetTest.java index 9e0936a..92680fb 100644 --- a/tests/SpreadsheetTest.java +++ b/tests/SpreadsheetTest.java @@ -5,11 +5,103 @@ public class SpreadsheetTest { + + Spreadsheet sheet = new Spreadsheet(); @Test - public void test() { - fail("Not yet implemented"); - + public void SpreadsheetTest_assign_get_val() { + sheet.set("A1", "-1"); + String val = sheet.get("A1"); + assertEquals("-1", val); + } + + @Test + public void SpreadsheetTest_assign_get_wrong_format_int() { + sheet.set("A1", "5A"); + String val = sheet.get("A1"); + assertEquals("#Error", val); + } + + @Test + public void SpreadsheetTest_assign_get_valid_string() { + sheet.set("A1", "'a string'"); + String val = sheet.get("A1"); + assertEquals("a string", val); + } + + @Test + public void SpreadsheetTest_assign_get_invalid_string() { + sheet.set("A1", "'a string"); + String val = sheet.get("A1"); + assertEquals("#Error", val); + } + + @Test + public void SpreadsheetTest_assign_formula_get_valid_string() { + sheet.set("A1", "='a string'"); + String val = sheet.get("A1"); + assertEquals("a string", val); + } + + @Test + public void SpreadsheetTest_assign_formula_get_invalid_string() { + sheet.set("A1", "='a string"); + String val = sheet.get("A1"); + assertEquals("#Error", val); + } + + @Test + public void SpreadsheetTest_assign_formula_get_valid_reference() { + sheet.set("A1", "='a string'"); + sheet.set("A2", "=A1"); + String val = sheet.get("A2"); + assertEquals("a string", val); + } + + @Test + public void SpreadsheetTest_assign_int_ref_get() { + sheet.set("A1", "5"); + sheet.set("A2", "=A1"); + String val = sheet.get("A2"); + assertEquals("5", val); + } + + @Test + public void SpreadsheetTest_assign_circular_reference_get() { + sheet.set("A1", "=A2"); + sheet.set("A2", "=A1"); + String val = sheet.get("A1"); + assertEquals("#Circular", val); + } + + @Test + public void SpreadsheetTest_invalid_calculation() { + sheet.set("A1", "10"); + sheet.set("A2", "5"); + sheet.set("A3", "asdf"); + sheet.set("A4", "A1+A2+A3"); + String val = sheet.get("A4"); + assertEquals("#Error", val); + } + + @Test + public void SpreadsheetTest_valid_calculation() { + sheet.set("A1", "10"); + sheet.set("A2", "5"); + sheet.set("A3", "4"); + sheet.set("A4", "=A1+A2+A3"); + String val = sheet.get("A4"); + assertEquals("19", val); + } + + @Test + public void SpreadsheetTest_valid_calculation_with_ref() { + sheet.set("A1", "10"); + sheet.set("A2", "5"); + sheet.set("A3", "=A1"); + sheet.set("A4", "=A1+A2+A3"); + String val = sheet.get("A4"); + assertEquals("25", val); } } From d4e67e0de76787877a7de484355657b60a39f3d9 Mon Sep 17 00:00:00 2001 From: Olli Hiekkaranta Date: Mon, 17 Oct 2016 13:03:36 +0300 Subject: [PATCH 2/2] add stuff --- src/Spreadsheet.java | 74 +++++++++++++++++++++++++++++++++----- tests/SpreadsheetTest.java | 51 ++++++++++++++++++++++++-- 2 files changed, 114 insertions(+), 11 deletions(-) diff --git a/src/Spreadsheet.java b/src/Spreadsheet.java index eff5a22..4f90980 100644 --- a/src/Spreadsheet.java +++ b/src/Spreadsheet.java @@ -19,7 +19,7 @@ else if (isFormula(val)) { val = handleFormula(cell, val); } } - else if (val != circular) { + if (val != circular && nodes.contains(cell)) { nodes.remove(cell); } return val; @@ -27,7 +27,6 @@ else if (val != circular) { private String handleFormula(String cell, String val) { if (isValidCalculation(val.substring(1))) { - System.err.println("calc"); val = calculate(val.substring(1)); } else if (isReference(val.substring(1))) { @@ -38,7 +37,7 @@ else if (isReference(val.substring(1))) { val = circular; } } - if (val != circular) { + if (val != circular && !isValidInteger(val)) { val = evaluate(val.substring(1)); } return val; @@ -53,6 +52,7 @@ private boolean isFormula(String val) { private String stripStringTags(String val) { val = val.replace("'", ""); + val = val.replace("&", ""); return val; } @@ -84,10 +84,15 @@ private boolean isValidInteger(String value) { public String evaluate(String cell) { String val = cell; if (isValidString(val)) { - val = stripStringTags(val); + if (hasStringOperation(val)) { + val = performStringOperation(val); + } + else { + val = stripStringTags(val); + } } else if (isValidInteger(val)) { - // + // do nothing } else if (isReference(val)) { val = this.get(val); @@ -98,21 +103,72 @@ else if (isReference(val)) { return val; } + private String performStringOperation(String val) { + String[] strings = val.split("&"); + String word; + String phrase = ""; + for (int i = 0; i < strings.length; i++) { + word = this.evaluate(strings[i]); + phrase = phrase.concat(word); + if (word == error) { + phrase = error; + break; + } + } + return phrase; + } + + private boolean hasStringOperation(String val) { + if (val.indexOf("&") != -1) { + return true; + } + return false; + } + private String calculate(String cell) { - String[] values = cell.split("[-+*/%]"); + String operations = "+"; int result = 0; + int val; + char operation; + String[] values = cell.split("[-+*/%]"); + operations += cell.replaceAll("\\w", ""); for (int i = 0; i < values.length; i++) { - System.err.println(values[i]); - result += Integer.parseInt(this.get(values[i])); + operation = operations.charAt(i); + if (isValidInteger(values[i])) { + val = Integer.parseInt(values[i]); + } + else { + val = Integer.parseInt(this.get(values[i])); + } + result = performOperation(result, val, operation); } return Integer.toString(result); } + private int performOperation(int result, int val, char operation) { + if (operation == '+') { + result += val; + } + else if (operation == '-') { + result -= val; + } + else if (operation == '*') { + result *= val; + } + else if (operation == '/') { + result /= val; + } + else if (operation == '%') { + result %= val; + } + return result; + } + private boolean isValidCalculation(String cell) { String[] values = cell.split("[-+*/%]"); if (values.length > 1) { for (int i = 0; i < values.length; i++) { - if (!isValidInteger(this.get(values[i]))) { + if (!isValidInteger(values[i]) && !isValidInteger(this.get(values[i]))) { return false; } } diff --git a/tests/SpreadsheetTest.java b/tests/SpreadsheetTest.java index 92680fb..4a40166 100644 --- a/tests/SpreadsheetTest.java +++ b/tests/SpreadsheetTest.java @@ -85,7 +85,7 @@ public void SpreadsheetTest_invalid_calculation() { } @Test - public void SpreadsheetTest_valid_calculation() { + public void SpreadsheetTest_valid_sum_calculation() { sheet.set("A1", "10"); sheet.set("A2", "5"); sheet.set("A3", "4"); @@ -95,7 +95,7 @@ public void SpreadsheetTest_valid_calculation() { } @Test - public void SpreadsheetTest_valid_calculation_with_ref() { + public void SpreadsheetTest_valid_sum_calculation_with_ref() { sheet.set("A1", "10"); sheet.set("A2", "5"); sheet.set("A3", "=A1"); @@ -103,5 +103,52 @@ public void SpreadsheetTest_valid_calculation_with_ref() { String val = sheet.get("A4"); assertEquals("25", val); } + + @Test + public void SpreadsheetTest_ref_error() { + sheet.set("A5", "5A"); + sheet.set("A1", "=A5"); + String val = sheet.get("A1"); + assertEquals("#Error", val); + } + + @Test + public void SpreadsheetTest_valid_mul_calculation() { + sheet.set("A1", "1"); + sheet.set("A2", "1"); + sheet.set("A3", "3"); + sheet.set("A4", "=A1+A2*A3"); + String val = sheet.get("A4"); + assertEquals("6", val); + } + + @Test + public void SpreadsheetTest_calc_error() { + sheet.set("A1", "1+A1"); + String val = sheet.get("A1"); + assertEquals("#Error", val); + } + + @Test + public void SpreadsheetTest_simple_calc() { + sheet.set("A1", "=1+2"); + String val = sheet.get("A1"); + assertEquals("3", val); + } + + @Test + public void SpreadsheetTest_string_concat() { + sheet.set("A1", "='a'&'string'"); + String val = sheet.get("A1"); + assertEquals("astring", val); + } + + @Test + public void SpreadsheetTest_string_concat_invalid() { + sheet.set("A1", "='a&'string'"); + String val = sheet.get("A1"); + assertEquals("#Error", val); + } + }