# HG changeset patch # User Paul Boddie # Date 1425159052 -3600 # Node ID 43aded34a75fa2ae0ec2a921f5bfe8f9af0292eb # Parent 577f8dbb9627e8f616acb5b1d6b17c48b52c1791 Added docstrings. diff -r 577f8dbb9627 -r 43aded34a75f vRecurrence.py --- a/vRecurrence.py Thu Feb 26 19:38:14 2015 +0100 +++ b/vRecurrence.py Sat Feb 28 22:30:52 2015 +0100 @@ -3,7 +3,7 @@ """ Recurrence rule calculation. -Copyright (C) 2014 Paul Boddie +Copyright (C) 2014, 2015 Paul Boddie This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -124,7 +124,7 @@ """ Process the list of 'values' of the form "key=value", returning a list of - qualifiers. + qualifiers of the form (qualifier name, args). """ qualifiers = [] @@ -382,7 +382,19 @@ # Classes for producing instances from recurrence structures. class Selector: + + "A generic selector." + def __init__(self, level, args, qualifier, selecting=None): + + """ + Initialise at the given 'level' a selector employing the given 'args' + defined in the interpretation of recurrence rule qualifiers, with the + 'qualifier' being the name of the rule qualifier, and 'selecting' being + an optional selector used to find more specific instances from those + found by this selector. + """ + self.level = level self.pos = positions[level] self.args = args @@ -394,6 +406,14 @@ return "%s(%r, %r, %r, %r)" % (self.__class__.__name__, self.level, self.args, self.qualifier, self.context) def materialise(self, start, end, count=None, setpos=None): + + """ + Starting at 'start', materialise instances up to but not including any + at 'end' or later, returning at most 'count' if specified, and returning + only the occurrences indicated by 'setpos' if specified. A list of + instances is returned. + """ + start = to_tuple(start) end = to_tuple(end) counter = count and [0, count] @@ -401,15 +421,27 @@ results.sort() return results[:count] - def materialise_item(self, current, last, next, counter, setpos=None): + def materialise_item(self, current, earliest, next, counter, setpos=None): + + """ + Given the 'current' instance, the 'earliest' acceptable instance, the + 'next' instance, an instance 'counter', and the optional 'setpos' + criteria, return a list of result items. Where no selection within the + current instance occurs, the current instance will be returned as a + result if the same or later than the earliest acceptable instance. + """ + if self.selecting: - return self.selecting.materialise_items(current, last, next, counter, setpos) - elif last <= current: + return self.selecting.materialise_items(current, earliest, next, counter, setpos) + elif earliest <= current: return [current] else: return [] def convert_positions(self, setpos): + + "Convert 'setpos' to 0-based indexes." + l = [] for pos in setpos: lower = pos < 0 and pos or pos - 1 @@ -418,6 +450,9 @@ return l def select_positions(self, results, setpos): + + "Select in 'results' the 1-based positions given by 'setpos'." + results.sort() l = [] for lower, upper in self.convert_positions(setpos): @@ -425,6 +460,12 @@ return l def filter_by_period(self, results, start, end): + + """ + Filter 'results' so that only those at or after 'start' and before 'end' + are returned. + """ + l = [] for result in results: if start <= result < end: @@ -432,6 +473,9 @@ return l class Pattern(Selector): + + "A selector of instances according to a repeating pattern." + def materialise_items(self, context, start, end, counter, setpos=None): first = scale(self.context[self.pos], self.pos) @@ -460,6 +504,9 @@ return results class WeekDayFilter(Selector): + + "A selector of instances specified in terms of day numbers." + def materialise_items(self, context, start, end, counter, setpos=None): step = scale(1, 2) results = [] @@ -613,6 +660,13 @@ # Public functions. def connect_selectors(selectors): + + """ + Make the 'selectors' reference each other in a hierarchy so that + materialising the principal selector causes the more specific ones to be + employed in the operation. + """ + current = selectors[0] for selector in selectors[1:]: current.selecting = selector