Skip to content

Instantly share code, notes, and snippets.

@tmitchell
Created October 1, 2012 21:16
Show Gist options
  • Save tmitchell/3814473 to your computer and use it in GitHub Desktop.
Save tmitchell/3814473 to your computer and use it in GitHub Desktop.
Django Binner
class Binner(object):
"""Bin a numeric value according to some set bins"""
def __init__(self, model, bins):
"""Set up the Binner
:Parameters:
- `model`: The BasicModel derived class that we'll be populating and pulling from
- `bins`: Iterable containing tuples for (min_val, max_val) for each bin, where None implies +/-Inf
"""
self._model = model
self._bins = bins
for (min, max) in self._bins:
bin, created = model.objects.get_or_create(name=self._get_bin_str(min, max))
if created:
logger.debug("Created new %s %s", model.__name__, bin)
def _get_bin_str(self, min, max):
if min is None:
assert max is not None
bin_str = "<= %d" % max
elif max is None:
bin_str = "> %d" % min
else:
bin_str = "%d - %d" % (min, max)
return bin_str
def get_bin(self, min, max):
return self._model.objects.get(name=self._get_bin_str(min, max))
def bin(self, value):
for (min, max) in self._bins:
if min is None and value <= max:
return self.get_bin(min, max)
elif max is None and value > min:
return self.get_bin(min, max)
elif min < value <= max:
return self.get_bin(min, max)
raise RuntimeError("Value %d does not fit any bins" % value)
@pydanny
Copy link

pydanny commented Oct 2, 2012

OMG this is great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment