Wednesday, July 18, 2012

Just had to create a median function in Python. We compute median values by ordering them and choosing the middle one. I found a routine, but it lacked unittest coverage and the edge case of an empty input array. So, here goes:
import unittest
###############################################################################

def getMedian(numericValues):
    
    theValues = sorted(numericValues)
    if not theValues:
        return None
    
    if len(theValues) % 2 == 1:
        return theValues[(len(theValues)+1)/2-1]
    else:
        lower = theValues[len(theValues)/2-1]
        upper = theValues[len(theValues)/2]
  
        return (float(lower + upper)) / 2  

###############################################################################

if __name__ == '__main__':
    unittest.main()

###############################################################################

class TestCommonUtils(unittest.TestCase):

    def test_trivial(self):
        return True

    def isValid(self, functionName, valueShouldBe, valueIs):
        assert (valueShouldBe == valueIs), "ERROR: Function %s returned value %.6fs, but value should be: %.6f." % (functionName, valueIs, valueShouldBe)  

    def test_getMedian(self):
        self.isValid('getMedian', 2.5,      getMedian([0,1,2,3,4,5]))
        self.isValid('getMedian', 2,        getMedian([0,1,2,3,4]))
        self.isValid('getMedian', 2,        getMedian([3,1,2]))
        self.isValid('getMedian', 3,        getMedian([3,2,3]))
        self.isValid('getMedian', 1.234,    getMedian([1.234, 3.678, -2.467]))
        self.isValid('getMedian', 1.345,    getMedian([1.234, 3.678, 1.456, -2.467]))
        self.isValid('getMedian', 3,        getMedian([3]))
        self.isValid('getMedian', None,     getMedian([]))


$ nosetests util.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

No comments: