Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 133 additions & 5 deletions src/Spreadsheet.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,146 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

public class Spreadsheet {

private static final String CIRCULAR_TAG = "#Circular";
private static final String ERROR_TAG = "#Error";
HashMap<String, List<SubEntry>> cell_entries = new HashMap<>();
Set<Integer> references;
boolean circularDetected = false;

public String get(String cell) {
// to be implemented
return null;
return concatSubEntries(cell_entries.get(cell));
}

public void set(String cell, String value) {
// to be implemented
cell_entries.put(cell, createSubEntries(value));
}

public String evaluate(String cell) {
// to be implemented
return null;
references = new HashSet<>();
List<String> evaluatedSubEntries = new LinkedList<>();
for (SubEntry se : cell_entries.get(cell)) {
String evaluatedSubEntry = evaluateSubEntry(se);
if (evaluatedSubEntry.equals(ERROR_TAG))
return ERROR_TAG;
else
evaluatedSubEntries.add(evaluatedSubEntry);

if (circularDetected) {
return CIRCULAR_TAG;
}
}
String cell_entry = concatStrings(evaluatedSubEntries);

return cell_entry;
}

public String evaluateSubEntry(SubEntry se) {
if (se.getType() == SubEntryType.NUMBER && ! isNum(se.getValue())) {
return ERROR_TAG;
} else if (se.getType() == SubEntryType.REFERENCE) {
if (references.contains(Integer.valueOf(se.getValue()))) {
circularDetected = true;
return CIRCULAR_TAG;
} else {
references.add(Integer.valueOf(se.getValue()));
return evaluate("A" + se.getValue());
}
} else {
return se.getValue();
}
}

public String concatSubEntries(List<SubEntry> subEntries) {
String res = "";
for (SubEntry se : subEntries) {
res += se.getValue();
}
return res;
}

public String concatStrings(List<String> strings) {
String res = "";
for (String s : strings) {
res += s;
}
return res;
}

public List<SubEntry> createSubEntries(String cell) {
List<SubEntry> subEntries = new LinkedList<>();
String intSubEntry = "";
String strSubEntry = "";
String refValue = "";
boolean quotesOpen = false;
boolean refToCell = false;

for (int i = 0; i < cell.toCharArray().length; i++) {
char c = cell.toCharArray()[i];

// Check for "=" at the beginning of the cell value
if (i == 0 && c == '=')
continue;

if (refToCell) {
if (c != ' ') {
refValue += c;
} else {
refToCell = false;
subEntries.add(new SubEntry(refValue, SubEntryType.REFERENCE));
refValue = "";
}
} else if (quotesOpen == false) {
if (c == 'A') {
refToCell = true;
if (intSubEntry != "" || strSubEntry != "") {
subEntries.add(new SubEntry(ERROR_TAG, SubEntryType.ERROR));
intSubEntry = "";
strSubEntry = "";
}
} else if (c != '\'') {
intSubEntry += c;
} else {
if (intSubEntry != "")
subEntries.add(new SubEntry(intSubEntry, SubEntryType.NUMBER));
intSubEntry = "";
quotesOpen = true;
}
} else {
if (c != '\'') {
strSubEntry += c;
} else {
subEntries.add(new SubEntry(strSubEntry, SubEntryType.STRING));
strSubEntry = "";
quotesOpen = false;
}
}
}
if (intSubEntry != "")
subEntries.add(new SubEntry(intSubEntry, SubEntryType.NUMBER));
if (strSubEntry != "")
subEntries.add(new SubEntry(ERROR_TAG, SubEntryType.ERROR));
if (refToCell == true) {
if (refValue != "")
subEntries.add(new SubEntry(refValue, SubEntryType.REFERENCE));
else
subEntries.add(new SubEntry(ERROR_TAG, SubEntryType.ERROR));
}

return subEntries;
}

public boolean isNum(String s) {
try {
Integer.valueOf(s);
} catch (NumberFormatException ex) {
return false;
}
return true;
}

}
27 changes: 27 additions & 0 deletions src/SubEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

