# HG changeset patch # User Paul Boddie # Date 1317336094 -7200 # Node ID ac0167b6ed9b217f7990514f27a67751a236f40c # Parent af6042166fc539a06d82fc158b75ee0d02610652 Added comments and docstrings. diff -r af6042166fc5 -r ac0167b6ed9b iixr/data.py --- a/iixr/data.py Tue Feb 15 00:13:21 2011 +0100 +++ b/iixr/data.py Fri Sep 30 00:41:34 2011 +0200 @@ -23,7 +23,18 @@ # High-level representations. -def convert_sequence(values, op, last_from_old): +def convert_sequence(values, op, last_from_preceding): + + """ + Convert the given sequence of 'values' either to a sequence of delta values + if 'op' is a subtractor of some kind, using the preceding value in the + sequence as the basis of the calculation of a delta for the current value + (with 'last_from_preceding' set to a true value), or from a sequence of + delta values if 'op' is an adder of some kind, using the last result as the + basis of the calculation of an absolute value (with 'last_from_preceding' + set to a false value). + """ + if values: new_values = list(values) last = new_values[0] @@ -36,7 +47,7 @@ # Subtracting entries requires the old value to be used. # Adding entries requires the new value. - if last_from_old: + if last_from_preceding: last = current else: last = new_values[i] @@ -47,6 +58,13 @@ else: return values +# Monotonic operators where an input sequence must always, when combined with an +# operand, produce a result whose elements are all greater than or equal to the +# values of the input sequence (for addition) or all less than or equal to the +# values of the input sequence (for subtraction). +# +# For example: (1, 2) -> (2, 2) -> (2, 3) -> (3, 4) + def op_seq_monotonic(x, y, op): return tuple([op(a, b) for a, b in zip(x, y)]) @@ -56,37 +74,66 @@ def sub_seq_monotonic(x, y): return op_seq_monotonic(x, y, operator.sub) -def add_seq(x, y): - length = min(len(x), len(y)) - seq = list(x)[:length] +# Operators where an input sequence, when combined with an operand, may produce +# a result whose elements generally obey the properties for a monotonic sequence +# as described above, but where an element in the result may be reset with +# respect to the corresponding element in the input sequence and be less than +# that element (for addition) or greater than that element (for subtraction). +# +# For example: (1, 2) -> (2, 0) -> (2, 3) -> (3, 1) + +def add_seq(delta, input): + + "Add 'delta' to 'input'." + + length = min(len(delta), len(input)) + seq = list(delta)[:length] i = 0 while i < length: - if x[i] != 0: - seq[i] = x[i] + y[i] + + # If the delta is not zero, apply it to the input and retain the rest of + # the delta sequence as absolute values in the result. + + if delta[i] != 0: + seq[i] = delta[i] + input[i] break - seq[i] = y[i] + + seq[i] = input[i] i += 1 return tuple(seq) -def sub_seq(x, y): - length = min(len(x), len(y)) - seq = list(x)[:length] +def sub_seq(current, last): + + "Subtract 'current' from 'last'." + + length = min(len(current), len(last)) + seq = list(current)[:length] i = 0 while i < length: - replacement = x[i] - y[i] + + # Calculate a suitable delta value. If it is not zero, record it and + # retain the rest of the current value to reset the sequence in the + # result. + + replacement = current[i] - last[i] if replacement != 0: seq[i] = replacement break + seq[i] = 0 i += 1 return tuple(seq) +# Data inspection functions. + def is_sequence(value): return isinstance(value, (list, tuple)) def sizeof(value): return is_sequence(value) and len(value) or 0 +# Functions returning operators appropriate for the given structure size. + def get_monotonic_adder(size): return size and add_seq_monotonic or operator.add