<commit_before>'''
Operations are the core of pyinfra. The ``@operation`` wrapper intercepts calls
to the function and instead diff against the remote server, outputting commands
to the deploy state. This is then run later by pyinfra's ``__main__`` or the
:doc:`./pyinfra.api.operations` module.
'''

from __future__ import unicode_literals

from functools import wraps
from types import FunctionType

import six

import pyinfra

from pyinfra import logger, pseudo_host, pseudo_state

from .command import StringCommand
from .exceptions import PyinfraError
from .host import Host
from .operation_kwargs import pop_global_op_kwargs
from .state import State
from .util import (
    get_arg_value,
    get_call_location,
    get_caller_frameinfo,
    make_hash,
    memoize,
    unroll_generators,
)

# List of available operation names
OPERATIONS = []

def get_operation_names():
    '''
    Returns a list of available operations.
    '''

    return OPERATIONS

class OperationMeta(object):
    def __init__(self, hash=None, commands=None):
        # Wrap all the attributes
        commands = commands or []
        self.commands = commands
        self.hash = hash

        # Changed flag = did we do anything?
        self.changed = len(self.commands) > 0

    def __repr__(self):
        '''Return Operation object as a string.'''
        return 'commands:{} changed:{} hash:{}'.format(
            self.commands, self.changed, self.hash)

def add_op(state, op_func, *args, **kwargs):
    '''
    Prepare & add an operation to ``pyinfra.state`` by executing it on all hosts.

    Args:
        state (``pyinfra.api.State`` obj): the deploy state to add the operation
        to op_func (function): the operation function from one of the modules,
        ie ``server.user``
        args/kwargs: passed to the operation function
    '''

    allow_cli_mode = kwargs.pop('_allow_cli_mode', False)

    if pyinfra.is_cli and not allow_cli_mode:
        raise PyinfraError((
            '`add_op` should not be called when pyinfra is executing in CLI mode! ({0})'
        ).format(get_call_location()))

    kwargs['frameinfo'] = get_caller_frameinfo()

    # This ensures that every time an operation is added (API mode), it is simply
    # appended to the operation order.
    kwargs['_line_number'] = len(state.op_meta)

    results = {}

    kwargs['state'] = state
    for host in state.inventory:
        kwargs['host'] = host
        results[host] = op_func(*args, **kwargs)

    return results

@memoize
def show_set_name_warning(call_location):
    logger.warning((
        '{0}:\n\tUse of a `set` to name operations is deprecated, '
        'please us the `name` keyword argument.'
    ).format(call_location))

@memoize
def show_state_host_arguments_warning(call_location):
    logger.warning((
        '{0}:\n\tPassing `state` and `host` as the first two arguments to operations is '
        'deprecated, please us `state` and `host` keyword arguments.'
    ).format(call_location))

def operation(func=None, pipeline_facts=None):
    '''
    Decorator that takes a simple module function and turn it into the internal
    operation representation that consists of a list of commands + options
    (sudo, (sudo|su)_user, env).
    '''

    # If not decorating, return function with config attached
    if func is None:
        def decorator(f):
            setattr(f, 'pipeline_facts', pipeline_facts)
            return operation(f)

        return decorator

    # Index the operation!
    module_bits = func.__module__.split('.')
    module_name = module_bits[-1]
    op_name = '.'.join((module_name, func.__name__))
    OPERATIONS.append(op_name)

    # Actually decorate!
    @wraps(func)
    def decorated_func(*args, **kwargs):
        # Prepare state/host
        #

        # State & host passed in as kwargs (API, nested op, @deploy op)
        if 'state' in kwargs and 'host' in kwargs:
            state = kwargs['state']
            host = kwargs['host']

        # State & host passed in as first two arguments (LEGACY)
        elif len(args) >= 2 and isinstance(args[0], State) and isinstance(args[1], Host):
            show_state_host_arguments_warning(get_call_location())
            state = kwargs['state'] = args[0]
            host = kwargs['host'] = args[1]
            args_copy = list(args)
            args = args_copy[2:]

        # Finally, still no state+host? Use pseudo if we're CLI mode, or fail
        elif pyinfra.is_cli:
            state = kwargs['state'] = pseudo_state._module
            host = kwargs['host'] = pseudo_host._module

            if state.in_op:
                raise PyinfraError((
                    'Nested operation called without state/host: {0} ({1})'
                ).format(op_name, get_call_location()))

            if state.in_deploy:
                raise PyinfraError((
                    'Nested deploy operation called without state/host: {0} ({1})'
                ).format(op_name, get_call_location()))

        else:
            raise PyinfraError((
                'API operation called without state/host: {0} ({1})'
            ).format(op_name, get_call_location()))

        # In API mode we have the kwarg - if a nested operation call we have
        # current_frameinfo.
        frameinfo = kwargs.pop('frameinfo', get_caller_frameinfo())

        # Configure operation
        #

        # Get the meta kwargs (globals that apply to all hosts)
        op_meta_kwargs = pop_global_op_kwargs(state, kwargs)

        # Name the operation
        name = op_meta_kwargs.get('name')
        if name:
            names = {name}

        # Look for a set as the first argument
        # TODO: remove this! COMPAT w/<1
        elif len(args) > 0 and isinstance(args[0], set):
            show_set_name_warning(get_call_location())
            names = args[0]
            args_copy = list(args)
            args = args[1:]

        # Generate an operation name if needed (Module/Operation format)
        else:
            module_bits = func.__module__.split('.')
            module_name = module_bits[-1]
            names = {
                '{0}/{1}'.format(module_name.title(), func.__name__.title()),
            }

        if state.deploy_name:
            names = {
                '{0} | {1}'.format(state.deploy_name, name)
                for name in names
            }

        # If this op is being called inside another, just return here
        # (any unwanted/op-related kwargs removed above).
        if state.in_op:
            return func(*args, **kwargs) or []

        # Inject the current op file number (only incremented in CLI mode)
        op_lines = [state.current_op_file]

        # Add any current @deploy line numbers
        if state.deploy_line_numbers:
            op_lines.extend(state.deploy_line_numbers)

        # Add any current loop count
        if state.loop_line:
            op_lines.extend([state.loop_line, state.loop_counter])

        # Add the line number that called this operation
        line_number = kwargs.pop('_line_number', frameinfo.lineno)
        op_lines.append(line_number)

        # Make a hash from the call stack lines
        op_hash = make_hash(op_lines)

        # Avoid adding duplicates! This happens if an operation is called within
        # a loop - such that the filename/lineno/code _are_ the same, but the
        # arguments might be different. We just append an increasing number to
        # the op hash and also handle below with the op order.
        host_op_hashes = state.meta[host]['op_hashes']
        duplicate_op_count = 0
        while op_hash in host_op_hashes:
            logger.debug('Duplicate hash ({0}) detected!'.format(op_hash))
            op_hash = '{0}-{1}'.format(op_hash, duplicate_op_count)
            duplicate_op_count += 1

        host_op_hashes.add(op_hash)

        if duplicate_op_count:
            op_lines.append(duplicate_op_count)

        op_lines = tuple(op_lines)

        logger.debug('Adding operation, {0}, called @ {1}:{2}, opLines={3}, opHash={4}'.format(
            names, frameinfo.filename, line_number, op_lines, op_hash,
        ))
        state.op_line_numbers_to_hash[op_lines] = op_hash

        # Ensure shared (between servers) operation meta
        op_meta = state.op_meta.setdefault(op_hash, {
            'names': set(),
            'args': [],
        })

        # Add any meta kwargs (sudo, etc) to the meta - first parse any strings
        # as jinja templates.
        actual_op_meta_kwargs = {
            key: get_arg_value(state, host, a)
            for key, a in six.iteritems(op_meta_kwargs)
        }
        op_meta.update(actual_op_meta_kwargs)

        # Add any new names to the set
        op_meta['names'].update(names)

        # Attach normal args, if we're auto-naming this operation
        for arg in args:
            if isinstance(arg, FunctionType):
                arg = arg.__name__

            if arg not in op_meta['args']:
                op_meta['args'].append(arg)

        # Attach keyword args
        for key, value in six.iteritems(kwargs):
            if key in ('state', 'host'):
                continue

            arg = '='.join((str(key), str(value)))
            if arg not in op_meta['args']:
                op_meta['args'].append(arg)

        # Check if we're actually running the operation on this host
        #

        # Run once and we've already added meta for this op? Stop here.
        if op_meta_kwargs['run_once']:
            has_run = False
            for ops in six.itervalues(state.ops):
                if op_hash in ops:
                    has_run = True
                    break

            if has_run:
                return OperationMeta(op_hash)

        # "Run" operation
        #

        # Otherwise, flag as in-op and run it to get the commands
        state.in_op = True
        state.current_op_hash = op_hash

        # Generate actual arguments by parsing strings as jinja2 templates. This
        # means you can string format arguments w/o generating multiple
        # operations. Only affects top level operations, as must be run "in_op"
        # so facts are gathered correctly.
        actual_args = [
            get_arg_value(state, host, a)
            for a in args
        ]

        actual_kwargs = {
            key: get_arg_value(state, host, a)
            for key, a in six.iteritems(kwargs)
        }

        # Convert to list as the result may be a generator
        commands = unroll_generators(func(*actual_args, **actual_kwargs))
        commands = [  # convert any strings -> StringCommand's
            StringCommand(command.strip())
            if isinstance(command, six.string_types) else command
            for command in commands
        ]

        state.in_op = False
        state.current_op_hash = None

        # Add host-specific operation data to state
        #

        # We're doing some commands, meta/ops++
        state.meta[host]['ops'] += 1
        state.meta[host]['commands'] += len(commands)

        # Add the server-relevant commands
        state.ops[host][op_hash] = {
            'commands': commands,
        }

        # Return result meta for use in deploy scripts
        return OperationMeta(op_hash, commands)

    decorated_func._pyinfra_op = func
    return decorated_func
<commit_msg>error out under the right conditions<commit_after>'''
Operations are the core of pyinfra. The ``@operation`` wrapper intercepts calls
to the function and instead diff against the remote server, outputting commands
to the deploy state. This is then run later by pyinfra's ``__main__`` or the
:doc:`./pyinfra.api.operations` module.
'''

from __future__ import unicode_literals

from functools import wraps
from types import FunctionType

import six

import pyinfra

from pyinfra import logger, pseudo_host, pseudo_state

from .command import StringCommand
from .exceptions import PyinfraError
from .host import Host
from .operation_kwargs import pop_global_op_kwargs
from .state import State
from .util import (
    get_arg_value,
    get_call_location,
    get_caller_frameinfo,
    make_hash,
    memoize,
    unroll_generators,
)

# List of available operation names
OPERATIONS = []

def get_operation_names():
    '''
    Returns a list of available operations.
    '''

    return OPERATIONS

class OperationMeta(object):
    def __init__(self, hash=None, commands=None):
        # Wrap all the attributes
        commands = commands or []
        self.commands = commands
        self.hash = hash

        # Changed flag = did we do anything?
        self.changed = len(self.commands) > 0

    def __repr__(self):
        '''Return Operation object as a string.'''
        return 'commands:{} changed:{} hash:{}'.format(
            self.commands, self.changed, self.hash)

def add_op(state, op_func, *args, **kwargs):
    '''
    Prepare & add an operation to ``pyinfra.state`` by executing it on all hosts.

    Args:
        state (``pyinfra.api.State`` obj): the deploy state to add the operation
        to op_func (function): the operation function from one of the modules,
        ie ``server.user``
        args/kwargs: passed to the operation function
    '''

    allow_cli_mode = kwargs.pop('_allow_cli_mode', False)

    if pyinfra.is_cli and not allow_cli_mode:
        raise PyinfraError((
            '`add_op` should not be called when pyinfra is executing in CLI mode! ({0})'
        ).format(get_call_location()))

    kwargs['frameinfo'] = get_caller_frameinfo()

    # This ensures that every time an operation is added (API mode), it is simply
    # appended to the operation order.
    kwargs['_line_number'] = len(state.op_meta)

    results = {}

    kwargs['state'] = state
    for host in state.inventory:
        kwargs['host'] = host
        results[host] = op_func(*args, **kwargs)

    return results

@memoize
def show_set_name_warning(call_location):
    logger.warning((
        '{0}:\n\tUse of a `set` to name operations is deprecated, '
        'please us the `name` keyword argument.'
    ).format(call_location))

@memoize
def show_state_host_arguments_warning(call_location):
    logger.warning((
        '{0}:\n\tPassing `state` and `host` as the first two arguments to operations is '
        'deprecated, please us `state` and `host` keyword arguments.'
    ).format(call_location))

def operation(func=None, pipeline_facts=None):
    '''
    Decorator that takes a simple module function and turn it into the internal
    operation representation that consists of a list of commands + options
    (sudo, (sudo|su)_user, env).
    '''

    # If not decorating, return function with config attached
    if func is None:
        def decorator(f):
            setattr(f, 'pipeline_facts', pipeline_facts)
            return operation(f)

        return decorator

    # Index the operation!
    module_bits = func.__module__.split('.')
    module_name = module_bits[-1]
    op_name = '.'.join((module_name, func.__name__))
    OPERATIONS.append(op_name)

    # Actually decorate!
    @wraps(func)
    def decorated_func(*args, **kwargs):
        # Prepare state/host
        #

        # State & host passed in as kwargs (API, nested op, @deploy op)
        if 'state' in kwargs and 'host' in kwargs:
            state = kwargs['state']
            host = kwargs['host']

        # State & host passed in as first two arguments (LEGACY)
        elif len(args) >= 2 and isinstance(args[0], State) and isinstance(args[1], Host):
            show_state_host_arguments_warning(get_call_location())
            state = kwargs['state'] = args[0]
            host = kwargs['host'] = args[1]
            args_copy = list(args)
            args = args_copy[2:]

        # Finally, still no state+host? Use pseudo if we're CLI mode, or fail
        elif pyinfra.is_cli:
            state = kwargs['state'] = pseudo_state._module
            host = kwargs['host'] = pseudo_host._module

            if not state or not host:
                if state.in_op:
                    raise PyinfraError((
                        'Nested operation called without state/host: {0} ({1})'
                    ).format(op_name, get_call_location()))

                if state.in_deploy:
                    raise PyinfraError((
                        'Nested deploy operation called without state/host: {0} ({1})'
                    ).format(op_name, get_call_location()))

        else:
            raise PyinfraError((
                'API operation called without state/host: {0} ({1})'
            ).format(op_name, get_call_location()))

        # In API mode we have the kwarg - if a nested operation call we have
        # current_frameinfo.
        frameinfo = kwargs.pop('frameinfo', get_caller_frameinfo())

        # Configure operation
        #

        # Get the meta kwargs (globals that apply to all hosts)
        op_meta_kwargs = pop_global_op_kwargs(state, kwargs)

        # Name the operation
        name = op_meta_kwargs.get('name')
        if name:
            names = {name}

        # Look for a set as the first argument
        # TODO: remove this! COMPAT w/<1
        elif len(args) > 0 and isinstance(args[0], set):
            show_set_name_warning(get_call_location())
            names = args[0]
            args_copy = list(args)
            args = args[1:]

        # Generate an operation name if needed (Module/Operation format)
        else:
            module_bits = func.__module__.split('.')
            module_name = module_bits[-1]
            names = {
                '{0}/{1}'.format(module_name.title(), func.__name__.title()),
            }

        if state.deploy_name:
            names = {
                '{0} | {1}'.format(state.deploy_name, name)
                for name in names
            }

        # If this op is being called inside another, just return here
        # (any unwanted/op-related kwargs removed above).
        if state.in_op:
            return func(*args, **kwargs) or []

        # Inject the current op file number (only incremented in CLI mode)
        op_lines = [state.current_op_file]

        # Add any current @deploy line numbers
        if state.deploy_line_numbers:
            op_lines.extend(state.deploy_line_numbers)

        # Add any current loop count
        if state.loop_line:
            op_lines.extend([state.loop_line, state.loop_counter])

        # Add the line number that called this operation
        line_number = kwargs.pop('_line_number', frameinfo.lineno)
        op_lines.append(line_number)

        # Make a hash from the call stack lines
        op_hash = make_hash(op_lines)

        # Avoid adding duplicates! This happens if an operation is called within
        # a loop - such that the filename/lineno/code _are_ the same, but the
        # arguments might be different. We just append an increasing number to
        # the op hash and also handle below with the op order.
        host_op_hashes = state.meta[host]['op_hashes']
        duplicate_op_count = 0
        while op_hash in host_op_hashes:
            logger.debug('Duplicate hash ({0}) detected!'.format(op_hash))
            op_hash = '{0}-{1}'.format(op_hash, duplicate_op_count)
            duplicate_op_count += 1

        host_op_hashes.add(op_hash)

        if duplicate_op_count:
            op_lines.append(duplicate_op_count)

        op_lines = tuple(op_lines)

        logger.debug('Adding operation, {0}, called @ {1}:{2}, opLines={3}, opHash={4}'.format(
            names, frameinfo.filename, line_number, op_lines, op_hash,
        ))
        state.op_line_numbers_to_hash[op_lines] = op_hash

        # Ensure shared (between servers) operation meta
        op_meta = state.op_meta.setdefault(op_hash, {
            'names': set(),
            'args': [],
        })

        # Add any meta kwargs (sudo, etc) to the meta - first parse any strings
        # as jinja templates.
        actual_op_meta_kwargs = {
            key: get_arg_value(state, host, a)
            for key, a in six.iteritems(op_meta_kwargs)
        }
        op_meta.update(actual_op_meta_kwargs)

        # Add any new names to the set
        op_meta['names'].update(names)

        # Attach normal args, if we're auto-naming this operation
        for arg in args:
            if isinstance(arg, FunctionType):
                arg = arg.__name__

            if arg not in op_meta['args']:
                op_meta['args'].append(arg)

        # Attach keyword args
        for key, value in six.iteritems(kwargs):
            if key in ('state', 'host'):
                continue

            arg = '='.join((str(key), str(value)))
            if arg not in op_meta['args']:
                op_meta['args'].append(arg)

        # Check if we're actually running the operation on this host
        #

        # Run once and we've already added meta for this op? Stop here.
        if op_meta_kwargs['run_once']:
            has_run = False
            for ops in six.itervalues(state.ops):
                if op_hash in ops:
                    has_run = True
                    break

            if has_run:
                return OperationMeta(op_hash)

        # "Run" operation
        #

        # Otherwise, flag as in-op and run it to get the commands
        state.in_op = True
        state.current_op_hash = op_hash

        # Generate actual arguments by parsing strings as jinja2 templates. This
        # means you can string format arguments w/o generating multiple
        # operations. Only affects top level operations, as must be run "in_op"
        # so facts are gathered correctly.
        actual_args = [
            get_arg_value(state, host, a)
            for a in args
        ]

        actual_kwargs = {
            key: get_arg_value(state, host, a)
            for key, a in six.iteritems(kwargs)
        }

        # Convert to list as the result may be a generator
        commands = unroll_generators(func(*actual_args, **actual_kwargs))
        commands = [  # convert any strings -> StringCommand's
            StringCommand(command.strip())
            if isinstance(command, six.string_types) else command
            for command in commands
        ]

        state.in_op = False
        state.current_op_hash = None

        # Add host-specific operation data to state
        #

        # We're doing some commands, meta/ops++
        state.meta[host]['ops'] += 1
        state.meta[host]['commands'] += len(commands)

        # Add the server-relevant commands
        state.ops[host][op_hash] = {
            'commands': commands,
        }

        # Return result meta for use in deploy scripts
        return OperationMeta(op_hash, commands)

    decorated_func._pyinfra_op = func
    return decorated_func
<|endoftext|>


<commit_before>"""
Support for WeMo device discovery.

For more details about this component, please refer to the documentation at
https://home-assistant.io/components/wemo/
"""
import logging

import voluptuous as vol

from homeassistant.components.discovery import SERVICE_WEMO
from homeassistant.helpers import discovery
from homeassistant.helpers import config_validation as cv

from homeassistant.const import EVENT_HOMEASSISTANT_STOP

REQUIREMENTS = ['pywemo==0.4.28']

DOMAIN = 'wemo'

# Mapping from Wemo model_name to component.
WEMO_MODEL_DISPATCH = {
    'Bridge':  'light',
    'CoffeeMaker': 'switch',
    'Dimmer': 'light',
    'Insight': 'switch',
    'LightSwitch': 'switch',
    'Maker':   'switch',
    'Sensor':  'binary_sensor',
    'Socket':  'switch'
}

SUBSCRIPTION_REGISTRY = None
KNOWN_DEVICES = []

_LOGGER = logging.getLogger(__name__)

CONF_STATIC = 'static'

CONFIG_SCHEMA = vol.Schema({
    DOMAIN: vol.Schema({
        vol.Optional(CONF_STATIC, default=[]): vol.Schema([cv.string])
    }),
}, extra=vol.ALLOW_EXTRA)

def setup(hass, config):
    """Set up for WeMo devices."""
    import pywemo

    global SUBSCRIPTION_REGISTRY
    SUBSCRIPTION_REGISTRY = pywemo.SubscriptionRegistry()
    SUBSCRIPTION_REGISTRY.start()

    def stop_wemo(event):
        """Shutdown Wemo subscriptions and subscription thread on exit."""
        _LOGGER.info("Shutting down subscriptions.")
        SUBSCRIPTION_REGISTRY.stop()

    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_wemo)

    def discovery_dispatch(service, discovery_info):
        """Dispatcher for WeMo discovery events."""
        # name, model, location, mac
        model_name = discovery_info.get('model_name')
        serial = discovery_info.get('serial')

        # Only register a device once
        if serial in KNOWN_DEVICES:
            return
        _LOGGER.debug('Discovered unique device %s', serial)
        KNOWN_DEVICES.append(serial)

        component = WEMO_MODEL_DISPATCH.get(model_name, 'switch')

        discovery.load_platform(hass, component, DOMAIN, discovery_info,
                                config)

    discovery.listen(hass, SERVICE_WEMO, discovery_dispatch)

    _LOGGER.info("Scanning for WeMo devices.")
    devices = [(device.host, device) for device in pywemo.discover_devices()]

    # Add static devices from the config file.
    devices.extend((address, None)
                   for address in config.get(DOMAIN, {}).get(CONF_STATIC, []))

    for address, device in devices:
        port = pywemo.ouimeaux_device.probe_wemo(address)
        if not port:
            _LOGGER.warning('Unable to probe wemo at %s', address)
            continue
        _LOGGER.info('Adding wemo at %s:%i', address, port)

        url = 'http://%s:%i/setup.xml' % (address, port)
        if device is None:
            device = pywemo.discovery.device_from_description(url, None)

        discovery_info = {
            'model_name': device.model_name,
            'serial': device.serialnumber,
            'mac_address': device.mac,
            'ssdp_description': url,
        }

        discovery.discover(hass, SERVICE_WEMO, discovery_info)
    return True
