diff --git a/core/src/processing/data/FloatHash.java b/core/src/processing/data/FloatHash.java index 96c5c0c85..b4183e06b 100644 --- a/core/src/processing/data/FloatHash.java +++ b/core/src/processing/data/FloatHash.java @@ -246,19 +246,19 @@ public class FloatHash { } - /** Increase the value of a specific key by 1. */ - public void inc(String key) { - inc(key, 1); -// int index = index(key); -// if (index == -1) { -// create(key, 1); -// } else { -// values[index]++; -// } - } +// /** Increase the value of a specific key by 1. */ +// public void inc(String key) { +// inc(key, 1); +//// int index = index(key); +//// if (index == -1) { +//// create(key, 1); +//// } else { +//// values[index]++; +//// } +// } - public void inc(String key, float amount) { + public void add(String key, float amount) { int index = index(key); if (index == -1) { create(key, amount); @@ -268,14 +268,14 @@ public class FloatHash { } - /** Decrease the value of a key by 1. */ - public void dec(String key) { - inc(key, -1); - } +// /** Decrease the value of a key by 1. */ +// public void dec(String key) { +// inc(key, -1); +// } - public void dec(String key, float amount) { - inc(key, -amount); + public void sub(String key, float amount) { + add(key, -amount); } diff --git a/core/src/processing/data/IntHash.java b/core/src/processing/data/IntHash.java index 16c8e4123..936b73ffa 100644 --- a/core/src/processing/data/IntHash.java +++ b/core/src/processing/data/IntHash.java @@ -236,12 +236,12 @@ public class IntHash { /** Increase the value of a specific key by 1. */ - public void inc(String key) { - inc(key, 1); + public void increment(String key) { + add(key, 1); } - public void inc(String key, int amount) { + public void add(String key, int amount) { int index = index(key); if (index == -1) { create(key, amount); @@ -251,14 +251,8 @@ public class IntHash { } - /** Decrease the value of a key by 1. */ - public void dec(String key) { - inc(key, -1); - } - - - public void dec(String key, int amount) { - inc(key, -amount); + public void sub(String key, int amount) { + add(key, -amount); } diff --git a/core/src/processing/data/JSONArray.java b/core/src/processing/data/JSONArray.java index 5955bd4fd..ba7555f04 100644 --- a/core/src/processing/data/JSONArray.java +++ b/core/src/processing/data/JSONArray.java @@ -392,6 +392,56 @@ public class JSONArray { } + /** Get this entire array as an int array. Everything must be an int. */ + public int[] getIntArray() { + int[] outgoing = new int[size()]; + for (int i = 0; i < size(); i++) { + outgoing[i] = getInt(i); + } + return outgoing; + } + + + /** Get this entire array as a long array. Everything must be an long. */ + public long[] getLongArray() { + long[] outgoing = new long[size()]; + for (int i = 0; i < size(); i++) { + outgoing[i] = getLong(i); + } + return outgoing; + } + + + /** Get this entire array as a float array. Everything must be an float. */ + public float[] getFloatArray() { + float[] outgoing = new float[size()]; + for (int i = 0; i < size(); i++) { + outgoing[i] = getFloat(i); + } + return outgoing; + } + + + /** Get this entire array as a double array. Everything must be an double. */ + public double[] getDoubleArray() { + double[] outgoing = new double[size()]; + for (int i = 0; i < size(); i++) { + outgoing[i] = getDouble(i); + } + return outgoing; + } + + + /** Get this entire array as a boolean array. Everything must be a boolean. */ + public boolean[] getBooleanArray() { + boolean[] outgoing = new boolean[size()]; + for (int i = 0; i < size(); i++) { + outgoing[i] = getBoolean(i); + } + return outgoing; + } + + // /** // * Get the optional boolean value associated with an index. // * It returns false if there is no value at that index, diff --git a/core/src/processing/data/StringList.java b/core/src/processing/data/StringList.java index 3bee3f82b..284361a87 100644 --- a/core/src/processing/data/StringList.java +++ b/core/src/processing/data/StringList.java @@ -611,7 +611,7 @@ public class StringList implements Iterable { public IntHash getTally() { IntHash outgoing = new IntHash(); for (int i = 0; i < count; i++) { - outgoing.inc(data[i]); + outgoing.increment(data[i]); } return outgoing; } diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index e6960ffb2..15ca6c838 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -3,7 +3,7 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2011-12 Ben Fry and Casey Reas + Copyright (c) 2011-13 Ben Fry and Casey Reas Copyright (c) 2006-11 Ben Fry This library is free software; you can redistribute it and/or @@ -36,26 +36,6 @@ import java.util.concurrent.Executors; import processing.core.PApplet; import processing.core.PConstants; -// function that will convert awful CSV to TSV.. or something else? -// maybe to write binary instead? then read the binary file once it's ok? - -// if loading from a File object (or PApplet is passed in and we can check online) -// then check the (probable) size of the file before loading - -// implement binary tables - -// no column max/min functions since it needs to be per-datatype -// better to use float mx = max(float(getColumn(3))); -// *** but what to do with null entries? - -// todo: need a method to reset the row/column indices after add/remove -// or just make sure that it's covered for all cases - -// no longer the case, ja? -//

By default, empty rows are skipped and so are lines that start with the -// # character. Using # at the beginning of a line indicates a comment.

- -// attempt at a CSV spec: http://tools.ietf.org/html/rfc4180 /** *

Generic class for handling tabular data, typically from a CSV, TSV, or @@ -65,6 +45,7 @@ import processing.core.PConstants; * often with the data in quotes. TSV files use tabs as separators, and usually * don't bother with the quotes.

*

File names should end with .csv if they're comma separated.

+ *

A rough "spec" for CSV can be found here.

* * @webref data:composite * @see PApplet#createTable() @@ -93,12 +74,13 @@ public class Table { protected Object[] columns; // [column] - static final int STRING = 0; - static final int INT = 1; - static final int LONG = 2; - static final int FLOAT = 3; - static final int DOUBLE = 4; - static final int CATEGORICAL = 5; + // accessible for advanced users + static public final int STRING = 0; + static public final int INT = 1; + static public final int LONG = 2; + static public final int FLOAT = 3; + static public final int DOUBLE = 4; + static public final int CATEGORY = 5; int[] columnTypes; protected RowIterator rowIterator; @@ -846,7 +828,7 @@ public class Table { } for (int i = 0; i < getColumnCount(); i++) { - if (columnTypes[i] == CATEGORICAL) { + if (columnTypes[i] == CATEGORY) { columnCategories[i].write(output); } } @@ -880,7 +862,7 @@ public class Table { case DOUBLE: output.writeDouble(row.getDouble(col)); break; - case CATEGORICAL: + case CATEGORY: output.writeInt(columnCategories[col].index(row.getString(col))); break; } @@ -931,7 +913,7 @@ public class Table { case STRING: columns[column] = new String[rowCount];; break; - case CATEGORICAL: + case CATEGORY: columns[column] = new int[rowCount];; break; default: @@ -940,7 +922,7 @@ public class Table { } for (int i = 0; i < columnCount; i++) { - if (columnTypes[i] == CATEGORICAL) { + if (columnTypes[i] == CATEGORY) { columnCategories[i] = new HashMapBlows(input); } } @@ -974,7 +956,7 @@ public class Table { case DOUBLE: setDouble(row, col, input.readDouble()); break; - case CATEGORICAL: + case CATEGORY: int index = input.readInt(); //String name = columnCategories[col].key(index); setInt(row, col, index); @@ -1008,7 +990,7 @@ public class Table { /** - * @param type the type to be used for the new column: INT, LONG, FLOAT, DOUBLE, STRING, or CATEGORICAL + * @param type the type to be used for the new column: INT, LONG, FLOAT, DOUBLE, STRING, or CATEGORY */ public void addColumn(String title, int type) { insertColumn(columns.length, title, type); @@ -1059,7 +1041,7 @@ public class Table { case FLOAT: columns[index] = new float[rowCount]; break; case DOUBLE: columns[index] = new double[rowCount]; break; case STRING: columns[index] = new String[rowCount]; break; - case CATEGORICAL: columns[index] = new int[rowCount]; break; + case CATEGORY: columns[index] = new int[rowCount]; break; } } @@ -1153,8 +1135,8 @@ public class Table { type = FLOAT; } else if (columnType.equals("double")) { type = DOUBLE; - } else if (columnType.equals("categorical")) { - type = CATEGORICAL; + } else if (columnType.equals("category")) { + type = CATEGORY; } else { throw new IllegalArgumentException("'" + columnType + "' is not a valid column type."); } @@ -1162,7 +1144,7 @@ public class Table { } - protected void setColumnType(String columnName, int newType) { + public void setColumnType(String columnName, int newType) { setColumnType(checkColumnIndex(columnName), newType); } @@ -1173,7 +1155,7 @@ public class Table { * @param column the column whose type should be changed * @param newType something fresh, maybe try an int or a float for size? */ - protected void setColumnType(int column, int newType) { + public void setColumnType(int column, int newType) { switch (newType) { case INT: { int[] intData = new int[rowCount]; @@ -1229,7 +1211,7 @@ public class Table { } break; } - case CATEGORICAL: { + case CATEGORY: { int[] indexData = new int[rowCount]; HashMapBlows categories = new HashMapBlows(); for (int row = 0; row < rowCount; row++) { @@ -1304,6 +1286,17 @@ public class Table { } + public int getColumnType(String columnName) { + return getColumnType(getColumnIndex(columnName)); + } + + + /** Returns one of Table.STRING, Table.INT, etc... */ + public int getColumnType(int column) { + return columnTypes[column]; + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -1437,7 +1430,7 @@ public class Table { case FLOAT: columns[col] = PApplet.expand((float[]) columns[col], newCount); break; case DOUBLE: columns[col] = PApplet.expand((double[]) columns[col], newCount); break; case STRING: columns[col] = PApplet.expand((String[]) columns[col], newCount); break; - case CATEGORICAL: columns[col] = PApplet.expand((int[]) columns[col], newCount); break; + case CATEGORY: columns[col] = PApplet.expand((int[]) columns[col], newCount); break; } if (newCount > 1000000) { try { @@ -1469,7 +1462,7 @@ public class Table { for (int col = 0; col < columns.length; col++) { switch (columnTypes[col]) { - case CATEGORICAL: + case CATEGORY: case INT: setInt(row, col, source.getInt(col)); break; @@ -1502,7 +1495,7 @@ public class Table { public void insertRow(int insert, Object[] columnData) { for (int col = 0; col < columns.length; col++) { switch (columnTypes[col]) { - case CATEGORICAL: + case CATEGORY: case INT: { int[] intTemp = new int[rowCount+1]; System.arraycopy(columns[col], 0, intTemp, 0, insert); @@ -1548,7 +1541,7 @@ public class Table { public void removeRow(int row) { for (int col = 0; col < columns.length; col++) { switch (columnTypes[col]) { - case CATEGORICAL: + case CATEGORY: case INT: { int[] intTemp = new int[rowCount-1]; // int[] intData = (int[]) columns[col]; @@ -1641,7 +1634,7 @@ public class Table { doubleData[row] = missingDouble; } break; - case CATEGORICAL: + case CATEGORY: int[] indexData = (int[]) columns[col]; indexData[row] = columnCategories[col].index(piece); break; @@ -1723,7 +1716,7 @@ public class Table { } } break; - case CATEGORICAL: + case CATEGORY: int[] indexData = (int[]) columns[col]; if (piece == null) { indexData[row] = missingCategory; @@ -1872,6 +1865,14 @@ public class Table { public int getColumnCount() { return table.getColumnCount(); } + + public int getColumnType(String columnName) { + return table.getColumnType(columnName); + } + + public int getColumnType(int column) { + return table.getColumnType(column); + } } @@ -1939,6 +1940,7 @@ public class Table { } + /* static public Iterator createIterator(final ResultSet rs) { return new Iterator() { boolean already; @@ -2068,6 +2070,17 @@ public class Table { return -1; } } + + + public int getColumnType(String columnName) { + // unimplemented + } + + + public int getColumnType(int column) { + // unimplemented + } + }; } @@ -2076,6 +2089,7 @@ public class Table { } }; } + */ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -2084,7 +2098,7 @@ public class Table { public int getInt(int row, int column) { checkBounds(row, column); if (columnTypes[column] == INT || - columnTypes[column] == CATEGORICAL) { + columnTypes[column] == CATEGORY) { int[] intData = (int[]) columns[column]; return intData[row]; } @@ -2111,7 +2125,7 @@ public class Table { } else { ensureBounds(row, column); if (columnTypes[column] != INT && - columnTypes[column] != CATEGORICAL) { + columnTypes[column] != CATEGORY) { throw new IllegalArgumentException("Column " + column + " is not an int column."); } int[] intData = (int[]) columns[column]; @@ -2446,7 +2460,7 @@ public class Table { if (columnTypes[col] == STRING) { String[] stringData = (String[]) columns[col]; return stringData[row]; - } else if (columnTypes[col] == CATEGORICAL) { + } else if (columnTypes[col] == CATEGORY) { int cat = getInt(row, col); if (cat == missingCategory) { return missingString; @@ -3335,7 +3349,7 @@ public class Table { output.writeDouble(missingDouble); } break; - case CATEGORICAL: + case CATEGORY: output.writeInt(columnCategories[col].index(pieces[col])); break; } @@ -3357,7 +3371,7 @@ public class Table { case DOUBLE: output.writeDouble(missingDouble); break; - case CATEGORICAL: + case CATEGORY: output.writeInt(missingCategory); break; diff --git a/core/src/processing/data/TableRow.java b/core/src/processing/data/TableRow.java index d1f731d2f..82b191a8e 100644 --- a/core/src/processing/data/TableRow.java +++ b/core/src/processing/data/TableRow.java @@ -25,4 +25,6 @@ public interface TableRow { public void setDouble(String columnName, double value); public int getColumnCount(); + public int getColumnType(String columnName); + public int getColumnType(int column); } diff --git a/core/todo.txt b/core/todo.txt index a0f5250f7..826334f56 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -10,6 +10,33 @@ X implement content specifiers X getIntContent() X getFloatContent() X getContent() or getStringContent()? +X switch to CATEGORY instead of CATEGORICAL + +table +X do we need getColumnType() inside TableRow? +X also inside Table +X also do we make the constants public? + +// function that will convert awful CSV to TSV.. or something else? +// maybe to write binary instead? then read the binary file once it's ok? + +// if loading from a File object (or PApplet is passed in and we can check online) +// then check the (probable) size of the file before loading + +// implement binary tables + +// no column max/min functions since it needs to be per-datatype +// better to use float mx = max(float(getColumn(3))); +// *** but what to do with null entries? + +// todo: need a method to reset the row/column indices after add/remove +// or just make sure that it's covered for all cases + +// no longer the case, ja? +//

By default, empty rows are skipped and so are lines that start with the +// # character. Using # at the beginning of a line indicates a comment.

+ +// attempt at a CSV spec: _ draw() called again before finishing on OS X (retina issue) _ https://github.com/processing/processing/issues/1709 @@ -32,6 +59,17 @@ setMissingXxxx() -> should this live in PApplet? be static? "hash.toJSONObject()" or "new JSONObject(hash)" +no save/load in hash and list classes + no native format +removeIndex() vs removeValue() vs remove() + remove() refers to an index (with array) or key (with hash) + more consistent with other APIs (Java) + replaceValue[s]() the same, though more on the line + should we not have remove() and removeIndex() + and instead always specify? removeKey(), removeIndex(), removeValue()? + would mean that hash would only have removeKey + downside: remove() takes whatever get() takes as arg + hash/dict/etc _ need to sort out the final version of these and their names _ JSONObject.has(key) vs XML.hasAttribute(attr) vs HashMap.containsKey() @@ -48,7 +86,7 @@ inc(), inc(amount) dec(), dec(amount) increment, decrement, increase, decrease instead of add/subtract does double duty for incrementing/decrementing easily -_ getIntArray() or toIntArray() (also for JSONArray) +X getIntArray() for JSONArray _ add indent= as option for XML, JSON save _ not doing print() methods, since alternatives are more descriptive _ println(obj) and obj.write(System.out) are both better