From 269ed8fbce0a51d0639623f5b680a1fbddc631d4 Mon Sep 17 00:00:00 2001
From: Tobias Schmidt <tobias.schmidt@unibas.ch>
Date: Wed, 23 May 2012 14:47:19 +0200
Subject: [PATCH] TableClass: allow computation of median, stdev, sum on bool
 type columns

---
 modules/base/pymod/table.py      | 22 +++++++++++-----------
 modules/base/tests/test_table.py | 18 ++++++++++++------
 2 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/modules/base/pymod/table.py b/modules/base/pymod/table.py
index 7f57dbc58..4bd1a9999 100644
--- a/modules/base/pymod/table.py
+++ b/modules/base/pymod/table.py
@@ -984,11 +984,11 @@ class Table(object):
     """
     Returns the sum of the given column. Cells with None are ignored. Returns 
     0.0, if the column doesn't contain any elements. Col must be of numeric
-    column type ('float', 'int').
+    column type ('float', 'int') or boolean column type.
     """
     idx = self.GetColIndex(col)
     col_type = self.col_types[idx]
-    if col_type!='int' and col_type!='float':
+    if col_type!='int' and col_type!='float' and col_type!='bool':
       raise TypeError("Sum can only be used on numeric column types")
     s = 0.0
     for r in self.rows:
@@ -1025,8 +1025,8 @@ class Table(object):
     containing the mean of all specified columns for each row.
     
     Cols are specified by their names and must be of numeric column
-    type ('float', 'int'). Cells with None are ignored. Adds None if the row
-    doesn't contain any values.
+    type ('float', 'int') or boolean column type.. Cells with None are ignored.
+    Adds None if the row doesn't contain any values.
     
     
     == Example ==
@@ -1065,7 +1065,7 @@ class Table(object):
     for col in cols:
       idx = self.GetColIndex(col)
       col_type = self.col_types[idx]
-      if col_type!='int' and col_type!='float':
+      if col_type!='int' and col_type!='float' and col_type!='bool':
         raise TypeError("RowMean can only be used on numeric column types")
       cols_idxs.append(idx)
       
@@ -1088,12 +1088,12 @@ class Table(object):
     """
     Returns the median of the given column. Cells with None are ignored. Returns 
     None, if the column doesn't contain any elements. Col must be of numeric
-    column type ('float', 'int').
+    column type ('float', 'int') or boolean column type.
     """
     idx = self.GetColIndex(col)
     col_type = self.col_types[idx]
-    if col_type!='int' and col_type!='float':
-      raise TypeError("Mean can only be used on numeric column types")
+    if col_type!='int' and col_type!='float' and col_type!='bool':
+      raise TypeError("Median can only be used on numeric column types")
     
     vals=[]
     for v in self[col]:
@@ -1109,12 +1109,12 @@ class Table(object):
     """
     Returns the standard deviation of the given column. Cells with None are
     ignored. Returns None, if the column doesn't contain any elements. Col must
-    be of numeric column type ('float', 'int').
+    be of numeric column type ('float', 'int') or boolean column type.
     """
     idx = self.GetColIndex(col)
     col_type = self.col_types[idx]
-    if col_type!='int' and col_type!='float':
-      raise TypeError("Mean can only be used on numeric column types")
+    if col_type!='int' and col_type!='float' and col_type!='bool':
+      raise TypeError("StdDev can only be used on numeric column types")
     
     vals=[]
     for v in self[col]:
diff --git a/modules/base/tests/test_table.py b/modules/base/tests/test_table.py
index 842f4d633..7b6b3be22 100644
--- a/modules/base/tests/test_table.py
+++ b/modules/base/tests/test_table.py
@@ -921,22 +921,26 @@ class TestTable(unittest.TestCase):
   def testSumTable(self):
     tab = self.CreateTestTable()
     tab.AddCol('fourth','bool',[False,True,False])
+    tab.AddCol('fifth','string',['foo','bar',None])
     
     self.assertRaises(TypeError,tab.Sum,'first')
     self.assertEquals(tab.Sum('second'),12)
     self.assertAlmostEquals(tab.Sum('third'),5.5)
-    self.assertRaises(TypeError,tab.Sum,'fourth')
-    self.assertRaises(ValueError,tab.Sum,'fifth')
+    self.assertEquals(tab.Sum('fourth'),1)
+    self.assertRaises(TypeError,tab.Sum,'fifth')
+    self.assertRaises(ValueError,tab.Sum,'sixth')
     
   def testMedianTable(self):
     tab = self.CreateTestTable()
     tab.AddCol('fourth','bool',[False,True,False])
+    tab.AddCol('fifth','string',['foo','bar',None])
     
     self.assertRaises(TypeError,tab.Median,'first')
     self.assertEquals(tab.Median('second'),6.0)
     self.assertAlmostEquals(tab.Median('third'),2.75)
-    self.assertRaises(TypeError,tab.Median,'fourth')
-    self.assertRaises(ValueError,tab.Median,'fifth')
+    self.assertEquals(tab.Median('fourth'),False)
+    self.assertRaises(TypeError,tab.Median,'fifth')
+    self.assertRaises(ValueError,tab.Median,'sixth')
     
   def testMeanTable(self):
     tab = self.CreateTestTable()
@@ -975,12 +979,14 @@ class TestTable(unittest.TestCase):
   def testStdDevTable(self):
     tab = self.CreateTestTable()
     tab.AddCol('fourth','bool',[False,True,False])
+    tab.AddCol('fifth','string',['foo','bar',None])
     
     self.assertRaises(TypeError,tab.StdDev,'first')
     self.assertAlmostEquals(tab.StdDev('second'),3.0)
     self.assertAlmostEquals(tab.StdDev('third'),0.55)
-    self.assertRaises(TypeError,tab.StdDev,'fourth')
-    self.assertRaises(ValueError,tab.StdDev,'fifth')
+    self.assertAlmostEquals(tab.StdDev('fourth'),0.47140452079)
+    self.assertRaises(TypeError,tab.StdDev,'fifth')
+    self.assertRaises(ValueError,tab.StdDev,'sixth')
     
   def testCountTable(self):
     tab = self.CreateTestTable()
-- 
GitLab