<commit_msg>Add other wemo motion sensor identifier (#15627)<commit_after>"""
Support for WeMo device discovery.

For more details about this component, please refer to the documentation at
https://home-assistant.io/components/wemo/
"""
import logging

import voluptuous as vol

from homeassistant.components.discovery import SERVICE_WEMO
from homeassistant.helpers import discovery
from homeassistant.helpers import config_validation as cv

from homeassistant.const import EVENT_HOMEASSISTANT_STOP

REQUIREMENTS = ['pywemo==0.4.28']

DOMAIN = 'wemo'

# Mapping from Wemo model_name to component.
WEMO_MODEL_DISPATCH = {
    'Bridge':  'light',
    'CoffeeMaker': 'switch',
    'Dimmer': 'light',
    'Insight': 'switch',
    'LightSwitch': 'switch',
    'Maker':   'switch',
    'Motion': 'binary_sensor',
    'Sensor':  'binary_sensor',
    'Socket':  'switch'
}

SUBSCRIPTION_REGISTRY = None
KNOWN_DEVICES = []

_LOGGER = logging.getLogger(__name__)

CONF_STATIC = 'static'

CONFIG_SCHEMA = vol.Schema({
    DOMAIN: vol.Schema({
        vol.Optional(CONF_STATIC, default=[]): vol.Schema([cv.string])
    }),
}, extra=vol.ALLOW_EXTRA)

def setup(hass, config):
    """Set up for WeMo devices."""
    import pywemo

    global SUBSCRIPTION_REGISTRY
    SUBSCRIPTION_REGISTRY = pywemo.SubscriptionRegistry()
    SUBSCRIPTION_REGISTRY.start()

    def stop_wemo(event):
        """Shutdown Wemo subscriptions and subscription thread on exit."""
        _LOGGER.info("Shutting down subscriptions.")
        SUBSCRIPTION_REGISTRY.stop()

    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_wemo)

    def discovery_dispatch(service, discovery_info):
        """Dispatcher for WeMo discovery events."""
        # name, model, location, mac
        model_name = discovery_info.get('model_name')
        serial = discovery_info.get('serial')

        # Only register a device once
        if serial in KNOWN_DEVICES:
            return
        _LOGGER.debug('Discovered unique device %s', serial)
        KNOWN_DEVICES.append(serial)

        component = WEMO_MODEL_DISPATCH.get(model_name, 'switch')

        discovery.load_platform(hass, component, DOMAIN, discovery_info,
                                config)

    discovery.listen(hass, SERVICE_WEMO, discovery_dispatch)

    _LOGGER.info("Scanning for WeMo devices.")
    devices = [(device.host, device) for device in pywemo.discover_devices()]

    # Add static devices from the config file.
    devices.extend((address, None)
                   for address in config.get(DOMAIN, {}).get(CONF_STATIC, []))

    for address, device in devices:
        port = pywemo.ouimeaux_device.probe_wemo(address)
        if not port:
            _LOGGER.warning('Unable to probe wemo at %s', address)
            continue
        _LOGGER.info('Adding wemo at %s:%i', address, port)

        url = 'http://%s:%i/setup.xml' % (address, port)
        if device is None:
            device = pywemo.discovery.device_from_description(url, None)

        discovery_info = {
            'model_name': device.model_name,
            'serial': device.serialnumber,
            'mac_address': device.mac,
            'ssdp_description': url,
        }

        discovery.discover(hass, SERVICE_WEMO, discovery_info)
    return True
<|endoftext|>


<commit_before>from alembic import util
from alembic.context import get_context
from sqlalchemy.types import NULLTYPE
from sqlalchemy import schema

__all__ = [
            'alter_column',
            'create_foreign_key',
            'create_unique_constraint',
            'execute']

def alter_column(table_name, column_name,
                    nullable=util.NO_VALUE,
                    server_default=util.NO_VALUE,
                    name=util.NO_VALUE,
                    type_=util.NO_VALUE
):
    """Issue ALTER COLUMN using the current change context."""

    context.alter_column(table_name, column_name,
        nullable=nullable,
        server_default=server_default,
        name=name,
        type_=type_
    )

def _foreign_key_constraint(name, source, referent, local_cols, remote_cols):
    m = schema.MetaData()
    t1 = schema.Table(source, m,
            *[schema.Column(n, NULLTYPE) for n in local_cols])
    t2 = schema.Table(referent, m,
            *[schema.Column(n, NULLTYPE) for n in remote_cols])

    f = schema.ForeignKeyConstraint(local_cols,
                                        ["%s.%s" % (referent, name)
                                        for name in remote_cols],
                                        name=name
                                        )
    t1.append_constraint(f)

    return f

def _unique_constraint(name, source, local_cols):
    t = schema.Table(source, schema.MetaData(),
                *[schema.Column(n, NULLTYPE) for n in local_cols])
    return schema.UniqueConstraint(*t.c, name=name)

def _table(name, *columns, **kw):
    m = schema.MetaData()
    t = schema.Table(name, m, *columns, **kw)
    for f in t._foreign_keys:
        _ensure_table_for_fk(m, f)
    return t

def _ensure_table_for_fk(metadata, fk):
    """create a placeholder Table object for the referent of a
    ForeignKey.

    """
    if isinstance(fk._colspec, basestring):
        table_key, cname = fk._colspec.split('.')
        if '.' in table_key:
            tokens = tname.split('.')
            sname = ".".join(tokens[0:-1])
            tname = tokens[-1]
        else:
            tname = table_key
            sname = None
        if table_key not in metadata.tables:
            rel_t = schema.Table(tname, metadata, schema=sname)
        else:
            rel_t = metadata.tables[table_key]
        if not rel_t.c.contains_column(cname):
            rel_t.append_column(schema.Column(cname, NULLTYPE))

def create_foreign_key(name, source, referent, local_cols, remote_cols):
    get_context().add_constraint(
                _foreign_key_constraint(source, referent, local_cols, remote_cols)
            )

def create_unique_constraint(name, source, local_cols):
    get_context().add_constraint(
                _unique_constraint(name, source, local_cols)
            )

def create_table(name, *columns, **kw):
    get_context().create_table(
        _table(name, *columns, **kw)
    )

def execute(sql):
    get_context().execute(sql)<commit_msg>use public foreign keys collection<commit_after>from alembic import util
from alembic.context import get_context
from sqlalchemy.types import NULLTYPE
from sqlalchemy import schema

__all__ = [
            'alter_column',
            'create_foreign_key',
            'create_unique_constraint',
            'execute']

def alter_column(table_name, column_name,
                    nullable=util.NO_VALUE,
                    server_default=util.NO_VALUE,
                    name=util.NO_VALUE,
                    type_=util.NO_VALUE
):
    """Issue ALTER COLUMN using the current change context."""

    context.alter_column(table_name, column_name,
        nullable=nullable,
        server_default=server_default,
        name=name,
        type_=type_
    )

def _foreign_key_constraint(name, source, referent, local_cols, remote_cols):
    m = schema.MetaData()
    t1 = schema.Table(source, m,
            *[schema.Column(n, NULLTYPE) for n in local_cols])
    t2 = schema.Table(referent, m,
            *[schema.Column(n, NULLTYPE) for n in remote_cols])

    f = schema.ForeignKeyConstraint(local_cols,
                                        ["%s.%s" % (referent, name)
                                        for name in remote_cols],
                                        name=name
                                        )
    t1.append_constraint(f)

    return f

def _unique_constraint(name, source, local_cols):
    t = schema.Table(source, schema.MetaData(),
                *[schema.Column(n, NULLTYPE) for n in local_cols])
    return schema.UniqueConstraint(*t.c, name=name)

def _table(name, *columns, **kw):
    m = schema.MetaData()
    t = schema.Table(name, m, *columns, **kw)
    for f in t.foreign_keys:
        _ensure_table_for_fk(m, f)
    return t

def _ensure_table_for_fk(metadata, fk):
    """create a placeholder Table object for the referent of a
    ForeignKey.

    """
    if isinstance(fk._colspec, basestring):
        table_key, cname = fk._colspec.split('.')
        if '.' in table_key:
            tokens = tname.split('.')
            sname = ".".join(tokens[0:-1])
            tname = tokens[-1]
        else:
            tname = table_key
            sname = None
        if table_key not in metadata.tables:
            rel_t = schema.Table(tname, metadata, schema=sname)
        else:
            rel_t = metadata.tables[table_key]
        if not rel_t.c.contains_column(cname):
            rel_t.append_column(schema.Column(cname, NULLTYPE))

def create_foreign_key(name, source, referent, local_cols, remote_cols):
    get_context().add_constraint(
                _foreign_key_constraint(source, referent, local_cols, remote_cols)
            )

def create_unique_constraint(name, source, local_cols):
    get_context().add_constraint(
                _unique_constraint(name, source, local_cols)
            )

def create_table(name, *columns, **kw):
    get_context().create_table(
        _table(name, *columns, **kw)
    )

def execute(sql):
    get_context().execute(sql)<|endoftext|>


<commit_before>
from fractions import Fraction as F
from itertools import count, islice, izip, chain, repeat
from functools import partial
from math import floor

from MemoizedGenerator import MemoizedGenerator

def repeated(func, n):
    def ret(x):
        return reduce( lambda x,func: func(x) , repeat(func, n), x )
    return ret

class PowerSeries(object):
    testlimit = 5

    def __init__(self, g=None):
        self.__g = g

    def __eq__(self, entry):
        return all(s == e for s,e in islice(izip(self,entry), self.testlimit))

    def __iter__( self ):
        return chain(self.__g(), repeat(0)) if self.__g else repeat(0)

    def __str__(self):
        return self.getstr()

    def getstr(self, num=None):
        def gen_str():
            is_pps = any( isinstance(term, PowerSeries) for term in islice(self, num or self.testlimit ) )
            for term in islice(self, num if num else self.testlimit):
                if is_pps:
                    yield term.getstr(num) + "\n"
                else:
                    yield str(term) + ", "

        return "".join(gen_str()) + "..."

    def deep_apply( self, func, n=1 ):
        if n == 0:
            return func(self)

        if n == 1:
            @MemoizedGenerator
            def _deep_apply():
                for term in self:
                    yield func(term)
        else:
            @MemoizedGenerator
            def _deep_apply():
                for term in self:
                    yield term.deep_apply( func, n-1 )

        return PowerSeries( _deep_apply )

    def deep_map( self, func ):
        @MemoizedGenerator
        def _deep_map():
            for term in self:
                if not isinstance(term, PowerSeries):
                    yield func(term)
                else:
                    yield term.deep_map( func )

        return PowerSeries(_deep_map)

    def get_tail( self ):
        @MemoizedGenerator
        def _tail():
            for term in islice(self, 1, None):
                yield term

        return PowerSeries(_tail)

    @property
    def zero(self):
        return get_zero(self)

    @property
    def tail(self):
        return self.get_tail()

    @property
    def xmul(self):
        @MemoizedGenerator
        def _xmul():
            yield 0
            for term in self:
                yield term

        return PowerSeries(_xmul)

    def __add__(self, entry):
        if is_powerseries(entry):
            @MemoizedGenerator
            def _add():
                for term1, term2 in izip(self, entry):
                    yield term1 + term2
        else:
            @MemoizedGenerator
            def _add():
                it = iter(self)
                yield next(it) + entry

                for term in it:
                    yield term

        return PowerSeries(_add)

    def __mul__(self, entry):
        if not is_powerseries(entry):
            if entry == 1:
                return self
            elif entry == 0 and not is_powerseries(self.zero):
                return PowerSeries()
            else:
                return self.deep_apply( lambda x: x*entry )

        @MemoizedGenerator
        def _mul():
            f0 = self.zero
            g0 = entry.zero
            yield f0 * g0

            F = self.tail
            G = entry.tail

            r1 = 0
            mterms = [F * G]
            if is_powerseries(f0) or f0 != 0:
                f0G = G.deep_apply( lambda x: f0*x )
                r1 += f0G.zero
                mterms.append(f0G.tail)
            if is_powerseries(g0) or g0 != 0:
                g0F = F.deep_apply( lambda x: g0*x )
                r1 += g0F.zero
                mterms.append(g0F.tail)

            yield r1

            for terms in izip(*mterms):
                yield sum(terms)

        return PowerSeries(_mul)

    def __rdiv__(self, entry):
        """

        >>> B = 1 / (1 - X - X*Y)
        >>> 1/B == 1-X-X*Y
        True

        """

        if is_powerseries(entry):
            return entry * (1/self)

        @MemoizedGenerator
        def _rdiv():
            f0 = self.zero
            if is_powerseries(f0):
                recip = entry / f0
            elif f0 == 1:
                recip = entry
            else:
                recip = F(entry, f0)

            yield recip

            for term in ( (self.tail * R).deep_apply( lambda x: -x*recip ) ):
                yield term

        R = PowerSeries(_rdiv)
        return R

    def __radd__(self, entry):
        return self + entry

    def __sub__(self, entry):
        return self + (-entry)

    def __rsub__(self, entry):
        return entry + (-self)

    def __neg__(self):
        return self.deep_apply( lambda x: -x )

    def __rmul__(self, entry):
        return self * entry

    def __div__(self, entry):
        if is_powerseries(entry):
            return self * (1 / entry)
        elif entry == 1:
            return self
        else:
            return self * F(1, entry)

    def __pow__( self, alpha ):
        """

        >>> X*X == X**2
        True

        >>> log((1/(1+X))**(F(3,2))) == -F(3,2)*log(1+X)
        True

        >>> exp( X + 3*Y )**F(-4,7) == exp( -F(4,7) * (X + 3*Y) )
        True

        """

        f0 = self.zero
        if not is_powerseries(f0) and f0 == 0:
            if floor(alpha) == alpha:
                @MemoizedGenerator
                def _pow():
                    for e in repeat(0, alpha):
                        yield e
                    for term in self.tail ** alpha:
                        yield term

                return PowerSeries(_pow)
            else:
                raise ValueError("Can't raise powerseries with vanishing first term to non integer power")

        c0 = self.zero**alpha if is_powerseries(self.zero) or self.zero != 1 else 1

        @MemoizedGenerator
        def _pow():
            for term in integral(alpha * P * D(self)/ self, c0 ):
                yield term

        P = PowerSeries(_pow)
        return P

    def __call__( self, *args ):
        """

        >>> (1/(1-X-X*Y))(X,X) == 1/(1-X-X**2)
        True

        >>> A = exp(X)
        >>> B = log(1/(1-X))
        >>> A(B) == 1/(1-X)
        True

        >>> (1/(1-X-X*Y))(Y,X) == 1/(1-Y-Y*X)
        True

        >>> (1/(1-X-Z))(X,Y,X*Y) == 1/(1-X-X*Y)
        True

        >>> (1/(1-X))(Y) == 1/(1-Y)
        True

        """

        n = len(args)

        try:
            k,a = next( ( (k,a) for k,a in enumerate(args) if not is_powerseries(a) ) )

            if a == 0:
                if n > 1:
                    return self.deep_apply( get_zero, k )( *(args[:k] + args[k+1:]) )
                else:
                    return self.zero
            else:
                raise ValueError("Can't calculate powerseries at non-zero value")

        except StopIteration:
            pass

        @MemoizedGenerator
        def _compose():
            c0 = self.deep_apply(get_zero, n)( *map( get_zero, args ) )

            G = ( self.deep_apply( D, k ) for k in xrange(len(args)) )
            F = map( D, args )

            r = sum( g(*args) * f for g,f in izip(G, F) ) + self.deep_apply( D, n )(*args)
            for term in integral(r, c0):
                yield term

        return PowerSeries(_compose)

def is_powerseries( entry ):
    return isinstance(entry, PowerSeries)

def get_zero( d ):
    if is_powerseries(d):
        for term in d:
            return term
    else:
        return d

def D( f ):
    if not is_powerseries(f):
        return 0
    @MemoizedGenerator
    def _D():
        for n,term in enumerate(f.tail):
            yield (n+1) * term

    return PowerSeries(_D)

def linsolve( M, B ):
    for n,b in enumerate(B):
        print "b"
        print b
    for n,e in enumerate(M):
        inv = 1/e[n]
        s = [ u*inv for u in e ]
        for m,d in enumerate(M):
            if m == n:
                continue

            M[m] = [ t - r*d[n] for t,r in izip(d, s) ]
            B[m] = B[m] - inv*B[n]

    for n,e in enumerate(M):
        for m, r in enumerate(e):
            print "n, m", n, m
            print r

    for n,b in enumerate(B):
        print "b"
        print b

    return B

def solve( *args ):
    """

    """
    n = len(args)

    get_n_zero = repeated( get_zero, n )

    print "START"
    for a in args:
        print a
    print "START ENDE"

    if any( not is_powerseries(get_n_zero(a)) for a in args ):
        if all( get_n_zero(a) == 0 for a in args ):
            return (PowerSeries(),)*n
        else:
            raise ValueError("No solution")

    c0s = solve( *[ a.deep_apply( get_zero, n ) for a in args ] )
    print "REC RES: "
    for c in c0s:
        print c

    m = [ [ a.deep_apply( D, k ) for k in xrange(n) ] for a in args ]
    b = [   -a.deep_apply( D, n ) for a in args ]

    dfs = linsolve( m, b )
    print "DFS"
    for df in dfs:
        print df
        print df(-Y)
    print "DFS ENDE"

    SOL = []
    for i in xrange(n):
        def _solve(i=i):
            for term in integral( dfs[i](*SOL), c0s[i] ):
                yield term

        SOL.append(PowerSeries(_solve))

    return tuple(SOL)

def integral( f, const=0 ):
    @MemoizedGenerator
    def _int():
        yield const
        for n, term in enumerate(f):
            yield F(1,n+1)*term

    return PowerSeries(_int)

def tensor( f1, f2 ):
    return f1.deep_map( lambda x: f2*x )

def exp( f ):
    """

    >>> e = exp(X)
    >>> e == D(e)
    True
    >>> e == integral(e, 1)
    True
    >>> log(e) == X
    True
    >>> d = exp(3*X*X)
    >>> d*e == exp(X + 3*X*X)
    True

    """
    f0 = f.zero
    if is_powerseries( f0 ):
        c0 = exp(f0)
    elif f0 == 0:
        c0 = 1
    else:
        raise ValueError("Can't take exp of powerseries with non-zero constant term")

    @MemoizedGenerator
    def _exp():
        for term in integral( E * D(f), c0 ):
            yield term

    E = PowerSeries(_exp)
    return E

def log( f ):
    """

    >>> l = log(1+X)
    >>> 3*l == log((1+X)*(1+X)*(1+X))
    True
    >>> D(l) == 1/(1+X)
    True

    """
    f0 = f.zero
    if is_powerseries( f0 ):
        c0 = log(f0)
    elif f0 == 1:
        c0 = 0
    else:
        raise ValueError("Can't take log of powerseries with non-unit constant term")

    @MemoizedGenerator
    def _log():
        for term in integral( D(f)/f, c0 ):
            yield term

    return PowerSeries(_log)

I = 1 + PowerSeries()
X = I.xmul
Y = tensor(I, X)
Z = tensor(I, Y)

if __name__ == '__main__':
    import doctest
    doctest.testmod()

<commit_msg>Working and __init__.py added<commit_after>
from fractions import Fraction as F
from itertools import count, islice, izip, chain, repeat, imap
from functools import partial
from math import floor

from MemoizedGenerator import MemoizedGenerator

def repeated(func, n):
    def ret(x):
        return reduce( lambda x,func: func(x) , repeat(func, n), x )
    return ret

class PowerSeries(object):
    testlimit = 5

    def __init__(self, g=None):
        self.__g = g

    def __eq__(self, entry):
        return all(s == e for s,e in islice(izip(self,entry), self.testlimit))

    def __iter__( self ):
        return chain(self.__g(), repeat(0)) if self.__g else repeat(0)

    def __str__(self):
        return self.getstr()

    def getstr(self, num=None):
        def gen_str():
            is_pps = any( isinstance(term, PowerSeries) for term in islice(self, num or self.testlimit ) )
            for term in islice(self, num if num else self.testlimit):
                if is_pps:
                    yield term.getstr(num) + "\n"
                else:
                    yield str(term) + ", "

        return "".join(gen_str()) + "..."

    def deep_apply( self, func, n=1 ):
        if n == 0:
            return func(self)

        if n == 1:
            @MemoizedGenerator
            def _deep_apply():
                for term in self:
                    yield func(term)
        else:
            @MemoizedGenerator
            def _deep_apply():
                for term in self:
                    yield term.deep_apply( func, n-1 )

        return PowerSeries( _deep_apply )

    def deep_map( self, func ):
        @MemoizedGenerator
        def _deep_map():
            for term in self:
                if not isinstance(term, PowerSeries):
                    yield func(term)
                else:
                    yield term.deep_map( func )

        return PowerSeries(_deep_map)

    def get_tail( self ):
        @MemoizedGenerator
        def _tail():
            for term in islice(self, 1, None):
                yield term

        return PowerSeries(_tail)

    @property
    def zero(self):
        return get_zero(self)

    @property
    def tail(self):
        return self.get_tail()

    @property
    def xmul(self):
        @MemoizedGenerator
        def _xmul():
            yield 0
            for term in self:
                yield term

        return PowerSeries(_xmul)

    def __add__(self, entry):
        if is_powerseries(entry):
            @MemoizedGenerator
            def _add():
                for term1, term2 in izip(self, entry):
                    yield term1 + term2
        else:
            @MemoizedGenerator
            def _add():
                it = iter(self)
                yield next(it) + entry

                for term in it:
                    yield term

        return PowerSeries(_add)

    def __mul__(self, entry):
        if not is_powerseries(entry):
            if entry == 1:
                return self
            elif entry == 0 and not is_powerseries(self.zero):
                return PowerSeries()
            else:
                return self.deep_apply( lambda x: x*entry )

        @MemoizedGenerator
        def _mul():
            f0 = self.zero
            g0 = entry.zero
            yield f0 * g0

            F = self.tail
            G = entry.tail

            r1 = 0
            mterms = [F * G]
            if is_powerseries(f0) or f0 != 0:
                f0G = G.deep_apply( lambda x: f0*x )
                r1 += f0G.zero
                mterms.append(f0G.tail)
            if is_powerseries(g0) or g0 != 0:
                g0F = F.deep_apply( lambda x: g0*x )
                r1 += g0F.zero
                mterms.append(g0F.tail)

            yield r1

            for terms in izip(*mterms):
                yield sum(terms)

        return PowerSeries(_mul)

    def __rdiv__(self, entry):
        """

        >>> B = 1 / (1 - X - X*Y)
        >>> 1/B == 1-X-X*Y
        True

        """

        if is_powerseries(entry):
            return entry * (1/self)

        @MemoizedGenerator
        def _rdiv():
            f0 = self.zero
            if is_powerseries(f0):
                recip = entry / f0
            elif f0 == 1:
                recip = entry
            else:
                recip = F(entry, f0)

            yield recip

            for term in ( (self.tail * R).deep_apply( lambda x: -x*recip ) ):
                yield term

        R = PowerSeries(_rdiv)
        return R

    def __radd__(self, entry):
        return self + entry

    def __sub__(self, entry):
        return self + (-entry)

    def __rsub__(self, entry):
        return entry + (-self)

    def __neg__(self):
        return self.deep_apply( lambda x: -x )

    def __rmul__(self, entry):
        return self * entry

    def __div__(self, entry):
        if is_powerseries(entry):
            return self * (1 / entry)
        elif entry == 1:
            return self
        else:
            return self * F(1, entry)

    def __pow__( self, alpha ):
        """

        >>> X*X == X**2
        True

        >>> log((1/(1+X))**(F(3,2))) == -F(3,2)*log(1+X)
        True

        >>> exp( X + 3*Y )**F(-4,7) == exp( -F(4,7) * (X + 3*Y) )
        True

        """

        f0 = self.zero
        if not is_powerseries(f0) and f0 == 0:
            if floor(alpha) == alpha:
                @MemoizedGenerator
                def _pow():
                    for e in repeat(0, alpha):
                        yield e
                    for term in self.tail ** alpha:
                        yield term

                return PowerSeries(_pow)
            else:
                raise ValueError("Can't raise powerseries with vanishing first term to non integer power")

        c0 = self.zero**alpha if is_powerseries(self.zero) or self.zero != 1 else 1

        @MemoizedGenerator
        def _pow():
            for term in integral(alpha * P * D(self)/ self, c0 ):
                yield term

        P = PowerSeries(_pow)
        return P

    def __call__( self, *args ):
        """

        >>> (1/(1-X-X*Y))(X,X) == 1/(1-X-X**2)
        True

        >>> A = exp(X)
        >>> B = log(1/(1-X))
        >>> A(B) == 1/(1-X)
        True

        >>> (1/(1-X-X*Y))(Y,X) == 1/(1-Y-Y*X)
        True

        >>> (1/(1-X-X*Y))(Y) == 1/(1-Y-Y*X)
        True

        >>> (1/(1-X-Z))(X,Y,X*Y) == 1/(1-X-X*Y)
        True

        >>> (1/(1-X))(Y) == 1/(1-Y)
        True

        """

        n = len(args)

        try:
            k,a = next( ( (k,a) for k,a in enumerate(args) if not is_powerseries(a) ) )

            if a == 0:
                if n > 1:
                    return self.deep_apply( get_zero, k )( *(args[:k] + args[k+1:]) )
                else:
                    return self.zero
            else:
                raise ValueError("Can't calculate powerseries at non-zero value")

        except StopIteration:
            pass

        @MemoizedGenerator
        def _compose():
            c0 = self.deep_apply(get_zero, n)( *map( get_zero, args ) )

            G = ( self.deep_apply( D, k ) for k in xrange(n) )
            F = imap( D, args )

            r = sum( g.deep_apply(lambda x, f=f: f*x, n) for g,f in izip(G, F) ) + self.deep_apply( D, n )
            for term in integral(r(*args), c0):
                yield term

        return PowerSeries(_compose)

def is_powerseries( entry ):
    return isinstance(entry, PowerSeries)

def get_zero( d ):
    if is_powerseries(d):
        for term in d:
            return term
    else:
        return d

def D( f ):
    if not is_powerseries(f):
        return 0
    @MemoizedGenerator
    def _D():
        for n,term in enumerate(f.tail):
            yield (n+1) * term

    return PowerSeries(_D)

def linsolve( M, B ):
    for n,b in enumerate(B):
        print "b"
        print b
    for n,e in enumerate(M):
        inv = 1/e[n]
        s = [ u*inv for u in e ]
        for m,d in enumerate(M):
            if m == n:
                continue

            M[m] = [ t - r*d[n] for t,r in izip(d, s) ]
            B[m] = B[m] - inv*B[n]

    for n,e in enumerate(M):
        for m, r in enumerate(e):
            print "n, m", n, m
            print r

    for n,b in enumerate(B):
        print "b"
        print b

    return B

def solve( *args ):
    """

    """
    n = len(args)

    get_n_zero = repeated( get_zero, n )

    print "START"
    for a in args:
        print a
    print "START ENDE"

    if any( not is_powerseries(get_n_zero(a)) for a in args ):
        if all( get_n_zero(a) == 0 for a in args ):
            return (PowerSeries(),)*n
        else:
            raise ValueError("No solution")

    c0s = solve( *[ a.deep_apply( get_zero, n ) for a in args ] )
    print "REC RES: "
    for c in c0s:
        print c

    m = [ [ a.deep_apply( D, k ) for k in xrange(n) ] for a in args ]
    b = [   -a.deep_apply( D, n ) for a in args ]

    dfs = linsolve( m, b )
    print "DFS"
    for df in dfs:
        print df
        print df(-Y)
    print "DFS ENDE"

    SOL = []
    for i in xrange(n):
        def _solve(i=i):
            for term in integral( dfs[i](*SOL), c0s[i] ):
                yield term

        SOL.append(PowerSeries(_solve))

    return tuple(SOL)

def integral( f, const=0 ):
    @MemoizedGenerator
    def _int():
        yield const
        for n, term in enumerate(f):
            yield F(1,n+1)*term

    return PowerSeries(_int)

def tensor( f1, f2 ):
    return f1.deep_map( lambda x: f2*x )

def exp( f ):
    """

    >>> e = exp(X)
    >>> e == D(e)
    True
    >>> e == integral(e, 1)
    True
    >>> log(e) == X
    True
    >>> d = exp(3*X*X)
    >>> d*e == exp(X + 3*X*X)
    True

    """
    f0 = f.zero
    if is_powerseries( f0 ):
        c0 = exp(f0)
    elif f0 == 0:
        c0 = 1
    else:
        raise ValueError("Can't take exp of powerseries with non-zero constant term")

    @MemoizedGenerator
    def _exp():
        for term in integral( E * D(f), c0 ):
            yield term

    E = PowerSeries(_exp)
    return E

def log( f ):
    """

    >>> l = log(1+X)
    >>> 3*l == log((1+X)*(1+X)*(1+X))
    True
    >>> D(l) == 1/(1+X)
    True

    """
    f0 = f.zero
    if is_powerseries( f0 ):
        c0 = log(f0)
    elif f0 == 1:
        c0 = 0
    else:
        raise ValueError("Can't take log of powerseries with non-unit constant term")

    @MemoizedGenerator
    def _log():
        for term in integral( D(f)/f, c0 ):
            yield term

    return PowerSeries(_log)

I = 1 + PowerSeries()
X = I.xmul
Y = tensor(I, X)
Z = tensor(I, Y)

if __name__ == '__main__':
    import doctest
    doctest.testmod()

<|endoftext|>


<commit_before># coding: utf-8
import os
import sys
import time
import atexit
import shutil
import tempfile
import unittest
import threading
from warnings import catch_warnings
from contextlib import closing, contextmanager

from flask import Flask
from werkzeug.exceptions import NotFound

from flask.ext.makestatic import MakeStatic, RuleMissing
from flask.ext.makestatic.watcher import ThreadedWatcher

TEST_APPS = os.path.join(os.path.dirname(__file__), 'test_apps')
sys.path.insert(0, TEST_APPS)

def get_temporary_filename():
    filename = tempfile.mkstemp()[1]
    @atexit.register
    def remove_file():
        try:
            os.remove(filename)
        except EnvironmentError:
            pass
    return filename

def get_temporary_directory():
    directory = tempfile.mkdtemp()
    @atexit.register
    def remove_directory():
        try:
            shutil.rmtree(directory)
        except EnvironmentError:
            pass
    return directory

def bump_modification_time(path):
    stat = os.stat(path)
    os.utime(path, (stat.st_atime, stat.st_mtime + 1))

class MakeStaticTestCase(unittest.TestCase):
    def tearDown(self):
        for test_app_dir in os.listdir(TEST_APPS):
            static_dir = os.path.join(TEST_APPS, test_app_dir, 'static')
            if os.path.isdir(static_dir):
                for root, dirs, files in os.walk(static_dir):
                    for file in files:
                        if file == '.gitignore':
                            continue
                        os.remove(os.path.join(root, file))
                    for dir in dirs:
                        os.rmdir(os.path.join(root, dir))

    @contextmanager
    def make_static(self, import_name):
        app = Flask(import_name)
        make_static = MakeStatic(app)
        watcher = make_static.watch()
        try:
            yield app, make_static
        finally:
            watcher.stop()

    def test_send_static_file(self):
        with self.make_static('working') as (app, make_static):
            with app.test_request_context():
                with closing(app.send_static_file('foo')) as response:
                    self.assertEqual(response.status_code, 200)

                with closing(app.send_static_file('spam')) as response:
                    self.assertEqual(response.status_code, 200)

                with closing(app.send_static_file('bar')) as response:
                    self.assertEqual(response.status_code, 200)
                    response.direct_passthrough = False
                    self.assertEqual(response.data, b'abc\ndef\n')

                self.assertRaises(NotFound, app.send_static_file, 'baz')

    def test_static_view(self):
        with self.make_static('working') as (app, make_static):
            client = app.test_client()
            with closing(client.get('/static/foo')) as response:
                self.assertEqual(response.status_code, 200)

            with closing(client.get('/static/spam')) as response:
                self.assertEqual(response.status_code, 200)

            with closing(client.get('/static/bar')) as response:
                self.assertEqual(response.status_code, 200)
                self.assertEqual(response.data, b'abc\ndef\n')

            with closing(client.get('/static/baz')) as response:
                self.assertEqual(response.status_code, 404)

    def test_compile(self):
        app = Flask('working')
        make_static = MakeStatic(app)
        with app.app_context():
            make_static.compile()

        # ensure that app is not patched and assets are not compiled on demand
        app = Flask('working')
        client = app.test_client()
        with closing(client.get('/static/foo')) as response:
            self.assertEqual(response.status_code, 200)

        with closing(client.get('/static/spam')) as response:
            self.assertEqual(response.status_code, 200)

        with closing(client.get('/static/bar')) as response:
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.data, b'abc\ndef\n')

    def test_compile_warns_on_missing_rule(self):
        app = Flask('missing_rule')
        make_static = MakeStatic(app)
        with catch_warnings(record=True) as warnings:
            with app.app_context():
                make_static.compile()
        self.assertEqual(len(warnings), 1)
        self.assertTrue(issubclass(warnings[-1].category, RuleMissing))
        self.assertEqual(str(warnings[-1].message),
                         'cannot find a rule for foo.css')

class WatcherTestCase(unittest.TestCase):
    def assert_(self, **kwargs):
        self.assertEqual(self.added_files, kwargs.pop('added_files', []))
        del self.added_files[:]
        self.assertEqual(self.modified_files, kwargs.pop('modified_files', []))
        del self.modified_files[:]
        self.assertEqual(self.removed_files, kwargs.pop('removed_files', []))
        del self.removed_files[:]
        self.assertEqual(self.added_directories,
                         kwargs.pop('added_directories', []))
        del self.added_directories[:]
        self.assertEqual(self.modified_directories,
                         kwargs.pop('modified_directories', []))
        del self.modified_directories[:]
        self.assertEqual(self.removed_directories,
                         kwargs.pop('removed_directories', []))
        del self.removed_directories[:]

        if kwargs:
            raise TypeError(
                'unexpected keyword argument: %s' % kwargs.popitem()[0]
            )

    def test(self):
        watcher = ThreadedWatcher()
        self.added_files = []
        self.modified_files = []
        self.removed_files = []
        self.added_directories = []
        self.modified_directories = []
        self.removed_directories = []
        watcher.file_added.connect(self.added_files.append)
        watcher.file_modified.connect(self.modified_files.append)
        watcher.file_removed.connect(self.removed_files.append)
        watcher.directory_added.connect(self.added_directories.append)
        watcher.directory_modified.connect(self.modified_directories.append)
        watcher.directory_removed.connect(self.removed_directories.append)

        directory = get_temporary_directory()
        watcher.add_directory(directory)
        watcher.watch()

        foo = os.path.join(directory, 'foo')
        open(foo, 'w').close()
        time.sleep(0.15) # reasonable amount of reaction time
        self.assert_(added_files=[foo], modified_directories=[directory])

        bump_modification_time(foo)
        time.sleep(0.15)
        self.assert_(modified_files=[foo], modified_directories=[directory])

        os.remove(foo)
        time.sleep(0.15)
        self.assert_(removed_files=[foo], modified_directories=[directory])

        bar = os.path.join(directory, 'bar')
        os.mkdir(bar)
        time.sleep(0.15)
        self.assert_(added_directories=[bar], modified_directories=[directory])

        baz = os.path.join(bar, 'baz')
        open(baz, 'w').close()
        time.sleep(0.15)
        self.assert_(added_files=[baz], modified_directories=[bar])

        bump_modification_time(baz)
        time.sleep(0.15)
        self.assert_(modified_files=[baz], modified_directories=[bar])

        os.remove(baz)
        time.sleep(0.15)
        self.assert_(removed_files=[baz], modified_directories=[bar])

        os.rmdir(bar)
        time.sleep(0.15)
        self.assert_(removed_directories=[bar],
                     modified_directories=[directory])

        watcher.stop()
        time.sleep(0.15)
        self.assertEqual(threading.active_count(), 1)

def suite():
    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(MakeStaticTestCase))
    suite.addTest(unittest.makeSuite(WatcherTestCase))
    return suite

if __name__ == '__main__':
    unittest.main(defaultTest='suite')
<commit_msg>Use shorter sleep time in WatcherTestCase<commit_after># coding: utf-8
import os
import sys
import time
import atexit
import shutil
import tempfile
import unittest
import threading
from warnings import catch_warnings
from contextlib import closing, contextmanager

from flask import Flask
from werkzeug.exceptions import NotFound

from flask.ext.makestatic import MakeStatic, RuleMissing
from flask.ext.makestatic.watcher import ThreadedWatcher

TEST_APPS = os.path.join(os.path.dirname(__file__), 'test_apps')
sys.path.insert(0, TEST_APPS)

def get_temporary_filename():
    filename = tempfile.mkstemp()[1]
    @atexit.register
    def remove_file():
        try:
            os.remove(filename)
        except EnvironmentError:
            pass
    return filename

def get_temporary_directory():
    directory = tempfile.mkdtemp()
    @atexit.register
    def remove_directory():
        try:
            shutil.rmtree(directory)
        except EnvironmentError:
            pass
    return directory

def bump_modification_time(path):
    stat = os.stat(path)
    os.utime(path, (stat.st_atime, stat.st_mtime + 1))

class MakeStaticTestCase(unittest.TestCase):
    def tearDown(self):
        for test_app_dir in os.listdir(TEST_APPS):
            static_dir = os.path.join(TEST_APPS, test_app_dir, 'static')
            if os.path.isdir(static_dir):
                for root, dirs, files in os.walk(static_dir):
                    for file in files:
                        if file == '.gitignore':
                            continue
                        os.remove(os.path.join(root, file))
                    for dir in dirs:
                        os.rmdir(os.path.join(root, dir))

    @contextmanager
    def make_static(self, import_name):
        app = Flask(import_name)
        make_static = MakeStatic(app)
        watcher = make_static.watch()
        try:
            yield app, make_static
        finally:
            watcher.stop()

    def test_send_static_file(self):
        with self.make_static('working') as (app, make_static):
            with app.test_request_context():
                with closing(app.send_static_file('foo')) as response:
                    self.assertEqual(response.status_code, 200)

                with closing(app.send_static_file('spam')) as response:
                    self.assertEqual(response.status_code, 200)

                with closing(app.send_static_file('bar')) as response:
                    self.assertEqual(response.status_code, 200)
                    response.direct_passthrough = False
                    self.assertEqual(response.data, b'abc\ndef\n')

                self.assertRaises(NotFound, app.send_static_file, 'baz')

    def test_static_view(self):
        with self.make_static('working') as (app, make_static):
            client = app.test_client()
            with closing(client.get('/static/foo')) as response:
                self.assertEqual(response.status_code, 200)

            with closing(client.get('/static/spam')) as response:
                self.assertEqual(response.status_code, 200)

            with closing(client.get('/static/bar')) as response:
                self.assertEqual(response.status_code, 200)
                self.assertEqual(response.data, b'abc\ndef\n')

            with closing(client.get('/static/baz')) as response:
                self.assertEqual(response.status_code, 404)

    def test_compile(self):
        app = Flask('working')
        make_static = MakeStatic(app)
        with app.app_context():
            make_static.compile()

        # ensure that app is not patched and assets are not compiled on demand
        app = Flask('working')
        client = app.test_client()
        with closing(client.get('/static/foo')) as response:
            self.assertEqual(response.status_code, 200)

        with closing(client.get('/static/spam')) as response:
            self.assertEqual(response.status_code, 200)

        with closing(client.get('/static/bar')) as response:
            self.assertEqual(response.status_code, 200)
            self.assertEqual(response.data, b'abc\ndef\n')

    def test_compile_warns_on_missing_rule(self):
        app = Flask('missing_rule')
        make_static = MakeStatic(app)
        with catch_warnings(record=True) as warnings:
            with app.app_context():
                make_static.compile()
        self.assertEqual(len(warnings), 1)
        self.assertTrue(issubclass(warnings[-1].category, RuleMissing))
        self.assertEqual(str(warnings[-1].message),
                         'cannot find a rule for foo.css')

class WatcherTestCase(unittest.TestCase):
    def assert_(self, **kwargs):
        self.assertEqual(self.added_files, kwargs.pop('added_files', []))
        del self.added_files[:]
        self.assertEqual(self.modified_files, kwargs.pop('modified_files', []))
        del self.modified_files[:]
        self.assertEqual(self.removed_files, kwargs.pop('removed_files', []))
        del self.removed_files[:]
        self.assertEqual(self.added_directories,
                         kwargs.pop('added_directories', []))
        del self.added_directories[:]
        self.assertEqual(self.modified_directories,
                         kwargs.pop('modified_directories', []))
        del self.modified_directories[:]
        self.assertEqual(self.removed_directories,
                         kwargs.pop('removed_directories', []))
        del self.removed_directories[:]

        if kwargs:
            raise TypeError(
                'unexpected keyword argument: %s' % kwargs.popitem()[0]
            )

    def test(self):
        watcher = ThreadedWatcher()
        self.added_files = []
        self.modified_files = []
        self.removed_files = []
        self.added_directories = []
        self.modified_directories = []
        self.removed_directories = []
        watcher.file_added.connect(self.added_files.append)
        watcher.file_modified.connect(self.modified_files.append)
        watcher.file_removed.connect(self.removed_files.append)
        watcher.directory_added.connect(self.added_directories.append)
        watcher.directory_modified.connect(self.modified_directories.append)
        watcher.directory_removed.connect(self.removed_directories.append)

        directory = get_temporary_directory()
        watcher.add_directory(directory)
        watcher.watch(sleep=0.01)

        foo = os.path.join(directory, 'foo')
        open(foo, 'w').close()
        time.sleep(0.05) # reasonable amount of reaction time
        self.assert_(added_files=[foo], modified_directories=[directory])

        bump_modification_time(foo)
        time.sleep(0.05)
        self.assert_(modified_files=[foo], modified_directories=[directory])

        os.remove(foo)
        time.sleep(0.05)
        self.assert_(removed_files=[foo], modified_directories=[directory])

        bar = os.path.join(directory, 'bar')
        os.mkdir(bar)
        time.sleep(0.05)
        self.assert_(added_directories=[bar], modified_directories=[directory])

        baz = os.path.join(bar, 'baz')
        open(baz, 'w').close()
        time.sleep(0.05)
        self.assert_(added_files=[baz], modified_directories=[bar])

        bump_modification_time(baz)
        time.sleep(0.05)
        self.assert_(modified_files=[baz], modified_directories=[bar])

        os.remove(baz)
        time.sleep(0.05)
        self.assert_(removed_files=[baz], modified_directories=[bar])

        os.rmdir(bar)
        time.sleep(0.05)
        self.assert_(removed_directories=[bar],
                     modified_directories=[directory])

        watcher.stop()
        time.sleep(0.05)
        self.assertEqual(threading.active_count(), 1)

def suite():
    suite = unittest.TestSuite()
    suite.addTest(unittest.makeSuite(MakeStaticTestCase))
    suite.addTest(unittest.makeSuite(WatcherTestCase))
    return suite

if __name__ == '__main__':
    unittest.main(defaultTest='suite')
<|endoftext|>


<commit_before>import inspect
import dis
import os
from importlib.machinery import ExtensionFileLoader

from .function import InlineFunction, IFunction
from .inline import build_install_module

class InlineModule(object):

    def __init__(self, name):
        self._name = name
        self._functions = list()
        self._cpp_code = ''
        self._cpp_footer = ''

        self._create_footer()

    def _create_footer(self):
        module_def = 'static struct PyModuleDef inline_module = {\n'
        module_def += '    PyModuleDef_HEAD_INIT,\n'
        module_def += '    "%s",\n' % self._name
        module_def += '    nullptr,\n'
        module_def += '    -1,\n'
        module_def += '    module_functions_def\n'
        module_def += '};\n'

        module_init = 'PyMODINIT_FUNC PyInit_%s(void)\n' % self._name
        module_init += '{\n'
        module_init += '    PyObject* module = PyModule_Create(&inline_module);\n'
        module_init += '    if (module == nullptr)\n'
        module_init += '        return nullptr;\n'
        module_init += '    return module;\n'
        module_init += '}\n'

        self._cpp_footer = module_def + '\n\n' + module_init

    def add_function(self, inline_function):
        if not isinstance(inline_function, IFunction):
            inline_function = InlineFunction(inline_function)

        self._functions.append(inline_function)

        # Invalidate CPP code
        self._cpp_code = ''

    def get_cpp_code(self):
        if len(self._cpp_code) == 0:
            self._create_code()
        return self._cpp_code

    def _create_code(self):
        # Build include
        module_header = '''
        #include <Python.h>
        #include <pybind11/pybind11.h>

        namespace py = pybind11;
        '''

        # Merge code of all the functions
        function_code = ''
        for function in self._functions:
            function_code += function.get_code()
            function_code += '\n\n'

        # Build method definition
        function_def = 'static PyMethodDef module_functions_def[] = {\n'
        for function in self._functions:
            name = function.get_name()
            function_def += '    {"%s", reinterpret_cast<PyCFunction>(%s), METH_VARARGS | METH_KEYWORDS, nullptr},\n' % (name, name)
        function_def += '    {NULL, NULL, 0, NULL}\n'
        function_def += '};\n\n'

        # Merge all the code in a single source
        cpp_code = module_header + '\n\n'
        cpp_code += function_code + '\n\n'
        cpp_code += function_def + '\n\n'
        cpp_code += self._cpp_footer

        self._cpp_code = cpp_code

    def import_module(self, module_dir=None, silent=True):
        cpp_code = self.get_cpp_code()
        module_filename = build_install_module(cpp_code, self._name,
                                               module_dir=module_dir, silent=silent)

        if module_filename is None:
            raise ImportError('Module %s could not be load' % self._name)

        file_loader = ExtensionFileLoader(self._name, module_filename)
        imported_module = file_loader.load_module(self._name)
        return imported_module

<commit_msg>Working on initial implementation<commit_after>import inspect
import dis
import os
from importlib.machinery import ExtensionFileLoader

from .function import InlineFunction, IFunction
from .inline import build_install_module

class InlineModule(object):

    def __init__(self, name):
        self._name = name
        self._functions = list()
        self._cpp_code = ''
        self._cpp_footer = ''

        self._create_footer()

    def _create_footer(self):
        module_def = 'static struct PyModuleDef inline_module = {\n'
        module_def += '    PyModuleDef_HEAD_INIT,\n'
        module_def += '    "%s",\n' % self._name
        module_def += '    nullptr,\n'
        module_def += '    -1,\n'
        module_def += '    module_functions_def\n'
        module_def += '};\n'

        module_init = 'PyMODINIT_FUNC PyInit_%s(void)\n' % self._name
        module_init += '{\n'
        module_init += '    PyObject* module = PyModule_Create(&inline_module);\n'
        module_init += '    if (module == nullptr)\n'
        module_init += '        return nullptr;\n'
        module_init += '    return module;\n'
        module_init += '}\n'

        self._cpp_footer = module_def + '\n\n' + module_init

    def add_function(self, inline_function):
        if not isinstance(inline_function, IFunction):
            inline_function = InlineFunction(inline_function)

        self._functions.append(inline_function)

        # Invalidate CPP code
        self._cpp_code = ''

    def get_cpp_code(self):
        if len(self._cpp_code) == 0:
            self._create_code()
        return self._cpp_code

    def _create_code(self):
        # Build include
        module_header = '''
        #include <Python.h>
        #include <pybind11/pybind11.h>

        namespace py = pybind11;
        '''

        # Merge code of all the functions
        function_code = ''
        for function in self._functions:
            function_code += function.get_code()
            function_code += '\n\n'

        # Build method definition
        function_def = 'static PyMethodDef module_functions_def[] = {\n'
        for function in self._functions:
            name = function.get_name()
            function_def += '    {"%s", reinterpret_cast<PyCFunction>(%s), METH_VARARGS | METH_KEYWORDS, nullptr},\n' % (name, name)
        function_def += '    {NULL, NULL, 0, NULL}\n'
        function_def += '};\n\n'

        # Merge all the code in a single source
        cpp_code = module_header + '\n\n'
        cpp_code += function_code + '\n\n'
        cpp_code += function_def + '\n\n'
        cpp_code += self._cpp_footer

        self._cpp_code = cpp_code

    def import_module(self, module_dir=None, silent=True):
        cpp_code = self.get_cpp_code()
        module_filename = build_install_module(cpp_code, self._name,
                                               module_dir=module_dir, silent=silent)

        if module_filename is None:
            raise ImportError('Module %s could not be load' % self._name)

        file_loader = ExtensionFileLoader(self._name, module_filename)
        imported_module = file_loader.load_module(self._name)
        return imported_module
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  test_recoverstats.py
#
#  Copyright 2016 Bruno S <bruno.sanchez.63@gmail.com>
#

import os
import shlex
import subprocess

import numpy as np
import matplotlib.pyplot as plt

from astropy.io import fits

import propercoadd as pc

# =============================================================================
#     PSF measure test by propercoadd
# =============================================================================
datapath = os.path.abspath('/home/bruno/Documentos/reduccionTolar/20151212/Landolt_C53')

S = np.zeros((1365, 1365))

for root, dirs, files in os.walk(datapath):
    for afile in files:
        frame = os.path.join(root, afile)
        sim = pc.SingleImage(frame, imagefile=True)
        s_comp = sim.s_component()

        S += s_comp

test_dir = os.path.abspath('./test_images/real_coadd_test/')

plt.figure(figsize=(16,16))
plt.imshow(np.log10(S), interpolation='none')
plt.colorbar(orientation='horizontal')
plt.savefig(os.path.join(test_dir, 'S.png'))
plt.close()

<commit_msg>prepared test<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  test_recoverstats.py
#
#  Copyright 2016 Bruno S <bruno.sanchez.63@gmail.com>
#

import os
import shlex
import subprocess

import numpy as np
import matplotlib.pyplot as plt

from astropy.io import fits

import propercoadd as pc

# =============================================================================
#     PSF measure test by propercoadd
# =============================================================================
datapath = os.path.abspath('/home/bruno/Documentos/reduccionTolar/20151212/Landolt_C53')

S = np.zeros((1365, 1365))

for root, dirs, files in os.walk(datapath):
    ensemble = pc.ImageEnsemble(files)
    S = ensemble.calculate_S(n_procs=8)

test_dir = os.path.abspath('./test_images/real_coadd_test/')

plt.figure(figsize=(16,16))
plt.imshow(np.log10(S), interpolation='none')
plt.colorbar(orientation='horizontal')
plt.savefig(os.path.join(test_dir, 'S.png'))
plt.close()

<|endoftext|>


<commit_before>'''imports the command for generating random numbers'''
from random import randint
print("\n==========Program Start==========")
"""common Lines and zeroing"""
invalid=("\nInvalid selection please try again")
plsEn="Please enter an option:"
"""Rule and table placeholder base"""
class nomod(object):
	ruleCheck=False
	def n(self):
		print("\nNo %s Module Loaded" % str(self.checkName))
		return
"""Rule and Table Placeholders"""
class attributeRolls(nomod):
	def __init__(self):
		self.checkName="Dice Module"
	def moduleCheck(self):
		return self.n()
	def statRolls(self):
		return self.n()
	def displayStatResults(self):
		return self.n()
dice=attributeRolls()
class raceRules(nomod):
	def __init__(self):
		self.checkName="Race Module"
race=raceRules()
print("==========Checking Modules==========")
'''config file check that handles imports goes here, until them import will just go here'''
from pp_module_diceRule import dice
#from pp_module_raceRule import race
print("")
dice.moduleCheck()
'''importing like in the following line does not work except for singular instances, just for reference'''
#import pp_module_diceRule
'''rule check method goes here, referenced later for checks'''
def rulecheck(s):
	if s.ruleCheck==True:
		ruleCheck=True
		print("%s Rules: Present and %s." % (s.checkName, s.ruleCheck))
		return
	elif s.ruleCheck==False:
		print("%s Rules: Not Present and %s, please select" % (s.checkName, s.ruleCheck))
		return
print("")
"""Rule Checks"""
"""Referenced Immediately and as option 5 of overmenu"""
"""checks to make sure rule has been loaded by checking 'ruleCheck' variable in each class using 'rulecheck' method created earlier in the prototype main file"""
def ruleCheckList():
	rulecheck(dice)
	rulecheck(race)
	return
ruleCheckList()
def charmenu():
	print("\n==========Character Generation==========\n\n[1] Display Current Character Information\n[2] Roll for Attributes\n[/] or [t] Main Menu\n[*] or [q] Quit Program")
	menuSel=str(input(plsEn))
	if (menuSel=="t")or(menuSel=="/"):
		return mainmenu()
	elif menuSel=="1":
		dice.displayStatResults()
		return charmenu()
	elif menuSel=="2":
		dice.statRolls()
		return charmenu()
	elif (menuSel=="*")or(menuSel=="q"):
		return quit()
	else:
		print(invalid)
		return charmenu()
	#character Generation
	#needs several options
	#option-1 is appearance
	#option-2 is dice rolls
def utilitymenu():
	print("\n==========Utilities==========\n\n[/] or [t] Main Menu\n[*] or [q] Quit Program")
	#dice.statRolls()
	menuSel=str(input(plsEn))
	if (menuSel=="t")or(menuSel=="/"):
		return mainmenu()
	elif (menuSel=="*")or(menuSel=="q"):
		return quit()
	else:
		print(invalid)
		return utilitymenu()
def optionsmenu():
	print("\n==========Options==========\n\n[/] or [t] Main Menu\n[*] or [q] Quit Program")
	#dice.statRolls()
	menuSel=str(input(plsEn))
	if (menuSel=="t")or(menuSel=="/"):
		return mainmenu()
	elif (menuSel=="*")or(menuSel=="q"):
		return quit()
	else:
		print(invalid)
		return optionsmenu()
def mainmenu():
	print("\n==========Main Menu==========\n\n[1] Character Generation\n[2] Utilities\n[3] Options\n[4] check imports\n[*] or [q] Quit Program")
	menuSel =str(input(plsEn))

	if (menuSel=="t")or(menuSel=="/"):
		return mainmenu()
	elif menuSel=="1":
		return charmenu()
	elif menuSel=="2":
		return utilitymenu()
	elif menuSel=="3":
		return optionsmenu()
	elif menuSel=="4":
		print("You selected %s Check Imports\n"  % menuSel)
		ruleCheckList()
		return mainmenu()
	elif (menuSel=="*")or(menuSel=="q"):
		return quit()
	else:
		print(invalid)
		return mainmenu()
def quit():
	print("\nQuitting Program")
	input("Press Enter to close the program")
mainmenu()
input("Nothing left to run, press Enter to close the program")<commit_msg>Learned about raw_input and fixed code<commit_after>'''imports the command for generating random numbers'''
from random import randint
print("\n==========Program Start==========")
"""common Lines and zeroing"""
menuSel="string"
invalid=("\nInvalid selection please try again")
plsEn="Please enter an option:"
"""Rule and table placeholder base"""
class nomod(object):
	ruleCheck=False
	def n(self):
		print("\nNo %s Module Loaded" % str(self.checkName))
		return
"""Rule and Table Placeholders"""
class attributeRolls(nomod):
	def __init__(self):
		self.checkName="Dice Module"
	def moduleCheck(self):
		return self.n()
	def statRolls(self):
		return self.n()
	def displayStatResults(self):
		return self.n()
dice=attributeRolls()
class raceRules(nomod):
	def __init__(self):
		self.checkName="Race Module"
race=raceRules()
print("==========Checking Modules==========")
'''config file check that handles imports goes here, until them import will just go here'''
from pp_module_diceRule import dice
#from pp_module_raceRule import race
print("")
dice.moduleCheck()
'''importing like in the following line does not work except for singular instances, just for reference'''
#import pp_module_diceRule
'''rule check method goes here, referenced later for checks'''
def rulecheck(s):
	if s.ruleCheck==True:
		ruleCheck=True
		print("%s Rules: Present and %s." % (s.checkName, s.ruleCheck))
		return
	elif s.ruleCheck==False:
		print("%s Rules: Not Present and %s, please select" % (s.checkName, s.ruleCheck))
		return
print("")
"""Rule Checks"""
"""Referenced Immediately and as option 5 of overmenu"""
"""checks to make sure rule has been loaded by checking 'ruleCheck' variable in each class using 'rulecheck' method created earlier in the prototype main file"""
def ruleCheckList():
	rulecheck(dice)
	rulecheck(race)
	return
ruleCheckList()
def charmenu():
	print("\n==========Character Generation==========\n\n[1] Display Current Character Information\n[2] Roll for Attributes\n[/] or [t] Main Menu\n[*] or [q] Quit Program")
	menuSel=raw_input(plsEn)
	if (menuSel=="t")or(menuSel=="/"):
		return mainmenu()
	elif menuSel=="1":
		dice.displayStatResults()
		return charmenu()
	elif menuSel=="2":
		dice.statRolls()
		return charmenu()
	elif (menuSel=="*")or(menuSel=="q"):
		return quit()
	else:
		print(invalid)
		return charmenu()
	#character Generation
	#needs several options
	#option-1 is appearance
	#option-2 is dice rolls
def utilitymenu():
	print("\n==========Utilities==========\n\n[/] or [t] Main Menu\n[*] or [q] Quit Program")
	#dice.statRolls()
	menuSel=raw_input(plsEn)
	if (menuSel=="t")or(menuSel=="/"):
		return mainmenu()
	elif (menuSel=="*")or(menuSel=="q"):
		return quit()
	else:
		print(invalid)
		return utilitymenu()
def optionsmenu():
	print("\n==========Options==========\n\n[/] or [t] Main Menu\n[*] or [q] Quit Program")
	#dice.statRolls()
	menuSel=raw_input(plsEn)
	if (menuSel=="t")or(menuSel=="/"):
		return mainmenu()
	elif (menuSel=="*")or(menuSel=="q"):
		return quit()
	else:
		print(invalid)
		return optionsmenu()
def mainmenu():
	print("\n==========Main Menu==========\n\n[1] Character Generation\n[2] Utilities\n[3] Options\n[4] check imports\n[*] or [q] Quit Program")
	menuSel=raw_input(plsEn)
	if (menuSel=="t")or(menuSel=="/"):
		return mainmenu()
	elif menuSel=="1":
		return charmenu()
	elif menuSel=="2":
		return utilitymenu()
	elif menuSel=="3":
		return optionsmenu()
	elif menuSel=="4":
		print("You selected %s Check Imports\n"  % menuSel)
		ruleCheckList()
		return mainmenu()
	elif (menuSel=="*")or(menuSel=="q"):
		return quit()
	else:
		print(invalid)
		return mainmenu()
def quit():
	print("\nQuitting Program")
	raw_input("Press Enter to close the program")
mainmenu()
raw_input("Nothing left to run, press Enter to close the program")<|endoftext|>