From d28ecd79ee53ef5d4ca4feab682e08ca0c959240 Mon Sep 17 00:00:00 2001 From: Ben Fry Date: Fri, 2 Aug 2013 09:40:20 -0400 Subject: [PATCH] fix up getPercentages() -> getPercent()... also add sort() to Table --- core/src/processing/data/FloatDict.java | 5 +- core/src/processing/data/FloatList.java | 20 ++++ core/src/processing/data/IntDict.java | 4 +- core/src/processing/data/IntList.java | 35 +++++++ core/src/processing/data/Table.java | 122 +++++++++++++++++++++++- core/todo.txt | 1 + 6 files changed, 183 insertions(+), 4 deletions(-) diff --git a/core/src/processing/data/FloatDict.java b/core/src/processing/data/FloatDict.java index e725d4806..91b2b7538 100644 --- a/core/src/processing/data/FloatDict.java +++ b/core/src/processing/data/FloatDict.java @@ -427,6 +427,7 @@ public class FloatDict { * @webref floatlist:method * @brief Return the largest value */ + // The index of the entry that has the max value. Reference above is incorrect. public int maxIndex() { checkMinMax("maxIndex"); // Will still return NaN if there is 1 or more entries, and they're all NaN @@ -453,12 +454,14 @@ public class FloatDict { } + /** The key for a max value. */ public String maxKey() { checkMinMax("maxKey"); return keys[maxIndex()]; } + /** The max value. */ public float maxValue() { checkMinMax("maxValue"); return values[maxIndex()]; @@ -685,7 +688,7 @@ public class FloatDict { * each key, divided by the total sum. The total for all values will be ~1.0. * @return a Dict with the original keys, mapped to their pct of the total */ - public FloatDict getPercentages() { + public FloatDict getPercent() { double sum = 0; for (float value : valueArray()) { sum += value; diff --git a/core/src/processing/data/FloatList.java b/core/src/processing/data/FloatList.java index 92a3c160b..97404d98e 100644 --- a/core/src/processing/data/FloatList.java +++ b/core/src/processing/data/FloatList.java @@ -708,6 +708,26 @@ public class FloatList implements Iterable { } + /** + * Returns a normalized version of this array. Called getPercent() for + * consistency with the Dict classes. It's a getter method because it needs + * to returns a new list (because IntList/Dict can't do percentages or + * normalization in place on int values). + */ + public FloatList getPercent() { + double sum = 0; + for (float value : array()) { + sum += value; + } + FloatList outgoing = new FloatList(count); + for (int i = 0; i < count; i++) { + double percent = data[i] / sum; + outgoing.set(i, (float) percent); + } + return outgoing; + } + + public FloatList getSubset(int start) { return getSubset(start, count - start); } diff --git a/core/src/processing/data/IntDict.java b/core/src/processing/data/IntDict.java index d812d76d0..4cc3d927f 100644 --- a/core/src/processing/data/IntDict.java +++ b/core/src/processing/data/IntDict.java @@ -470,7 +470,7 @@ public class IntDict { } - // return the key for the maximum value + // return the key corresponding to the maximum value public String maxKey() { checkMinMax("maxKey"); return keys[maxIndex()]; @@ -626,7 +626,7 @@ public class IntDict { * each key, divided by the total sum. The total for all values will be ~1.0. * @return a Dict with the original keys, mapped to their pct of the total */ - public FloatDict getPercentages() { + public FloatDict getPercent() { double sum = 0; for (int value : valueArray()) { sum += value; diff --git a/core/src/processing/data/IntList.java b/core/src/processing/data/IntList.java index 0a1fd6b26..a2a577214 100644 --- a/core/src/processing/data/IntList.java +++ b/core/src/processing/data/IntList.java @@ -60,6 +60,21 @@ public class IntList implements Iterable { } + static public IntList fromRange(int stop) { + return fromRange(0, stop); + } + + + static public IntList fromRange(int start, int stop) { + int count = stop - start; + IntList newbie = new IntList(count); + for (int i = 0; i < count; i++) { + newbie.set(i, start+i); + } + return newbie; + } + + /** * Improve efficiency by removing allocated but unused entries from the * internal array used to store the data. Set to private, though it could @@ -698,6 +713,26 @@ public class IntList implements Iterable { // } + /** + * Returns a normalized version of this array. Called getPercent() for + * consistency with the Dict classes. It's a getter method because it needs + * to returns a new list (because IntList/Dict can't do percentages or + * normalization in place on int values). + */ + public FloatList getPercent() { + double sum = 0; + for (float value : array()) { + sum += value; + } + FloatList outgoing = new FloatList(count); + for (int i = 0; i < count; i++) { + double percent = data[i] / sum; + outgoing.set(i, (float) percent); + } + return outgoing; + } + + public IntList getSubset(int start) { return getSubset(start, count - start); } diff --git a/core/src/processing/data/Table.java b/core/src/processing/data/Table.java index d85b896c8..744c98f7f 100644 --- a/core/src/processing/data/Table.java +++ b/core/src/processing/data/Table.java @@ -91,6 +91,10 @@ public class Table { protected RowIterator rowIterator; + // 0 for doubling each time, otherwise the number of rows to increment on + // each expansion. + protected int expandIncrement; + /** * Creates a new, empty table. Use addRow() to add additional rows. @@ -1707,6 +1711,7 @@ public class Table { return getRowCount() - 1; } + /** * @webref table:method * @brief Removes all rows from a table @@ -1749,6 +1754,7 @@ public class Table { rowCount = newCount; } + /** * @webref table:method * @brief Adds a row to a table @@ -1760,6 +1766,7 @@ public class Table { return new RowPointer(this, rowCount - 1); } + /** * @param source a reference to the original row to be duplicated */ @@ -1793,6 +1800,7 @@ public class Table { return new RowPointer(this, row); } + /** * @nowebref */ @@ -3580,7 +3588,119 @@ public class Table { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - // TODO maybe these aren't needed. better to use getStringList().getUnique()? + public void sort(String columnName) { + sort(getColumnIndex(columnName), false); + } + + + public void sort(int column) { + sort(column, false); + } + + + public void sortReverse(String columnName) { + sort(getColumnIndex(columnName), true); + } + + + public void sortReverse(int column) { + sort(column, true); + } + + + protected void sort(final int column, final boolean reverse) { + final int[] order = IntList.fromRange(getRowCount()).array(); + Sort s = new Sort() { + + @Override + public int size() { + return getRowCount(); + } + + @Override + public float compare(int index1, int index2) { + int a = reverse ? order[index2] : order[index1]; + int b = reverse ? order[index1] : order[index2]; + + switch (getColumnType(column)) { + case INT: + return getInt(a, column) - getInt(b, column); + case LONG: + return getLong(a, column) - getLong(b, column); + case FLOAT: + return getFloat(a, column) - getFloat(b, column); + case DOUBLE: + return (float) (getDouble(a, column) - getDouble(b, column)); + case STRING: + return getString(a, column).compareToIgnoreCase(getString(b, column)); + case CATEGORY: + return getInt(a, column) - getInt(b, column); + default: + throw new IllegalArgumentException("Invalid column type: " + getColumnType(column)); + } + } + + @Override + public void swap(int a, int b) { + int temp = order[a]; + order[a] = order[b]; + order[b] = temp; + } + + }; + s.run(); + + //Object[] newColumns = new Object[getColumnCount()]; + for (int col = 0; col < getColumnCount(); col++) { + switch (getColumnType(col)) { + case INT: + case CATEGORY: + int[] oldInt = (int[]) columns[col]; + int[] newInt = new int[rowCount]; + for (int row = 0; row < getRowCount(); row++) { + newInt[row] = oldInt[order[row]]; + } + columns[col] = newInt; + break; + case LONG: + long[] oldLong = (long[]) columns[col]; + long[] newLong = new long[rowCount]; + for (int row = 0; row < getRowCount(); row++) { + newLong[row] = oldLong[order[row]]; + } + columns[col] = newLong; + break; + case FLOAT: + float[] oldFloat = (float[]) columns[col]; + float[] newFloat = new float[rowCount]; + for (int row = 0; row < getRowCount(); row++) { + newFloat[row] = oldFloat[order[row]]; + } + columns[col] = newFloat; + break; + case DOUBLE: + double[] oldDouble = (double[]) columns[col]; + double[] newDouble = new double[rowCount]; + for (int row = 0; row < getRowCount(); row++) { + newDouble[row] = oldDouble[order[row]]; + } + columns[col] = newDouble; + break; + case STRING: + String[] oldString = (String[]) columns[col]; + String[] newString = new String[rowCount]; + for (int row = 0; row < getRowCount(); row++) { + newString[row] = oldString[order[row]]; + } + columns[col] = newString; + break; + } + } + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + public String[] getUnique(String columnName) { return getUnique(getColumnIndex(columnName)); diff --git a/core/todo.txt b/core/todo.txt index c30d98b88..177e004c5 100644 --- a/core/todo.txt +++ b/core/todo.txt @@ -28,6 +28,7 @@ _ Unable to get TAB key event with P2D/P3D renderer _ https://github.com/processing/processing/issues/1967 table +X add sort() to Table _ implement version of Table that takes a dictionary file _ addRow() is not efficient, probably need to do the doubling _ or have a setIncrement() function?