summaryrefslogtreecommitdiffstats
path: root/cobbler/Cheetah/Tools/MondoReportDoc.txt
diff options
context:
space:
mode:
Diffstat (limited to 'cobbler/Cheetah/Tools/MondoReportDoc.txt')
-rw-r--r--cobbler/Cheetah/Tools/MondoReportDoc.txt391
1 files changed, 391 insertions, 0 deletions
diff --git a/cobbler/Cheetah/Tools/MondoReportDoc.txt b/cobbler/Cheetah/Tools/MondoReportDoc.txt
new file mode 100644
index 0000000..29a026d
--- /dev/null
+++ b/cobbler/Cheetah/Tools/MondoReportDoc.txt
@@ -0,0 +1,391 @@
+MondoReport Documentation
+Version 0.01 alpha 24-Nov-2001. iron@mso.oz.net or mso@oz.net.
+Copyright (c) 2001 Mike Orr. License: same as Python or Cheetah.
+
+* * * * *
+STATUS: previous/next batches and query string are not implemented yet.
+Sorting not designed yet. Considering "click on this column header to sort by
+this field" and multiple ascending/descending sort fields for a future version.
+
+Tested with Python 2.2b1. May work with Python 2.1 or 2.0.
+
+* * * * *
+OVERVIEW
+
+MondoReport -- provide information about a list that is useful in generating
+any kind of report. The module consists of one main public class, and some
+generic functions you may find useful in other programs. This file contains an
+overview, syntax reference and examples. The module is designed both for
+standalone use and for integration with the Cheetah template system
+(http://www.cheetahtemplate.org/), so the examples are in both Python and
+Cheetah. The main uses of MondoReport are:
+
+(A) to iterate through a list. In this sense MR is a for-loop enhancer,
+providing information that would be verbose to calculate otherwise.
+
+(B) to separate a list into equal-size "pages" (or "batches"--the two terms are
+interchangeable) and only display the current page, plus limited information
+about the previous and next pages.
+
+(C) to extract summary statistics about a certain column ("field") in the list.
+
+* * * * *
+MAIN PUBLIC CLASS
+
+To create a MondoReport instance, supply a list to operate on.
+
+ mr = MondoReport(origList)
+
+The list may be a list of anything, but if you use the 'field' argument in any
+of the methods below, the elements must be instances or dictionaries.
+
+MondoReport assumes it's operating on an unchanging list. Do not modify the
+list or any of its elements until you are completely finished with the
+ModoReport object and its sub-objects. Otherwise, you may get an exception or
+incorrect results.
+
+MondoReport instances have three methods:
+
+ .page(size, start, overlap=0, orphan=0
+ sort=None, reverse=False) => list of (r, a, b).
+
+'size' is an integer >= 1. 'start', 'overlap' and 'orphan' are integers >= 0.
+The list returned contains one triple for each record in the current page. 'r'
+is the original record. 'a' is a BatchRecord instance for the current record
+in relation to all records in the origList. 'b' is a BatchRecord instance for
+the current record in relation to all the records in that batch/page. (There
+is a .batch method that's identical to .page.)
+
+The other options aren't implemented yet, but 'overlap' duplicates this many
+records on adjacent batches. 'orphan' moves this many records or fewer, if
+they are on a page alone, onto the neighboring page. 'sort' (string) specifies
+a field to sort the records by. It may be suffixed by ":desc" to sort in
+descending order. 'reverse' (boolean) reverses the sort order. If both
+":desc" and 'reverse' are specified, they will cancel each other out. This
+sorting/reversal happens on a copy of the origList, and all objects returned
+by this method use the sorted list, except when resorting the next time.
+To do more complicated sorting, such as a hierarchy of columns, do it to the
+original list before creating the ModoReport object.
+
+ .all(sort=None, reverse=False) => list of (r, a).
+
+Same, but the current page spans the entire origList.
+
+ .summary() => Summary instance.
+
+Summary statistics for the entire origList.
+
+In Python, use .page or .all in a for loop:
+
+ from Cheetah.Tools.MondoReport import MondoReport
+ mr = MondoReport(myList)
+ for r, a, b in mr.page(20, 40):
+ # Do something with r, a and b. The current page is the third page,
+ # with twenty records corresponding to origList[40:60].
+ if not myList:
+ # Warn the user there are no records in the list.
+
+It works the same way in Cheetah, just convert to Cheetah syntax. This example
+assumes the template doubles as a Webware servlet, so we use the servlet's
+'$request' method to look up the CGI parameter 'start'. The default value is 0
+for the first page.
+
+ #from Cheetah.Tools.MondoReport import MondoReport
+ #set $mr = $MondoReport($bigList)
+ #set $start = $request.field("start", 0)
+ #for $o, $a, $b in $mr.page(20, $start)
+ ... do something with $o, $a and $b ...
+ #end for
+ #unless $bigList
+ This is displayed if the original list has no elements.
+ It's equivalent to the "else" part Zope DTML's <dtml-in>.
+ #end unless
+
+* * * * *
+USING 'r' RECORDS
+
+Use 'r' just as you would the original element. For instance:
+
+ print r.attribute # If r is an instance.
+ print r['key'] # If r is a dictionary.
+ print r # If r is numeric or a string.
+
+In Cheetah, you can take advantage of Universal Dotted Notation and autocalling:
+
+ $r.name ## 'name' may be an attribute or key of 'r'. If 'r' and/or
+ ## 'name' is a function or method, it will be called without
+ ## arguments.
+ $r.attribute
+ $r['key']
+ $r
+ $r().attribute()['key']()
+
+If origList is a list of name/value pairs (2-tuples or 2-lists), you may
+prefer to do this:
+
+ for (key, value), a, b in mr.page(20, 40):
+ print key, "=>", value
+
+ #for ($key, $value), $a, $b in $mr.page(20, $start)
+ $key =&gt; $value
+ #end for
+
+* * * * *
+STATISTICS METHODS AND FIELD VALUES
+
+Certain methods below have an optional argument 'field'. If specified,
+MondoReport will look up that field in each affected record and use its value
+in the calculation. MondoReport uses Cheetah's NameMapper if available,
+otherwise it uses a minimal NameMapper substitute that looks for an attribute
+or dictionary key called "field". You'll get an exception if any record is a
+type without attributes or keys, or if one or more records is missing that
+attribute/key.
+
+If 'field' is None, MondoReport will use the entire record in its
+calculation. This makes sense mainly if the records are a numeric type.
+
+All statistics methods filter out None values from their calculations, and
+reduce the number of records accordingly. Most filter out non-numeric fields
+(or records). Some raise NegativeError if a numeric field (or record) is
+negative.
+
+
+* * * * *
+BatchRecord METHODS
+
+The 'a' and 'b' objects of MondoReport.page() and MondoReport.all() provide
+these methods.
+
+ .index()
+
+The current subscript. For 'a', this is the true subscript into origList.
+For 'b', this is relative to the current page, so the first record will be 0.
+Hint: In Cheetah, use autocalling to skip the parentheses: '$b.index'.
+
+ .number()
+
+The record's position starting from 1. This is always '.index() + 1'.
+
+ .Letter()
+
+The letter ("A", "B", "C") corresponding to .number(). Undefined if .number()
+> 26. The current implementation just adds the offset to 'a' and returns
+whatever character it happens to be.
+
+To make a less dumb implementation (e.g., "Z, AA, BB" or "Z, A1, B1"):
+1) Subclass BatchRecord and override the .Letter method.
+2) Subclass MondoReport and set the class variable .BatchRecordClass to your
+new improved class.
+
+ .letter()
+
+Same but lower case.
+
+ .Roman()
+
+The Roman numeral corresponding to .number().
+
+ .roman()
+
+Same but lower case.
+
+ .even()
+
+True if .number() is even.
+
+ .odd()
+
+True if .number() is odd.
+
+ .even_i()
+
+True if .index() is even.
+
+ .odd_i()
+
+True if .index() is odd.
+
+ .length()
+
+For 'a', number of records in origList. For 'b', number of records on this
+page.
+
+ .item()
+
+The record itself. You don't need this in the normal case since it's the same
+as 'r', but it's useful for previous/next batches.
+
+ .size()
+
+The 'size' argument used when this BatchRecord was created.
+'a.size() == b.size()'.
+
+ .first()
+
+True if this is the first record.
+
+ .last()
+
+True if this is the last record.
+
+ .firstValue(field=None)
+
+True if there is no previous record, or if the previous field/record has a
+different value. Used for to print section headers. For instance, if you
+are printing addresses by country, this will be true at the first occurrance
+of each country. Or for indexes, you can have a non-printing field showing
+which letter of the alphablet this entry starts with, and then print a "B"
+header before printing the first record starting with "B".
+
+ .lastValue(field=None)
+
+True if this is the last record containing the current value in the
+field/record.
+
+ .percentOfTotal(field=None, suffix="%", default="N/A", decimals=2)
+
+Returns the percent that the current field/record is of all fields/records.
+If 'suffix' is None, returns a number; otherwise it returns a string with
+'suffix' suffixed. If the current value is non-numeric, returns 'default'
+instead (without 'suffix'). 'decimals' tells the number of decimal places to
+return; if 0, there will be no decimal point.
+
+ .prev()
+
+Returns a PrevNextBatch instance for the previous page. If there is no
+previous page, returns None. [Not implemented yet.]
+
+ .next()
+
+Returns a PrevNextBatch instance for the next page. If there is no next page,
+returns None. [Not implemented yet.]
+
+ .prevPages()
+
+Returns a list of PrevNextPage instances for every previous page, or [] if no
+previous pages. [Not implemented yet.]
+
+ .nextPages()
+
+Returns a list of PrevNextPage instances for every next page, or [] if no next
+pages. [Not implemented yet.]
+
+ .query(start=None, label=None, attribName="start", attribs=[])
+
+[Not implemented yet.]
+
+With no arguments, returns the HTML query string with start value removed (so
+you can append a new start value in your hyperlink). The query string is taken
+from the 'QUERY_STRING' environmental variable, or "" if missing. (This is
+Webware compatible.)
+
+With 'start' (an integer >= 0), returns the query string with an updated start
+value, normally for the next or previous batch.
+
+With 'label' (a string), returns a complete HTML hyperlink:
+'<A HREF="?new_query_string">label</A>'. You'll get a TypeError if you specify
+'label' but not 'start'.
+
+With 'attribName' (a string), uses this attribute name rather than "start".
+Useful if you have another CGI parameter "start" that's used for something
+else.
+
+With 'attribs' (a dictionary), adds these attributes to the hyperlink.
+For instance, 'attribs={"target": "_blank"}'. Ignored unless 'label' is
+specified too.
+
+This method assumes the start parameter is a GET variable, not a POST variable.
+
+ .summary()
+
+Returns a Summary instance. 'a.summary()' refers to all records in the
+origList, so it's the same as MondoReport.summary(). 'b.summary()' refers only
+to the records on the current page. [Not implemented yet.]
+
+* * * * *
+PrevNextPage INSTANCES
+
+[Not implemented yet.]
+
+PrevNextPage instances have the following methods:
+
+ .start()
+
+The index (true index of origList) that that page starts at. You may also use
+'.start().index()', '.start().number()', etc. Also
+'.start().item(field=None)'. (Oh, so *that*'s what .item is for!)
+
+ .end()
+
+The index (true index of origList) that that page ends at. You may also use
+'.end().index()', '.end().number()', etc. Also
+'.end().item(field=None)'.
+
+ .length()
+
+Number of records on that page.
+
+ .query(label=None, attribName="start", attribs={}, before="", after="")
+
+[Not implemented yet.]
+
+Similar to 'a.query()' and 'b.query()', but automatically calculates the start
+value for the appropriate page.
+
+For fancy HTML formatting, 'before' is prepended to the returned text and
+'after' is appended. (There was an argument 'else_' for if there is no such
+batch, but it was removed because you can't even get to this method at all in
+that case.)
+
+* * * * * *
+SUMMARY STATISTICS
+
+These methods are supported by the Summary instances returned by
+MondoReport.Summary():
+
+ .sum(field=None)
+
+Sum of all numeric values in a field, or sum of all records.
+
+ .total(field=None)
+
+Same.
+
+ .count(field=None)
+
+Number of fields/records with non-None values.
+
+ .min(field=None)
+
+Minimum value in that field/record. Ignores None values.
+
+ .max(field=None)
+
+Maximum value in that field/record. Ignores None values.
+
+ .mean(field=None)
+
+The mean (=average) of all numeric values in that field/record.
+
+ .average(field=None)
+
+Same.
+
+ .median(field=None)
+
+The median of all numeric values in that field/record. This is done by sorting
+the values and taking the middle value.
+
+ .variance(field=None), .variance_n(field=None)
+ .standardDeviation(field=None), .standardDeviation_n(field=None)
+
+[Not implemented yet.]
+
+
+* * * * *
+To run the regression tests (requires unittest.py, which is standard with
+Python 2.2), run MondoReportTest.py from the command line. The regression test
+double as usage examples.
+
+
+# vim: shiftwidth=4 tabstop=4 expandtab textwidth=79