diff options
Diffstat (limited to 'cobbler/Cheetah/Tools/MondoReport.py')
-rw-r--r-- | cobbler/Cheetah/Tools/MondoReport.py | 464 |
1 files changed, 0 insertions, 464 deletions
diff --git a/cobbler/Cheetah/Tools/MondoReport.py b/cobbler/Cheetah/Tools/MondoReport.py deleted file mode 100644 index f73e7fc..0000000 --- a/cobbler/Cheetah/Tools/MondoReport.py +++ /dev/null @@ -1,464 +0,0 @@ -#!/usr/bin/env python -""" -@@TR: This code is pretty much unsupported. - -MondoReport.py -- Batching module for Python and Cheetah. - -Version 2001-Nov-18. Doesn't do much practical yet, but the companion -testMondoReport.py passes all its tests. --Mike Orr (Iron) - -TODO: BatchRecord.prev/next/prev_batches/next_batches/query, prev.query, -next.query. - -How about Report: .page(), .all(), .summary()? Or PageBreaker. -""" -import operator, types -try: - from Cheetah.NameMapper import valueForKey as lookup_func -except ImportError: - def lookup_func(obj, name): - if hasattr(obj, name): - return getattr(obj, name) - else: - return obj[name] # Raises KeyError. - -########## CONSTANTS ############################## - -True, False = (1==1), (1==0) -numericTypes = types.IntType, types.LongType, types.FloatType - -########## PUBLIC GENERIC FUNCTIONS ############################## - -class NegativeError(ValueError): - pass - -def isNumeric(v): - return type(v) in numericTypes - -def isNonNegative(v): - ret = isNumeric(v) - if ret and v < 0: - raise NegativeError(v) - -def isNotNone(v): - return v is not None - -def Roman(n): - n = int(n) # Raises TypeError. - if n < 1: - raise ValueError("roman numeral for zero or negative undefined: " + n) - roman = '' - while n >= 1000: - n = n - 1000 - roman = roman + 'M' - while n >= 500: - n = n - 500 - roman = roman + 'D' - while n >= 100: - n = n - 100 - roman = roman + 'C' - while n >= 50: - n = n - 50 - roman = roman + 'L' - while n >= 10: - n = n - 10 - roman = roman + 'X' - while n >= 5: - n = n - 5 - roman = roman + 'V' - while n < 5 and n >= 1: - n = n - 1 - roman = roman + 'I' - roman = roman.replace('DCCCC', 'CM') - roman = roman.replace('CCCC', 'CD') - roman = roman.replace('LXXXX', 'XC') - roman = roman.replace('XXXX', 'XL') - roman = roman.replace('VIIII', 'IX') - roman = roman.replace('IIII', 'IV') - return roman - - -def sum(lis): - return reduce(operator.add, lis, 0) - -def mean(lis): - """Always returns a floating-point number. - """ - lis_len = len(lis) - if lis_len == 0: - return 0.00 # Avoid ZeroDivisionError (not raised for floats anyway) - total = float( sum(lis) ) - return total / lis_len - -def median(lis): - lis = lis[:] - lis.sort() - return lis[int(len(lis)/2)] - - -def variance(lis): - raise NotImplementedError() - -def variance_n(lis): - raise NotImplementedError() - -def standardDeviation(lis): - raise NotImplementedError() - -def standardDeviation_n(lis): - raise NotImplementedError() - - - -class IndexFormats: - """Eight ways to display a subscript index. - ("Fifty ways to leave your lover....") - """ - def __init__(self, index, item=None): - self._index = index - self._number = index + 1 - self._item = item - - def index(self): - return self._index - - __call__ = index - - def number(self): - return self._number - - def even(self): - return self._number % 2 == 0 - - def odd(self): - return not self.even() - - def even_i(self): - return self._index % 2 == 0 - - def odd_i(self): - return not self.even_i() - - def letter(self): - return self.Letter().lower() - - def Letter(self): - n = ord('A') + self._index - return chr(n) - - def roman(self): - return self.Roman().lower() - - def Roman(self): - return Roman(self._number) - - def item(self): - return self._item - - - -########## PRIVATE CLASSES ############################## - -class ValuesGetterMixin: - def __init__(self, origList): - self._origList = origList - - def _getValues(self, field=None, criteria=None): - if field: - ret = [lookup_func(elm, field) for elm in self._origList] - else: - ret = self._origList - if criteria: - ret = filter(criteria, ret) - return ret - - -class RecordStats(IndexFormats, ValuesGetterMixin): - """The statistics that depend on the current record. - """ - def __init__(self, origList, index): - record = origList[index] # Raises IndexError. - IndexFormats.__init__(self, index, record) - ValuesGetterMixin.__init__(self, origList) - - def length(self): - return len(self._origList) - - def first(self): - return self._index == 0 - - def last(self): - return self._index >= len(self._origList) - 1 - - def _firstOrLastValue(self, field, currentIndex, otherIndex): - currentValue = self._origList[currentIndex] # Raises IndexError. - try: - otherValue = self._origList[otherIndex] - except IndexError: - return True - if field: - currentValue = lookup_func(currentValue, field) - otherValue = lookup_func(otherValue, field) - return currentValue != otherValue - - def firstValue(self, field=None): - return self._firstOrLastValue(field, self._index, self._index - 1) - - def lastValue(self, field=None): - return self._firstOrLastValue(field, self._index, self._index + 1) - - # firstPage and lastPage not implemented. Needed? - - def percentOfTotal(self, field=None, suffix='%', default='N/A', decimals=2): - rec = self._origList[self._index] - if field: - val = lookup_func(rec, field) - else: - val = rec - try: - lis = self._getValues(field, isNumeric) - except NegativeError: - return default - total = sum(lis) - if total == 0.00: # Avoid ZeroDivisionError. - return default - val = float(val) - try: - percent = (val / total) * 100 - except ZeroDivisionError: - return default - if decimals == 0: - percent = int(percent) - else: - percent = round(percent, decimals) - if suffix: - return str(percent) + suffix # String. - else: - return percent # Numeric. - - def __call__(self): # Overrides IndexFormats.__call__ - """This instance is not callable, so we override the super method. - """ - raise NotImplementedError() - - def prev(self): - if self._index == 0: - return None - else: - length = self.length() - start = self._index - length - return PrevNextPage(self._origList, length, start) - - def next(self): - if self._index + self.length() == self.length(): - return None - else: - length = self.length() - start = self._index + length - return PrevNextPage(self._origList, length, start) - - def prevPages(self): - raise NotImplementedError() - - def nextPages(self): - raise NotImplementedError() - - prev_batches = prevPages - next_batches = nextPages - - def summary(self): - raise NotImplementedError() - - - - def _prevNextHelper(self, start,end,size,orphan,sequence): - """Copied from Zope's DT_InSV.py's "opt" function. - """ - if size < 1: - if start > 0 and end > 0 and end >= start: - size=end+1-start - else: size=7 - - if start > 0: - - try: sequence[start-1] - except: start=len(sequence) - # if start > l: start=l - - if end > 0: - if end < start: end=start - else: - end=start+size-1 - try: sequence[end+orphan-1] - except: end=len(sequence) - # if l - end < orphan: end=l - elif end > 0: - try: sequence[end-1] - except: end=len(sequence) - # if end > l: end=l - start=end+1-size - if start - 1 < orphan: start=1 - else: - start=1 - end=start+size-1 - try: sequence[end+orphan-1] - except: end=len(sequence) - # if l - end < orphan: end=l - return start,end,size - - - -class Summary(ValuesGetterMixin): - """The summary statistics, that don't depend on the current record. - """ - def __init__(self, origList): - ValuesGetterMixin.__init__(self, origList) - - def sum(self, field=None): - lis = self._getValues(field, isNumeric) - return sum(lis) - - total = sum - - def count(self, field=None): - lis = self._getValues(field, isNotNone) - return len(lis) - - def min(self, field=None): - lis = self._getValues(field, isNotNone) - return min(lis) # Python builtin function min. - - def max(self, field=None): - lis = self._getValues(field, isNotNone) - return max(lis) # Python builtin function max. - - def mean(self, field=None): - """Always returns a floating point number. - """ - lis = self._getValues(field, isNumeric) - return mean(lis) - - average = mean - - def median(self, field=None): - lis = self._getValues(field, isNumeric) - return median(lis) - - def variance(self, field=None): - raiseNotImplementedError() - - def variance_n(self, field=None): - raiseNotImplementedError() - - def standardDeviation(self, field=None): - raiseNotImplementedError() - - def standardDeviation_n(self, field=None): - raiseNotImplementedError() - - -class PrevNextPage: - def __init__(self, origList, size, start): - end = start + size - self.start = IndexFormats(start, origList[start]) - self.end = IndexFormats(end, origList[end]) - self.length = size - - -########## MAIN PUBLIC CLASS ############################## -class MondoReport: - _RecordStatsClass = RecordStats - _SummaryClass = Summary - - def __init__(self, origlist): - self._origList = origlist - - def page(self, size, start, overlap=0, orphan=0): - """Returns list of ($r, $a, $b) - """ - if overlap != 0: - raise NotImplementedError("non-zero overlap") - if orphan != 0: - raise NotImplementedError("non-zero orphan") - origList = self._origList - origList_len = len(origList) - start = max(0, start) - end = min( start + size, len(self._origList) ) - mySlice = origList[start:end] - ret = [] - for rel in range(size): - abs_ = start + rel - r = mySlice[rel] - a = self._RecordStatsClass(origList, abs_) - b = self._RecordStatsClass(mySlice, rel) - tup = r, a, b - ret.append(tup) - return ret - - - batch = page - - def all(self): - origList_len = len(self._origList) - return self.page(origList_len, 0, 0, 0) - - - def summary(self): - return self._SummaryClass(self._origList) - -""" -********************************** - Return a pageful of records from a sequence, with statistics. - - in : origlist, list or tuple. The entire set of records. This is - usually a list of objects or a list of dictionaries. - page, int >= 0. Which page to display. - size, int >= 1. How many records per page. - widow, int >=0. Not implemented. - orphan, int >=0. Not implemented. - base, int >=0. Number of first page (usually 0 or 1). - - out: list of (o, b) pairs. The records for the current page. 'o' is - the original element from 'origlist' unchanged. 'b' is a Batch - object containing meta-info about 'o'. - exc: IndexError if 'page' or 'size' is < 1. If 'origlist' is empty or - 'page' is too high, it returns an empty list rather than raising - an error. - - origlist_len = len(origlist) - start = (page + base) * size - end = min(start + size, origlist_len) - ret = [] - # widow, orphan calculation: adjust 'start' and 'end' up and down, - # Set 'widow', 'orphan', 'first_nonwidow', 'first_nonorphan' attributes. - for i in range(start, end): - o = origlist[i] - b = Batch(origlist, size, i) - tup = o, b - ret.append(tup) - return ret - - def prev(self): - # return a PrevNextPage or None - - def next(self): - # return a PrevNextPage or None - - def prev_batches(self): - # return a list of SimpleBatch for the previous batches - - def next_batches(self): - # return a list of SimpleBatch for the next batches - -########## PUBLIC MIXIN CLASS FOR CHEETAH TEMPLATES ############## -class MondoReportMixin: - def batch(self, origList, size=None, start=0, overlap=0, orphan=0): - bat = MondoReport(origList) - return bat.batch(size, start, overlap, orphan) - def batchstats(self, origList): - bat = MondoReport(origList) - return bat.stats() -""" - -# vim: shiftwidth=4 tabstop=4 expandtab textwidth=79 |