public class SubEntry {
private String value;
private SubEntryType type;

public SubEntry(String value, SubEntryType type) {
this.value = value;
this.type = type;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

public SubEntryType getType() {
return type;
}

public void setType(SubEntryType type) {
this.type = type;
}

}
4 changes: 4 additions & 0 deletions src/SubEntryType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

public enum SubEntryType {
NUMBER, STRING, REFERENCE, ERROR
}
114 changes: 110 additions & 4 deletions tests/SpreadsheetTest.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,121 @@
import static org.junit.Assert.*;

import java.util.List;

import org.junit.Test;


public class SpreadsheetTest {
private static final String CIRCULAR_TAG = "#Circular";
private static final String ERROR_TAG = "#Error";
Spreadsheet spreadSheet = new Spreadsheet();

@Test
public void test() {
fail("Not yet implemented");


/*
* 1
*/

@Test public void testSpreadsheet_SetA1_1_GetA1_String_1() {
spreadSheet.set("A1", "1");
assertEquals("1", spreadSheet.get("A1"));
}


/*
* 2
*/

@Test public void testSpreadsheet_SetA1_1_EvalA1_String_1() {
spreadSheet.set("A1", "1");
assertEquals("1", spreadSheet.evaluate("A1"));
}


/*
* 3
*/

@Test public void testSpreadsheet_SetA1_A5_EvalA1_ErrorString() {
spreadSheet.set("A1", "5A");
assertEquals(ERROR_TAG, spreadSheet.evaluate("A1"));
}


/*
* 4
*/

@Test public void testSpreadsheet_SetA1_String_EvalA1_StringWithoutQuotes() {
spreadSheet.set("A1", "'a string'");
assertEquals("a string", spreadSheet.evaluate("A1"));
}


/*
* 5
*/

@Test public void testSpreadsheet_SetA1WrongQuotedString_EvalA1_Error() {
spreadSheet.set("A1", "'a string");
assertEquals(ERROR_TAG, spreadSheet.evaluate("A1"));
}


/*
* 6
*/

@Test public void testSpreadSheet_SetA1_EqualSignBeforeString_EvalA1_OnlyString() {
spreadSheet.set("A1", "='a string'");
assertEquals("a string", spreadSheet.evaluate("A1"));
}


/*
* 7
*/

@Test public void testSpreadsheet_SetA1_EqualSignAndWrongQuotedString_EvalA1_Error() {
spreadSheet.set("A1", "='a string");
assertEquals(ERROR_TAG, spreadSheet.evaluate("A1"));
}


/*
* 8
*/

@Test public void testSpreadSheet_createOneSubEntryWithReference_TypeOfSubEntry_REFERENCE() {
List<SubEntry> subEntries = spreadSheet.createSubEntries("=A5");
assertEquals(SubEntryType.REFERENCE, subEntries.get(0).getType());
}

@Test public void testSpreadSheet_Set_A5_5_And_A1_EqualA5_EvalA1_5() {
spreadSheet.set("A5", "5");
spreadSheet.set("A1", "=A5");
assertEquals("5", spreadSheet.evaluate("A1"));
}


/*
* 9
*/

@Test public void testSpreadSheet_Set_A5_5A_And_A1_EqualA5_EvalA1_Error() {
spreadSheet.set("A5", "5A");
spreadSheet.set("A1", "=A5");
assertEquals(ERROR_TAG, spreadSheet.evaluate("A1"));
}


/*
* 10
*/

@Test public void testSpreadSheet_Set_A5_EqualA1_And_A1_EqualA5_EvalA1_CircularTag() {
spreadSheet.set("A5", "=A1");
spreadSheet.set("A1", "=A5");
assertEquals(CIRCULAR_TAG, spreadSheet.evaluate("A1"));
}

}