more massaging, also tweak Table accessors for types

This commit is contained in:
Ben Fry
2013-04-28 14:55:12 -04:00
parent c7702c9b61
commit 7ac6a0bd79
7 changed files with 178 additions and 80 deletions
+17 -17
View File
@@ -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);
}
+5 -11
View File
@@ -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);
}
+50
View File
@@ -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,
+1 -1
View File
@@ -611,7 +611,7 @@ public class StringList implements Iterable<String> {
public IntHash getTally() {
IntHash outgoing = new IntHash();
for (int i = 0; i < count; i++) {
outgoing.inc(data[i]);
outgoing.increment(data[i]);
}
return outgoing;
}
+64 -50
View File
@@ -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?
// <p>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.</p>
// attempt at a CSV spec: http://tools.ietf.org/html/rfc4180
/**
* <p>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.</p>
* <p>File names should end with .csv if they're comma separated.</p>
* <p>A rough "spec" for CSV can be found <a href="http://tools.ietf.org/html/rfc4180">here</a>.</p>
*
* @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<TableRow> createIterator(final ResultSet rs) {
return new Iterator<TableRow>() {
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;
+2
View File
@@ -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);
}
+39 -1
View File
@@ -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?
// <p>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.</p>
// 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