Skip to content

Instantly share code, notes, and snippets.

@eddieantonio
Created July 29, 2013 01:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eddieantonio/6101612 to your computer and use it in GitHub Desktop.
Save eddieantonio/6101612 to your computer and use it in GitHub Desktop.
From a comment near the bottom of the file: "I wanted to know if 'Awakening' was significantly different from the rest. It isn't. "
#!/usr/bin/env python
# Copyright 2013 Eddie Antonio Santos
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
MahavishnuStats -- Simple statistics stuff because I got bored.
"""
import math
from functools import wraps
identity = lambda x: x
fst = lambda t: a[0]
snd = lambda t: t[1]
class immutable_property(object):
"""
Like property, but lazily evaluates the method one and only one
time. Raises an AttributeError when the attribute is set.
Intended to be used a decorator, which is also why it's in
snake_case as opposed to StudlyCamelCase.
"""
def __init__(self, get, doc=None):
self.get = get
self.answers = {}
# Set the doc from either the provided doc or the property's doc
# itself.
self.__doc__ = doc if doc is not None else get.__doc__
def __get__(self, obj, cls=None):
key = id(obj)
if key not in self.answers:
self.answers[key] = self.get(obj)
return self.answers[key]
def __set__(self, obj, value):
raise AttributeError("'%s' is read-only." % self.get.__name__)
odd = lambda x: x & 1
class Sample(object):
def __init__(self, data, key=identity, label=None):
# Apply the key function to everything first.
self._nums = sorted(key(x) for x in data)
# I wish it didn't have to be applied AGAIN, but such is life.
self._data = sorted(data, key=key)
self._label = label
self._key = key
self._len = len(data)
def __len__(self):
return self._len
def __repr__(self):
datums = (self.__class__.__name__, '(',
repr(self._data),
', label=', repr(self._label),
', key=', repr(self._key),
')')
return ''.join(datums)
@property
def data(self):
return self._data
@immutable_property
def mean(self):
return sum(self._nums) / float(self._len)
@immutable_property
def median(self):
midpoint = self._len // 2
if odd(self._len):
return float(self._nums[midpoint])
leftMiddle = self._nums[midpoint - 1]
rightMiddle = self._nums[midpoint]
return (leftMiddle + rightMiddle) / 2.0
@immutable_property
def range(self):
return (self._data[0], self._data[self._len-1])
@immutable_property
def variance(self):
mean = self.mean
ss = sum((x - mean) ** 2 for x in self._nums)
return ss / self._len
@immutable_property
def standard_deviation(self):
return math.sqrt(self.variance)
@immutable_property
def interquartile_range(self):
return InterquartileRange(self._data, self._nums, self._len, self._key)
class InterquartileRange(object):
def __init__(self, data, xs, n, v):
# Make some indicies, yo!
midpoint = n // 2
quartile1 = n // 4
quartile3 = 3 * n // 4
# Get some slices of that data!
self.lower = data[:quartile1]
self.middle = data[quartile1:quartile3]
self.upper = data[quartile3:]
# Get *the* interquartile's range.
self.q1 = xs[quartile1]
self.q3 = xs[quartile3]
self.range = self.q3 - self.q1
self.lower_cutoff = self.q1 - 1.5 * self.range
self.upper_cutoff = self.q3 + 1.5 * self.range
self.lower_outliers = [x for x in self.lower if v(x) < self.lower_cutoff]
self.upper_outliers = [x for x in self.upper if v(x) > self.upper_cutoff]
# I wanted to know if 'Awakening' was significantly different from the
# rest. It isn't.
inner_mounting_flame_raw = [
('Meeting of the Spirits', 412),
('Dawn', 310),
('The Noonward Race', 388),
('A Lotus On Irish Streams', 339),
('Vital Transformation', 376),
('The Dance of Maya', 437),
('You Know You Know', 307),
('Awakening', 212)
]
inner_mounting_flame = Sample(inner_mounting_flame_raw, key=snd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment