Example #1
0
    def __init__(self, source, limits=None):
        """ Initializes TransactionNode. """
        if isinstance(source, type(self)):
            # Copy initialization:
            self.source = source.source
            self.limits = source.limits
            return

        # Hold on to the original list/dict/whatever.
        # (Consider copying it in case input `children` is mutated?)
        self.source = source

        # Parse `limits` input:
        if limits is not None:
            # Cast to LimitTuple if not already in that format:
            if not isinstance(limits, LimitTuple):
                limits = LimitTuple(*limits)
            self.limits = limits
        else:
            # To avoid testing for `self.limits is not None` elsewhere,
            # assign an all-None-valued LimitTuple if `limits` was not
            # provided.
            self.limits = LimitTuple()

        # Generate `children` attribute by recursively generating a
        # TransactionNode instance for each child in `source`.
        self.children = _children_from_source(self)
Example #2
0
def group_default_methods(field_names=LINK_FIELD_NAMES):
    """ Returns methods returning sets of linked accts. as a LimitTuple. """
    methods = []
    # Rather than write out four separate methods that return
    # min_inflow_link, max_inflow_link, ..., we write a generator for
    # such methods and return a full set of them as a LimitTuple:
    for field_name in field_names:
        # Define a method that returns the group of linked accounts for
        # a given link (e.g. `max_inflow_link`).
        # NOTE: Use `field_name` as a default value to avoid the issue
        # where the closure will use the most recent value for
        # `field_name` rather than the value at the time the closure
        # was defined. (This could also be solved by using a partial).
        # The default value is locked in at definition time.
        def default_method(account, name=field_name):
            # Return the group for the given link if the link exists:
            if hasattr(account, name):
                link = getattr(account, name)
                if link is not None:
                    return link.group
            # If the account doesn't have a link (either because it's
            # not a LinkedLimitAccount or similar, or because its link
            # is None), then simply return None:
            return None

        # default_method over. It will be added to the LimitTuple later.
        methods.append(default_method)
    return LimitTuple(*methods)
Example #3
0
def transaction_default_methods(field_names=TRANSACTION_LIMIT_FIELD_NAMES):
    """ Returns methods for finding min/max in/outflows as a LimitTuple. """
    methods = []
    # Rather than write out four separate methods that return
    # min_inflows, max_inflows, ..., we write a generator for such
    # methods and return a full set of them as a LimitTuple:
    for field_name in field_names:
        # We use `field_name` as a default value to avoid the issue
        # where the closure will use the most recent value for
        # `field_name` rather than the value at the time the closure
        # was defined. (This could also be solved by using a partial).
        # The default value is locked in at definition time.
        methods.append(lambda account, name=field_name: getattr(account, name))
    return LimitTuple(*methods)
Example #4
0
""" Defines helper functions for identifying an account's min/max. """

from forecaster.accounts import LimitTuple

# TODO: Move LimitTuple constants to forecaster.accounts module.
# Consider going further and refactoring `Account` so that
# `max_inflows`/etc and `max_inflow_link`/etc are held by LimitTuples
# (e.g. so client code accesses `transaction_schedule.max_inflow`
# or `link.max_inflow` instead). Is this pythonic?

# Map LimitTuple fields to the names of AccountLink members of
# LinkedLimitAccount objects:
LINK_FIELD_NAMES = LimitTuple('min_inflow_link', 'max_inflow_link',
                              'min_outflow_link', 'max_outflow_link')
# Map LimitTuple fields to the named of min/max inflow/outflow members
# of Account objects:
TRANSACTION_LIMIT_FIELD_NAMES = LimitTuple('min_inflows', 'max_inflows',
                                           'min_outflows', 'max_outflows')


def transaction_default_methods(field_names=TRANSACTION_LIMIT_FIELD_NAMES):
    """ Returns methods for finding min/max in/outflows as a LimitTuple. """
    methods = []
    # Rather than write out four separate methods that return
    # min_inflows, max_inflows, ..., we write a generator for such
    # methods and return a full set of them as a LimitTuple:
    for field_name in field_names:
        # We use `field_name` as a default value to avoid the issue
        # where the closure will use the most recent value for
        # `field_name` rather than the value at the time the closure
        # was defined. (This could also be solved by using a partial).