You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by kr...@apache.org on 2019/10/16 13:19:20 UTC
[knox] branch master updated: KNOX-2052 - KnoxShellTable mean,
median, and mode methods (#163)
This is an automated email from the ASF dual-hosted git repository.
krisden pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new 04f5d86 KNOX-2052 - KnoxShellTable mean, median, and mode methods (#163)
04f5d86 is described below
commit 04f5d86a0caa466755d287827e2b783f5896099f
Author: Larry McCay IV <46...@users.noreply.github.com>
AuthorDate: Wed Oct 16 09:19:12 2019 -0400
KNOX-2052 - KnoxShellTable mean, median, and mode methods (#163)
---
gateway-shell/pom.xml | 4 +
.../knox/gateway/shell/table/KnoxShellTable.java | 179 ++++++++++++++++++++-
.../gateway/shell/table/KnoxShellTableTest.java | 150 +++++++++++++++++
pom.xml | 6 +
4 files changed, 337 insertions(+), 2 deletions(-)
diff --git a/gateway-shell/pom.xml b/gateway-shell/pom.xml
index 61e61d4..4f57b71 100644
--- a/gateway-shell/pom.xml
+++ b/gateway-shell/pom.xml
@@ -95,6 +95,10 @@
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-math3</artifactId>
+ </dependency>
+ <dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
diff --git a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/table/KnoxShellTable.java b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/table/KnoxShellTable.java
index 00b47cc..0f8da20 100644
--- a/gateway-shell/src/main/java/org/apache/knox/gateway/shell/table/KnoxShellTable.java
+++ b/gateway-shell/src/main/java/org/apache/knox/gateway/shell/table/KnoxShellTable.java
@@ -24,8 +24,8 @@ import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.SortOrder;
-
import com.fasterxml.jackson.annotation.JsonFilter;
+import org.apache.commons.math3.stat.StatUtils;
/**
@@ -35,6 +35,16 @@ import com.fasterxml.jackson.annotation.JsonFilter;
*/
@JsonFilter("knoxShellTableFilter")
public class KnoxShellTable {
+
+ private enum Conversions {
+ DOUBLE,
+ INTEGER,
+ FLOAT,
+ BYTE,
+ SHORT,
+ LONG
+ }
+
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
List<String> headers = new ArrayList<String>();
@@ -86,6 +96,172 @@ public class KnoxShellTable {
return col;
}
+ private Conversions getConversion(Comparable<? extends Object> colIndex) {
+ Conversions type = null;
+ if (colIndex instanceof Double) {
+ type = Conversions.DOUBLE;
+ }
+ else if (colIndex instanceof Integer) {
+ type = Conversions.INTEGER;
+ }
+ else if (colIndex instanceof Float) {
+ type = Conversions.FLOAT;
+ }
+ else if (colIndex instanceof Byte) {
+ type = Conversions.BYTE;
+ }
+ else if (colIndex instanceof Short) {
+ type = Conversions.SHORT;
+ }
+ else if (colIndex instanceof Long) {
+ type = Conversions.LONG;
+ }
+ else {
+ throw new IllegalArgumentException();
+ }
+ return type;
+ }
+
+ private double[] toDoubleArray(String colName) throws IllegalArgumentException {
+ List<Comparable<? extends Object>> col = values(colName);
+ double[] colArray = new double[col.size()];
+ Conversions conversionMethod = null;
+ for (int i = 0; i < col.size(); i++) {
+ if (i == 0) {
+ conversionMethod = getConversion(col.get(i));
+ }
+ switch (conversionMethod) {
+ case DOUBLE:
+ colArray[i] = (double) ((Double) col.get(i));
+ break;
+ case INTEGER:
+ colArray[i] = (double) ((Integer) col.get(i)).intValue();
+ break;
+ case FLOAT:
+ colArray[i] = (double) ((Float) col.get(i)).floatValue();
+ break;
+ case BYTE:
+ colArray[i] = (double) ((Byte) col.get(i)).byteValue();
+ break;
+ case SHORT:
+ colArray[i] = (double) ((Short) col.get(i)).shortValue();
+ break;
+ case LONG:
+ colArray[i] = (double) ((Long) col.get(i)).longValue();
+ break;
+ }
+ }
+ return colArray;
+ }
+
+ /**
+ * Calculates the mean of specified column
+ * @param colName
+ * @return mean
+ */
+ public double mean(String colName) {
+ return StatUtils.mean(toDoubleArray(colName));
+ }
+
+ /**
+ * Calculates the mean of specified column
+ * @param colName
+ * @return mean
+ */
+ public double mean(int colIndex) {
+ return mean(headers.get(colIndex));
+ }
+
+ /**
+ * Calculates the median of specified column
+ * @param colName
+ * @return median
+ */
+ public double median(String colName) {
+ return StatUtils.percentile(toDoubleArray(colName), 50);
+ }
+
+ /**
+ * Calculates the median of specified column
+ * @param colName
+ * @return median
+ */
+ public double median(int colIndex) {
+ return median(headers.get(colIndex));
+ }
+
+ /**
+ * Calculates the mode of specified column
+ * @param colName
+ * @return mode
+ */
+ public double mode(String colName) {
+ return (double) StatUtils.mode(toDoubleArray(colName))[0];
+ }
+
+ /**
+ * Calculates the mode of specified column
+ * @param colName
+ * @return mode
+ */
+ public double mode(int colIndex) {
+ return mode(headers.get(colIndex));
+ }
+
+ /**
+ * Calculates the sum of specified column
+ * @param colName
+ * @return sum
+ */
+ public double sum(String colName) {
+ return StatUtils.sum(toDoubleArray(colName));
+ }
+
+ /**
+ * Calculates the sum of specified column
+ * @param colName
+ * @return sum
+ */
+ public double sum(int colIndex) {
+ return sum(headers.get(colIndex));
+ }
+
+ /**
+ * Calculates the max of specified column
+ * @param colName
+ * @return max
+ */
+ public double max(String colName) {
+ return StatUtils.max(toDoubleArray(colName));
+ }
+
+ /**
+ * Calculates the max of specified column
+ * @param colName
+ * @return max
+ */
+ public double max(int colIndex) {
+ return max(headers.get(colIndex));
+ }
+
+ /**
+ * Calculates the min of specified column
+ * @param colName
+ * @return min
+ */
+ public double min(String colName) {
+ return StatUtils.min(toDoubleArray(colName));
+ }
+
+ /**
+ * Calculates the min of specified column
+ * @param colName
+ * @return min
+ */
+ public double min(int colIndex) {
+ return min(headers.get(colIndex));
+ }
+
public KnoxShellTable apply(KnoxShellTableCell<? extends Comparable<? extends Object>> cell) {
if (!headers.isEmpty()) {
headers.set(cell.colIndex, cell.header);
@@ -234,5 +410,4 @@ public class KnoxShellTable {
public String toCSV() {
return new KnoxShellTableRenderer(this).toCSV();
}
-
}
diff --git a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/table/KnoxShellTableTest.java b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/table/KnoxShellTableTest.java
index efb618f..65d7f4c 100644
--- a/gateway-shell/src/test/java/org/apache/knox/gateway/shell/table/KnoxShellTableTest.java
+++ b/gateway-shell/src/test/java/org/apache/knox/gateway/shell/table/KnoxShellTableTest.java
@@ -359,6 +359,156 @@ public class KnoxShellTableTest {
verify(connection, statement, resultSet, metadata);
}
+ @Test (expected = IllegalArgumentException.class)
+ public void testConversion() throws IllegalArgumentException {
+ KnoxShellTable TABLE = new KnoxShellTable();
+ TABLE.header("Column Integer").header("Column String").header("Column Null");
+ TABLE.row().value(10).value("John").value(null);
+
+ System.out.println(TABLE.mean("Column String"));
+ System.out.println(TABLE.mean("Column Null"));
+
+ }
+
+ @Test
+ public void testMean() throws Exception {
+
+ Byte byte10 = 10;
+ Byte byte20 = 20;
+ Byte byte30 = 30;
+
+ Short short10 = 10;
+ Short short20 = 20;
+ Short short30 = 30;
+
+ Long long10 = (long) 100000000;
+ Long long20 = (long) 200000000;
+ Long long30 = (long) 300000000;
+
+ KnoxShellTable TABLE = new KnoxShellTable();
+ TABLE.header("Column Integer").header("Column Double").header("Column Float").header("Column Byte").header("Column Short").header("Column Long");
+ TABLE.row().value(10).value(20d).value(20.9999).value(byte10).value(short10).value(long10);
+ TABLE.row().value(30).value(40d).value(40.9999).value(byte20).value(short20).value(long20);
+ TABLE.row().value(27).value(60d).value(60.9999).value(byte30).value(short30).value(long30);
+
+ assertEquals(22.3, TABLE.mean("Column Integer"), 0.1);
+ assertEquals(40, TABLE.mean("Column Double"), 0.1);
+ assertEquals(22.3, TABLE.mean(0), 0.1);
+ assertEquals(40, TABLE.mean(1), 0.1);
+ assertEquals(40.9999, TABLE.mean("Column Float"), 0.1);
+ assertEquals(40.9999, TABLE.mean(2), 0.1);
+ assertEquals(20, TABLE.mean("Column Byte"), 0.1);
+ assertEquals(20, TABLE.mean("Column Short"), 0.1);
+ assertEquals(2.0E8, TABLE.mean("Column Long"), 0.1);
+ }
+
+ @Test
+ public void testMedian() throws Exception {
+
+ KnoxShellTable TABLE = new KnoxShellTable();
+ TABLE.header("Column Integer").header("Column Double").header("Column Float");
+ TABLE.row().value(10).value(20d).value(40.9999);
+ assertEquals(10, TABLE.median("Column Integer"), 0.1);
+ assertEquals(10, TABLE.median(0), 0.1);
+ assertEquals(20, TABLE.median("Column Double"), 0.1);
+ assertEquals(20, TABLE.median(1), 0.1);
+ assertEquals(40.9999, TABLE.mean("Column Float"), 0.1);
+ assertEquals(40.9999, TABLE.mean(2), 0.1);
+
+ KnoxShellTable TABLE2 = new KnoxShellTable();
+ TABLE2.header("Column Integer").header("Column Double").header("Column Float");
+ TABLE2.row().value(10).value(20d).value(20.9999);
+ TABLE2.row().value(30).value(40d).value(40.9999);
+ TABLE2.row().value(50).value(41d).value(60.9999);
+ assertEquals(30, TABLE2.median("Column Integer"), 0.1);
+ assertEquals(30, TABLE2.median(0), 0.1);
+ assertEquals(40.9999, TABLE2.mean("Column Float"), 0.1);
+ assertEquals(40.9999, TABLE2.mean(2), 0.1);
+
+ KnoxShellTable TABLE3 = new KnoxShellTable();
+ TABLE3.header("Column Integer").header("Column Double").header("Column Float");
+ TABLE3.row().value(10).value(20d).value(0.0000);
+ TABLE3.row().value(30).value(40d).value(30.0000);
+ TABLE3.row().value(31).value(41d).value(31.0000);
+ TABLE3.row().value(50).value(60d).value(70.0000);
+ assertEquals(30.5, TABLE3.median("Column Integer"), 0.1);
+ assertEquals(30.5, TABLE3.median(0), 0.01);
+ assertEquals(40.5, TABLE3.median("Column Double"), 0.01);
+ assertEquals(40.5, TABLE3.median(1), 0.01);
+ assertEquals(30.5000, TABLE3.median("Column Float"), 0.1);
+ assertEquals(30.5000, TABLE3.median(2), 0.1);
+ }
+
+ @Test
+ public void testMode() throws Exception {
+
+ KnoxShellTable TABLE = new KnoxShellTable();
+ TABLE.header("Column Integer").header("Column Double").header("Column Float");
+ TABLE.row().value(10).value(20d).value(40.9999);
+ assertEquals(10, TABLE.mode("Column Integer"), 0.1);
+ assertEquals(10, TABLE.mode(0), 0.1);
+ assertEquals(40.9999, TABLE.mean("Column Float"), 0.1);
+ assertEquals(40.9999, TABLE.mean(2), 0.1);
+
+
+ KnoxShellTable TABLE2 = new KnoxShellTable();
+ TABLE2.header("Column Integer").header("Column Double").header("Column Float");
+ TABLE2.row().value(10).value(20d).value(20.9999);
+ TABLE2.row().value(30).value(40d).value(20.9999);
+ TABLE2.row().value(30).value(40d).value(30.9999);
+ assertEquals(30, TABLE2.median("Column Integer"), 0.1);
+ assertEquals(30, TABLE2.median(0), 0.1);
+ assertEquals(40, TABLE2.median("Column Double"), 0.1);
+ assertEquals(40, TABLE2.median(1), 0.1);
+ assertEquals(20.9999, TABLE2.median("Column Float"), 0.1);
+ assertEquals(20.9999, TABLE2.median(2), 0.1);
+ }
+
+ @Test
+ public void testSum() throws Exception {
+
+ KnoxShellTable TABLE = new KnoxShellTable();
+ TABLE.header("Column Integer").header("Column Double").header("Column Float");
+ TABLE.row().value(10).value(20d).value(20.5000);
+ TABLE.row().value(90).value(100d).value(20.0500);
+ assertEquals(100, TABLE.sum("Column Integer"), 0.1);
+ assertEquals(100, TABLE.sum(0), 0.1);
+ assertEquals(120, TABLE.sum("Column Double"), 0.1);
+ assertEquals(120, TABLE.sum(1), 0.1);
+ assertEquals(40.5500, TABLE.sum("Column Float"), 0.1);
+ assertEquals(40.5500, TABLE.sum(2), 0.1);
+ }
+
+ @Test
+ public void testMax() throws Exception {
+
+ KnoxShellTable TABLE = new KnoxShellTable();
+ TABLE.header("Column Integer").header("Column Double").header("Column Float");
+ TABLE.row().value(10).value(20d).value(30.9998);
+ TABLE.row().value(20).value(50d).value(30.9999);
+ assertEquals(20, TABLE.max("Column Integer"), 0.1);
+ assertEquals(20, TABLE.max(0), 0.1);
+ assertEquals(50, TABLE.max("Column Double"), 0.1);
+ assertEquals(50, TABLE.max(1), 0.1);
+ assertEquals(30.9999, TABLE.max("Column Float"), 0.1);
+ assertEquals(30.9999, TABLE.max(2), 0.1);
+ }
+
+ @Test
+ public void testMin() throws Exception {
+
+ KnoxShellTable TABLE = new KnoxShellTable();
+ TABLE.header("Column Integer").header("Column Double").header("Column Float");
+ TABLE.row().value(10).value(20d).value(20.9998);
+ TABLE.row().value(20).value(50d).value(20.9999);
+ assertEquals(10, TABLE.min("Column Integer"), 0.1);
+ assertEquals(10, TABLE.min(0), 0.1);
+ assertEquals(20, TABLE.min("Column Double"), 0.1);
+ assertEquals(20, TABLE.min(1), 0.1);
+ assertEquals(20.9998, TABLE.min("Column Float"), 0.1);
+ assertEquals(20.9998, TABLE.min(2), 0.1);
+ }
+
@Test
public void shouldReturnDifferentCallHistoryForDifferentTables() throws Exception {
final KnoxShellTable table1 = new KnoxShellTable();
diff --git a/pom.xml b/pom.xml
index ea91d30..c0ef103 100644
--- a/pom.xml
+++ b/pom.xml
@@ -166,6 +166,7 @@
<commons-digester3.version>3.2</commons-digester3.version>
<commons-io.version>2.6</commons-io.version>
<commons-lang3.version>3.9</commons-lang3.version>
+ <commons-math3.version>3.6.1</commons-math3.version>
<commons-net.version>3.6</commons-net.version>
<commons-text.version>1.8</commons-text.version>
<cors-filter.version>2.8</cors-filter.version>
@@ -1544,6 +1545,11 @@
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-math3</artifactId>
+ <version>${commons-math3.version}</version>
+ </dependency>
+ <dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>${commons-net.version}</version>