Skip to content

Commit

Permalink
Merge pull request #69 from pgdr/median-submission
Browse files Browse the repository at this point in the history
Median submission
  • Loading branch information
joakim-hove authored Oct 24, 2016
2 parents 4567c9b + 41133c2 commit 7223142
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 11 deletions.
9 changes: 4 additions & 5 deletions bin/fby_client
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class FbyRunner(object):
self._sample_time = 10 * 60
self._sleep_time = 0.50
self._exception_count = 0 # #exceptions since last success

self._accuracy = 4 # round observation to fourth digit

@staticmethod
def install(config):
Expand Down Expand Up @@ -83,9 +83,8 @@ class FbyRunner(object):


def post(self, client_pm10, client_pm25, data):
client_pm10.post( data[0].mean() )
client_pm25.post( data[1].mean() )

client_pm10.post( data[0].median() )
client_pm25.post( data[1].median() )

def run(self):
network_block( )
Expand All @@ -96,7 +95,7 @@ class FbyRunner(object):
device_id = config.getDeviceID( )
client_pm10 = FriskbyClient(config , "%s_PM10" % device_id, VAR_PATH)
client_pm25 = FriskbyClient(config , "%s_PM25" % device_id, VAR_PATH)
sampler = Sampler( SDS011(True) , self._sample_time , sleep_time = self._sleep_time )
sampler = Sampler( SDS011(True) , self._sample_time , sleep_time = self._sleep_time, accuracy = self._accuracy )

while True:
if self._exception_count >= 5:
Expand Down
5 changes: 3 additions & 2 deletions lib/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

class Sampler(object):

def __init__(self, reader, sample_time , sleep_time = 0.10):
def __init__(self, reader, sample_time , sleep_time = 0.10, accuracy = None):
self.reader = reader
self.sample_time = sample_time
self.sleep_time = sleep_time
self.accuracy = accuracy


def collect(self):
Expand All @@ -17,7 +18,7 @@ def collect(self):
values = self.reader.read( )
if len(data) == 0:
for x in range(len(values)):
data.append( TS() )
data.append( TS(accuracy=self.accuracy) )

for index,v in enumerate(values):
data[index].append( v )
Expand Down
53 changes: 49 additions & 4 deletions lib/ts.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,62 @@
class TS(object):
"""A class for representing time series.
Remarkably close to just being a list. But has mean() and median().
class TS(object):
Set accuracy = 3 to get rounding to third decimal.
"""

def __init__(self):
def __init__(self, data = None, accuracy=None):
self.data = []

self.accuracy = accuracy
if data:
for x in data:
self.append(x)

def __len__(self):
return len(self.data)

def __getitem__(self, idx):
return self.data[idx]


def append(self , d):
if self.accuracy:
d = round(d, self.accuracy)
self.data.append( d )

def __repr__(self):
return str(self)

def __str__(self):
if len(self) < 10:
return str(self.data)
tmp = self.data[:4]
tmp += self.data[-4:]
fmt = 'TS[{}, {}, {}, {}, ..., {}, {}, {}, {}]'
return fmt.format(*tmp)

def mean(self):
return sum(self.data) / len(self)
if len(self) == 0:
raise ValueError('Arithmetic mean of empty time series.')
m = sum(self.data) / float(len(self))
if self.accuracy:
return round(m, self.accuracy)
return m

def median(self):
if len(self) == 0:
raise ValueError('Median of empty time series.')
tmp = sorted(self.data)
return tmp[len(self)//2]

def stddev(self):
ld = len(self.data)
if ld < 2:
raise ValueError('Standard deviation of too few values')
m = self.mean()
ss = sum((x-m)**2 for x in self.data)
std = (ss/float(ld))**0.5
if self.accuracy:
return round(std, self.accuracy)
return std
28 changes: 28 additions & 0 deletions tests/test_ts.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,31 @@ def test_ts(self):
ts.append( 5.0 )
self.assertEqual( len(ts) , 3 )
self.assertEqual( ts.mean() , 2.0 )

def setUp(self):
self._ts = TS( [2.71828,3.141592,4.12310] )
self._tsa = TS( [2.71828,3.141592,4.12310], accuracy=2 )
self._tsb = TS( [6.1, 5.2, 4.3, 1.2, 2.3, 4.5, 5.6, 1000.123] )
self._tsc = TS( [6.1, 5.2, 4.3, 1.2, 2.3, 4.5, 5.6, 10.0,12.3] )

def test_ts_init(self):
self.assertEqual(3, len(self._ts))
self.assertEqual(3, len(self._tsa))
self.assertEqual(8, len(self._tsb))
self.assertEqual(9, len(self._tsc))
self.assertEqual(2.72, self._tsa[0])

def test_math_with_accuracy(self):
self.assertEqual(3.141592, self._ts.median())
self.assertEqual(3.14, self._tsa.median())

self.assertAlmostEqual(3.3276573, self._ts.mean())
self.assertEqual(3.33, self._tsa.mean())

self.assertAlmostEqual(0.5884131, self._ts.stddev())
self.assertEqual(0.59, self._tsa.stddev())

def test_median(self):
self.assertEqual(3.141592, self._ts.median())
self.assertEqual(5.2, self._tsb.median())
self.assertEqual(5.2, self._tsc.median())

0 comments on commit 7223142

Please sign in to comment.