<commit_before>"""
kombu.serialization
===================

Serialization utilities.

:copyright: (c) 2009 - 2012 by Ask Solem
:license: BSD, see LICENSE for more details.

"""
from __future__ import absolute_import

import codecs
import sys

import pickle as pypickle
try:
    import cPickle as cpickle
except ImportError:  # pragma: no cover
    cpickle = None  # noqa

from .exceptions import SerializerNotInstalled
from .utils.encoding import bytes_to_str, str_to_bytes, bytes_t

__all__ = ['pickle', 'encode', 'decode',
           'register', 'unregister']
SKIP_DECODE = frozenset(['binary', 'ascii-8bit'])

if sys.platform.startswith('java'):  # pragma: no cover

    def _decode(t, coding):
        return codecs.getdecoder(coding)(t)[0]
else:
    _decode = codecs.decode

if sys.version_info < (2, 6):  # pragma: no cover
    # cPickle is broken in Python <= 2.5.
    # It unsafely and incorrectly uses relative instead of absolute
    # imports,
    # so e.g.:
    #       exceptions.KeyError
    # becomes:
    #       kombu.exceptions.KeyError
    #
    # Your best choice is to upgrade to Python 2.6,
    # as while the pure pickle version has worse performance,
    # it is the only safe option for older Python versions.
    pickle = pypickle
    pickle_load = pypickle.load
    pickle_loads = pypickle.loads
else:
    pickle = cpickle or pypickle
    pickle_load = pickle.load
    pickle_loads = pickle.loads

# cPickle.loads does not support buffer() objects,
# but we can just create a StringIO and use load.
if sys.version_info[0] == 3:
    from io import StringIO
else:
    try:
        from cStringIO import StringIO  # noqa
    except ImportError:
        from StringIO import StringIO   # noqa

def pickle_loads(s, load=pickle_load):
    return load(StringIO(s))

class SerializerRegistry(object):
    """The registry keeps track of serialization methods."""

    def __init__(self):
        self._encoders = {}
        self._decoders = {}
        self._default_encode = None
        self._default_content_type = None
        self._default_content_encoding = None
        self._disabled_content_types = set()
        self.type_to_name = {}

    def register(self, name, encoder, decoder, content_type,
                 content_encoding='utf-8'):
        if encoder:
            self._encoders[name] = (content_type, content_encoding, encoder)
        if decoder:
            self._decoders[content_type] = decoder
        self.type_to_name[content_type] = name

    def disable(self, name):
        if '/' not in name:
            name, _, _ = self._encoders[name]
        self._disabled_content_types.add(name)

    def unregister(self, name):
        try:
            content_type = self._encoders[name][0]
            self._decoders.pop(content_type, None)
            self._encoders.pop(name, None)
            self.type_to_name.pop(content_type, None)
        except KeyError:
            raise SerializerNotInstalled(
                'No encoder/decoder installed for %s' % name)

    def _set_default_serializer(self, name):
        """
        Set the default serialization method used by this library.

        :param name: The name of the registered serialization method.
            For example, `json` (default), `pickle`, `yaml`, `msgpack`,
            or any custom methods registered using :meth:`register`.

        :raises SerializerNotInstalled: If the serialization method
            requested is not available.
        """
        try:
            (self._default_content_type, self._default_content_encoding,
             self._default_encode) = self._encoders[name]
        except KeyError:
            raise SerializerNotInstalled(
                'No encoder installed for %s' % name)

    def encode(self, data, serializer=None):
        if serializer == 'raw':
            return raw_encode(data)
        if serializer and not self._encoders.get(serializer):
            raise SerializerNotInstalled(
                        'No encoder installed for %s' % serializer)

        # If a raw string was sent, assume binary encoding
        # (it's likely either ASCII or a raw binary file, and a character
        # set of 'binary' will encompass both, even if not ideal.
        if not serializer and isinstance(data, bytes_t):
            # In Python 3+, this would be "bytes"; allow binary data to be
            # sent as a message without getting encoder errors
            return 'application/data', 'binary', data

        # For Unicode objects, force it into a string
        if not serializer and isinstance(data, unicode):
            payload = data.encode('utf-8')
            return 'text/plain', 'utf-8', payload

        if serializer:
            content_type, content_encoding, encoder = \
                    self._encoders[serializer]
        else:
            encoder = self._default_encode
            content_type = self._default_content_type
            content_encoding = self._default_content_encoding

        payload = encoder(data)
        return content_type, content_encoding, payload

    def decode(self, data, content_type, content_encoding, force=False):
        if content_type in self._disabled_content_types and not force:
            raise SerializerNotInstalled(
                'Content-type %r has been disabled.' % (content_type, ))
        content_type = content_type or 'application/data'
        content_encoding = (content_encoding or 'utf-8').lower()

        if data:
            decode = self._decoders.get(content_type)
            if decode:
                return decode(data)
            if content_encoding not in SKIP_DECODE and \
                    not isinstance(data, unicode):
                return _decode(data, content_encoding)
        return data

"""
.. data:: registry

Global registry of serializers/deserializers.

"""
registry = SerializerRegistry()

"""
.. function:: encode(data, serializer=default_serializer)

    Serialize a data structure into a string suitable for sending
    as an AMQP message body.

    :param data: The message data to send. Can be a list,
        dictionary or a string.

    :keyword serializer: An optional string representing
        the serialization method you want the data marshalled
        into. (For example, `json`, `raw`, or `pickle`).

        If :const:`None` (default), then json will be used, unless
        `data` is a :class:`str` or :class:`unicode` object. In this
        latter case, no serialization occurs as it would be
        unnecessary.

        Note that if `serializer` is specified, then that
        serialization method will be used even if a :class:`str`
        or :class:`unicode` object is passed in.

    :returns: A three-item tuple containing the content type
        (e.g., `application/json`), content encoding, (e.g.,
        `utf-8`) and a string containing the serialized
        data.

    :raises SerializerNotInstalled: If the serialization method
            requested is not available.
"""
encode = registry.encode

"""
.. function:: decode(data, content_type, content_encoding):

    Deserialize a data stream as serialized using `encode`
    based on `content_type`.

    :param data: The message data to deserialize.

    :param content_type: The content-type of the data.
        (e.g., `application/json`).

    :param content_encoding: The content-encoding of the data.
        (e.g., `utf-8`, `binary`, or `us-ascii`).

    :returns: The unserialized data.

"""
decode = registry.decode

"""
.. function:: register(name, encoder, decoder, content_type,
                       content_encoding='utf-8'):
    Register a new encoder/decoder.

    :param name: A convenience name for the serialization method.

    :param encoder: A method that will be passed a python data structure
        and should return a string representing the serialized data.
        If :const:`None`, then only a decoder will be registered. Encoding
        will not be possible.

    :param decoder: A method that will be passed a string representing
        serialized data and should return a python data structure.
        If :const:`None`, then only an encoder will be registered.
        Decoding will not be possible.

    :param content_type: The mime-type describing the serialized
        structure.

    :param content_encoding: The content encoding (character set) that
        the `decoder` method will be returning. Will usually be
        utf-8`, `us-ascii`, or `binary`.

"""
register = registry.register

"""
.. function:: unregister(name):
    Unregister registered encoder/decoder.

    :param name: Registered serialization method name.

"""
unregister = registry.unregister

def raw_encode(data):
    """Special case serializer."""
    content_type = 'application/data'
    payload = data
    if isinstance(payload, unicode):
        content_encoding = 'utf-8'
        payload = payload.encode(content_encoding)
    else:
        content_encoding = 'binary'
    return content_type, content_encoding, payload

def register_json():
    """Register a encoder/decoder for JSON serialization."""
    from anyjson import loads, dumps

    def _loads(obj):
        if isinstance(obj, buffer):
            obj = str(obj)
        return loads(bytes_to_str(obj))

    registry.register('json', dumps, _loads,
                      content_type='application/json',
                      content_encoding='utf-8')

def register_yaml():
    """Register a encoder/decoder for YAML serialization.

    It is slower than JSON, but allows for more data types
    to be serialized. Useful if you need to send data such as dates"""
    try:
        import yaml
        registry.register('yaml', yaml.safe_dump, yaml.safe_load,
                          content_type='application/x-yaml',
                          content_encoding='utf-8')
    except ImportError:

        def not_available(*args, **kwargs):
            """In case a client receives a yaml message, but yaml
            isn't installed."""
            raise SerializerNotInstalled(
                'No decoder installed for YAML. Install the PyYAML library')
        registry.register('yaml', None, not_available, 'application/x-yaml')

if sys.version_info[0] == 3:

    def unpickle(s):
        return pickle_loads(str_to_bytes(s))

else:
    unpickle = pickle_loads  # noqa

def register_pickle():
    """The fastest serialization method, but restricts
    you to python clients."""
    registry.register('pickle', pickle.dumps, unpickle,
                      content_type='application/x-python-serialize',
                      content_encoding='binary')

def register_msgpack():
    """See http://msgpack.sourceforge.net/"""
    try:
        import msgpack
        registry.register('msgpack', msgpack.packs, msgpack.unpacks,
                content_type='application/x-msgpack',
                content_encoding='binary')
    except ImportError:

        def not_available(*args, **kwargs):
            """In case a client receives a msgpack message, but yaml
            isn't installed."""
            raise SerializerNotInstalled(
                    'No decoder installed for msgpack. '
                    'Install the msgpack library')
        registry.register('msgpack', None, not_available,
                          'application/x-msgpack')

# Register the base serialization methods.
register_json()
register_pickle()
register_yaml()
register_msgpack()

# JSON is assumed to always be available, so is the default.
# (this matches the historical use of kombu.)
registry._set_default_serializer('json')
<commit_msg>PEP8ify<commit_after>"""
kombu.serialization
===================

Serialization utilities.

:copyright: (c) 2009 - 2012 by Ask Solem
:license: BSD, see LICENSE for more details.

"""
from __future__ import absolute_import

import codecs
import sys

import pickle as pypickle
try:
    import cPickle as cpickle
except ImportError:  # pragma: no cover
    cpickle = None  # noqa

from .exceptions import SerializerNotInstalled
from .utils.encoding import bytes_to_str, str_to_bytes, bytes_t

__all__ = ['pickle', 'encode', 'decode',
           'register', 'unregister']
SKIP_DECODE = frozenset(['binary', 'ascii-8bit'])

if sys.platform.startswith('java'):  # pragma: no cover

    def _decode(t, coding):
        return codecs.getdecoder(coding)(t)[0]
else:
    _decode = codecs.decode

if sys.version_info < (2, 6):  # pragma: no cover
    # cPickle is broken in Python <= 2.5.
    # It unsafely and incorrectly uses relative instead of absolute
    # imports,
    # so e.g.:
    #       exceptions.KeyError
    # becomes:
    #       kombu.exceptions.KeyError
    #
    # Your best choice is to upgrade to Python 2.6,
    # as while the pure pickle version has worse performance,
    # it is the only safe option for older Python versions.
    pickle = pypickle
    pickle_load = pypickle.load
    pickle_loads = pypickle.loads
else:
    pickle = cpickle or pypickle
    pickle_load = pickle.load
    pickle_loads = pickle.loads

# cPickle.loads does not support buffer() objects,
# but we can just create a StringIO and use load.
if sys.version_info[0] == 3:
    from io import StringIO
else:
    try:
        from cStringIO import StringIO  # noqa
    except ImportError:
        from StringIO import StringIO   # noqa

def pickle_loads(s, load=pickle_load):
    return load(StringIO(s))

class SerializerRegistry(object):
    """The registry keeps track of serialization methods."""

    def __init__(self):
        self._encoders = {}
        self._decoders = {}
        self._default_encode = None
        self._default_content_type = None
        self._default_content_encoding = None
        self._disabled_content_types = set()
        self.type_to_name = {}

    def register(self, name, encoder, decoder, content_type,
                 content_encoding='utf-8'):
        if encoder:
            self._encoders[name] = (content_type, content_encoding, encoder)
        if decoder:
            self._decoders[content_type] = decoder
        self.type_to_name[content_type] = name

    def disable(self, name):
        if '/' not in name:
            name, _, _ = self._encoders[name]
        self._disabled_content_types.add(name)

    def unregister(self, name):
        try:
            content_type = self._encoders[name][0]
            self._decoders.pop(content_type, None)
            self._encoders.pop(name, None)
            self.type_to_name.pop(content_type, None)
        except KeyError:
            raise SerializerNotInstalled(
                'No encoder/decoder installed for %s' % name)

    def _set_default_serializer(self, name):
        """
        Set the default serialization method used by this library.

        :param name: The name of the registered serialization method.
            For example, `json` (default), `pickle`, `yaml`, `msgpack`,
            or any custom methods registered using :meth:`register`.

        :raises SerializerNotInstalled: If the serialization method
            requested is not available.
        """
        try:
            (self._default_content_type, self._default_content_encoding,
             self._default_encode) = self._encoders[name]
        except KeyError:
            raise SerializerNotInstalled(
                'No encoder installed for %s' % name)

    def encode(self, data, serializer=None):
        if serializer == 'raw':
            return raw_encode(data)
        if serializer and not self._encoders.get(serializer):
            raise SerializerNotInstalled(
                        'No encoder installed for %s' % serializer)

        # If a raw string was sent, assume binary encoding
        # (it's likely either ASCII or a raw binary file, and a character
        # set of 'binary' will encompass both, even if not ideal.
        if not serializer and isinstance(data, bytes_t):
            # In Python 3+, this would be "bytes"; allow binary data to be
            # sent as a message without getting encoder errors
            return 'application/data', 'binary', data

        # For Unicode objects, force it into a string
        if not serializer and isinstance(data, unicode):
            payload = data.encode('utf-8')
            return 'text/plain', 'utf-8', payload

        if serializer:
            content_type, content_encoding, encoder = \
                    self._encoders[serializer]
        else:
            encoder = self._default_encode
            content_type = self._default_content_type
            content_encoding = self._default_content_encoding

        payload = encoder(data)
        return content_type, content_encoding, payload

    def decode(self, data, content_type, content_encoding, force=False):
        if content_type in self._disabled_content_types and not force:
            raise SerializerNotInstalled(
                'Content-type %r has been disabled.' % (content_type, ))
        content_type = content_type or 'application/data'
        content_encoding = (content_encoding or 'utf-8').lower()

        if data:
            decode = self._decoders.get(content_type)
            if decode:
                return decode(data)
            if content_encoding not in SKIP_DECODE and \
                    not isinstance(data, unicode):
                return _decode(data, content_encoding)
        return data

"""
.. data:: registry

Global registry of serializers/deserializers.

"""
registry = SerializerRegistry()

"""
.. function:: encode(data, serializer=default_serializer)

    Serialize a data structure into a string suitable for sending
    as an AMQP message body.

    :param data: The message data to send. Can be a list,
        dictionary or a string.

    :keyword serializer: An optional string representing
        the serialization method you want the data marshalled
        into. (For example, `json`, `raw`, or `pickle`).

        If :const:`None` (default), then json will be used, unless
        `data` is a :class:`str` or :class:`unicode` object. In this
        latter case, no serialization occurs as it would be
        unnecessary.

        Note that if `serializer` is specified, then that
        serialization method will be used even if a :class:`str`
        or :class:`unicode` object is passed in.

    :returns: A three-item tuple containing the content type
        (e.g., `application/json`), content encoding, (e.g.,
        `utf-8`) and a string containing the serialized
        data.

    :raises SerializerNotInstalled: If the serialization method
            requested is not available.
"""
encode = registry.encode

"""
.. function:: decode(data, content_type, content_encoding):

    Deserialize a data stream as serialized using `encode`
    based on `content_type`.

    :param data: The message data to deserialize.

    :param content_type: The content-type of the data.
        (e.g., `application/json`).

    :param content_encoding: The content-encoding of the data.
        (e.g., `utf-8`, `binary`, or `us-ascii`).

    :returns: The unserialized data.

"""
decode = registry.decode

"""
.. function:: register(name, encoder, decoder, content_type,
                       content_encoding='utf-8'):
    Register a new encoder/decoder.

    :param name: A convenience name for the serialization method.

    :param encoder: A method that will be passed a python data structure
        and should return a string representing the serialized data.
        If :const:`None`, then only a decoder will be registered. Encoding
        will not be possible.

    :param decoder: A method that will be passed a string representing
        serialized data and should return a python data structure.
        If :const:`None`, then only an encoder will be registered.
        Decoding will not be possible.

    :param content_type: The mime-type describing the serialized
        structure.

    :param content_encoding: The content encoding (character set) that
        the `decoder` method will be returning. Will usually be
        utf-8`, `us-ascii`, or `binary`.

"""
register = registry.register

"""
.. function:: unregister(name):
    Unregister registered encoder/decoder.

    :param name: Registered serialization method name.

"""
unregister = registry.unregister

def raw_encode(data):
    """Special case serializer."""
    content_type = 'application/data'
    payload = data
    if isinstance(payload, unicode):
        content_encoding = 'utf-8'
        payload = payload.encode(content_encoding)
    else:
        content_encoding = 'binary'
    return content_type, content_encoding, payload

def register_json():
    """Register a encoder/decoder for JSON serialization."""
    from anyjson import loads, dumps

    def _loads(obj):
        if isinstance(obj, buffer):
            obj = str(obj)
        return loads(bytes_to_str(obj))

    registry.register('json', dumps, _loads,
                      content_type='application/json',
                      content_encoding='utf-8')

def register_yaml():
    """Register a encoder/decoder for YAML serialization.

    It is slower than JSON, but allows for more data types
    to be serialized. Useful if you need to send data such as dates"""
    try:
        import yaml
        registry.register('yaml', yaml.safe_dump, yaml.safe_load,
                          content_type='application/x-yaml',
                          content_encoding='utf-8')
    except ImportError:

        def not_available(*args, **kwargs):
            """In case a client receives a yaml message, but yaml
            isn't installed."""
            raise SerializerNotInstalled(
                'No decoder installed for YAML. Install the PyYAML library')
        registry.register('yaml', None, not_available, 'application/x-yaml')

if sys.version_info[0] == 3:

    def unpickle(s):
        return pickle_loads(str_to_bytes(s))

else:
    unpickle = pickle_loads  # noqa

def register_pickle():
    """The fastest serialization method, but restricts
    you to python clients."""
    registry.register('pickle', pickle.dumps, unpickle,
                      content_type='application/x-python-serialize',
                      content_encoding='binary')

def register_msgpack():
    """See http://msgpack.sourceforge.net/"""
    try:
        import msgpack
        registry.register('msgpack', msgpack.packs, msgpack.unpacks,
                content_type='application/x-msgpack',
                content_encoding='binary')
    except ImportError:

        def not_available(*args, **kwargs):
            """In case a client receives a msgpack message, but yaml
            isn't installed."""
            raise SerializerNotInstalled(
                    'No decoder installed for msgpack. '
                    'Install the msgpack library')
        registry.register('msgpack', None, not_available,
                          'application/x-msgpack')

# Register the base serialization methods.
register_json()
register_pickle()
register_yaml()
register_msgpack()

# JSON is assumed to always be available, so is the default.
# (this matches the historical use of kombu.)
registry._set_default_serializer('json')
<|endoftext|>


<commit_before>import logging

from itertools import combinations
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings

from queue.consumer import SingleChannel, QueueConsumer

log = logging.getLogger(__name__)

class NoAssignmentError(Exception):
    pass

def assign_workers_to_queues(queues, number_of_workers, workers_per_queue, minimum_disjoint_workers):
    """
    Returns a map of queues to worker ids (integers in range(number_of_workers))

    The function guarantees that each queue is assigned to workers_per_queue workers,
    and that each pair of queues has at least minimum_disjoint_workers workers
    that are distinct. This ensures that if one queue is overloaded, the other queues will
    still have active workers.

    If no such assignment is possible, then will raise NoAssignmentError
    """
    workers = range(number_of_workers)
    num_queues = len(queues)

    possible_assignments = (set(combo) for combo in combinations(workers, workers_per_queue))
    queue_assignments = []
    for next_assignment in possible_assignments:
        if len(queue_assignments) >= num_queues:
            break

        if min([len(next_assignment - old) for old in queue_assignments] + [workers_per_queue]) >= minimum_disjoint_workers:
            queue_assignments.append(next_assignment)

    if len(queue_assignments) < num_queues:
        raise NoAssignmentError()

    return dict(zip(queues, queue_assignments))

def assign_queues_to_workers(num_workers, queue_assignments):
    """
    Takes a dictionary mapping queues to workers for those queues, and converts
    it to a set of queues assigned to each worker

    queue_assignments: Dict from queue -> worker ids (ints)
    """
    worker_assignments = [set() for worker in range(num_workers)]
    for queue, assignment in queue_assignments.items():
        for worker in assignment:
            worker_assignments[worker].add(queue)

    return worker_assignments

class Command(BaseCommand):
    args = "<worker count>"
    help = "Listens to all queues specified as being push-queues in the django configuration with <worker count> threads"

    def handle(self, *args, **options):
        log.info(' [*] Starting queue consumers...')

        channels = []
        queues = [
            QueueConsumer(push_url, queue_name)
            for (queue_name, push_url)
            in settings.XQUEUES.items()
            if push_url is not None
        ]

        workers_per_queue = settings.XQUEUE_WORKERS_PER_QUEUE
        num_workers = settings.WORKER_COUNT

        assignments = None
        for min_disjoint_workers in range(workers_per_queue / 2, 0, -1):
            try:
                queue_assignments = assign_workers_to_queues(queues, num_workers, workers_per_queue, min_disjoint_workers)
                assignments = assign_queues_to_workers(num_workers, queue_assignments)

                break
            except NoAssignmentError:
                continue

        if assignments is None:
            raise CommandError("Unable to assign workers to queues with constraints: workers_per_queue=%d, num_workers=%d" % (workers_per_queue, num_workers))

        for wid, queues in enumerate(assignments):
            channel = SingleChannel(wid, queues)
            channel.start()
            channels.append(channel)

        # TODO (cpennington): Manage this so that if a subset of workers die, we figure that out and restart
        for channel in channels:
            channel.join()

        log.info(' [*] All workers finished. Exiting')
<commit_msg>Always try with 1 minimum disjoint worker<commit_after>import logging

from itertools import combinations
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings

from queue.consumer import SingleChannel, QueueConsumer

log = logging.getLogger(__name__)

class NoAssignmentError(Exception):
    pass

def assign_workers_to_queues(queues, number_of_workers, workers_per_queue, minimum_disjoint_workers):
    """
    Returns a map of queues to worker ids (integers in range(number_of_workers))

    The function guarantees that each queue is assigned to workers_per_queue workers,
    and that each pair of queues has at least minimum_disjoint_workers workers
    that are distinct. This ensures that if one queue is overloaded, the other queues will
    still have active workers.

    If no such assignment is possible, then will raise NoAssignmentError
    """
    workers = range(number_of_workers)
    num_queues = len(queues)

    possible_assignments = (set(combo) for combo in combinations(workers, workers_per_queue))
    queue_assignments = []
    for next_assignment in possible_assignments:
        if len(queue_assignments) >= num_queues:
            break

        if min([len(next_assignment - old) for old in queue_assignments] + [workers_per_queue]) >= minimum_disjoint_workers:
            queue_assignments.append(next_assignment)

    if len(queue_assignments) < num_queues:
        raise NoAssignmentError()

    return dict(zip(queues, queue_assignments))

def assign_queues_to_workers(num_workers, queue_assignments):
    """
    Takes a dictionary mapping queues to workers for those queues, and converts
    it to a set of queues assigned to each worker

    queue_assignments: Dict from queue -> worker ids (ints)
    """
    worker_assignments = [set() for worker in range(num_workers)]
    for queue, assignment in queue_assignments.items():
        for worker in assignment:
            worker_assignments[worker].add(queue)

    return worker_assignments

class Command(BaseCommand):
    args = "<worker count>"
    help = "Listens to all queues specified as being push-queues in the django configuration with <worker count> threads"

    def handle(self, *args, **options):
        log.info(' [*] Starting queue consumers...')

        channels = []
        queues = [
            QueueConsumer(push_url, queue_name)
            for (queue_name, push_url)
            in settings.XQUEUES.items()
            if push_url is not None
        ]

        workers_per_queue = settings.XQUEUE_WORKERS_PER_QUEUE
        num_workers = settings.WORKER_COUNT

        assignments = None
        for min_disjoint_workers in range(max(workers_per_queue / 2, 1), 0, -1):
            try:
                queue_assignments = assign_workers_to_queues(queues, num_workers, workers_per_queue, min_disjoint_workers)
                assignments = assign_queues_to_workers(num_workers, queue_assignments)

                break
            except NoAssignmentError:
                continue

        if assignments is None:
            raise CommandError("Unable to assign workers to queues with constraints: workers_per_queue=%d, num_workers=%d" % (workers_per_queue, num_workers))

        for wid, queues in enumerate(assignments):
            channel = SingleChannel(wid, queues)
            channel.start()
            channels.append(channel)

        # TODO (cpennington): Manage this so that if a subset of workers die, we figure that out and restart
        for channel in channels:
            channel.join()

        log.info(' [*] All workers finished. Exiting')
<|endoftext|>


<commit_before>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import jinja2
import flask

import views

class Krempelair(flask.Flask):
    jinja_options = {
        'extensions': ['jinja2.ext.autoescape'],
        'undefined': jinja2.StrictUndefined
    }

    def __init__(self):
        """(See `make_app` for parameter descriptions.)"""
        flask.Flask.__init__(self, __name__)

        self.setup_routes()

    def create_jinja_environment(self):
        """Called by Flask.__init__"""
        env = super(Krempelair, self).create_jinja_environment()
        for func in [
            'force_unicode',
            'timesince',
            'shorten_sha1',
            'shorten_message',
            'extract_author_name',
            'formattimestamp',
        ]:
            env.filters[func] = getattr(utils, func)

        return env

    def setup_routes(self):
        for endpoint, rule in [
            # Getter der Temperaturen und des Betriebsstatus
            ('air_get_status_betrieb',   '/'),
            ('air_get_status_stoerung',   '/stoerung'),
            ('air_get_temperaturen', '/lueftung/temperatur'),

            # Setters für Funktionen
            ('air_set_level', '/lueftung/stufe/<int:level>'),
            ('air_set_timer', '/lueftung/timer/<int:time>'),
            ('air_set_tempSoll', '/lueftung/temperatur/sollTemp/<int:temp>'),
            ('air_set_tempNAK', '/lueftung/temperatur/sollTempNAK/<int:temp>'),
            ('air_set_NAK', '/lueftung/NAK/<int:NAK>'),
        ]:
            self.add_url_rule(rule, view_func=getattr(views, endpoint))

if __name__ == "__main__":
    app = Krempelair()
    app.run(host="0.0.0.0", debug=True)
else:
    application = Krempelair()
<commit_msg>Update __init__.py<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import jinja2
import flask

import views

class Krempelair(flask.Flask):
    jinja_options = {
        'extensions': ['jinja2.ext.autoescape'],
        'undefined': jinja2.StrictUndefined
    }

    def __init__(self):
        """(See `make_app` for parameter descriptions.)"""
        flask.Flask.__init__(self, __name__)

        self.setup_routes()

    def create_jinja_environment(self):
        """Called by Flask.__init__"""
        env = super(Krempelair, self).create_jinja_environment()
        for func in [
            'force_unicode',
            'timesince',
            'shorten_sha1',
            'shorten_message',
            'extract_author_name',
            'formattimestamp',
        ]:
            env.filters[func] = getattr(utils, func)

        return env

    def setup_routes(self):
        for endpoint, rule in [
            #Allgemeine Funktionen
            ('air_login',   '/login'),

            # Getter der Temperaturen und des Betriebsstatus
            ('air_get_status_betrieb',   '/'),
            ('air_get_status_stoerung',   '/stoerung'),
            ('air_get_temperaturen', '/lueftung/temperatur'),

            # Setters für Funktionen
            ('air_set_level', '/lueftung/stufe/<int:level>'),
            ('air_set_timer', '/lueftung/timer/<int:time>'),
            ('air_set_tempSoll', '/lueftung/temperatur/sollTemp/<int:temp>'),
            ('air_set_tempNAK', '/lueftung/temperatur/sollTempNAK/<int:temp>'),
            ('air_set_NAK', '/lueftung/NAK/<int:NAK>'),
        ]:
            self.add_url_rule(rule, view_func=getattr(views, endpoint))

if __name__ == "__main__":
    app = Krempelair()
    app.run(host="0.0.0.0", debug=True)
else:
    application = Krempelair()
<|endoftext|>


<commit_before>config.load_autoconfig()

default_bg = "#F5F6F7"
alt_bg = "#d9dde0"
default_fg = "#444444"
alt_fg = "#888888"
orange = "#F27835"
red = "#F04A50"
cyan = "#2E96C0"
blue = "#5294e2"
green = "#60942C"

# set qutebrowser colors

# Text color of the completion widget. May be a single color to use for
# all columns or a list of three colors, one for each column.
c.colors.completion.fg = default_fg

# Background color of the completion widget for odd rows.
c.colors.completion.odd.bg = default_bg

# Background color of the completion widget for even rows.
c.colors.completion.even.bg = default_bg

# Foreground color of completion widget category headers.
c.colors.completion.category.fg = blue

# Background color of the completion widget category headers.
c.colors.completion.category.bg = alt_bg

# Top border color of the completion widget category headers.
c.colors.completion.category.border.top = alt_bg

# Bottom border color of the completion widget category headers.
c.colors.completion.category.border.bottom = alt_bg

# Foreground color of the selected completion item.
c.colors.completion.item.selected.fg = default_fg

# Background color of the selected completion item.
c.colors.completion.item.selected.bg = alt_bg

# Top border color of the completion widget category headers.
c.colors.completion.item.selected.border.top = alt_bg

# Bottom border color of the selected completion item.
c.colors.completion.item.selected.border.bottom = alt_bg

# Foreground color of the matched text in the completion.
c.colors.completion.match.fg = blue

# Color of the scrollbar handle in the completion view.
c.colors.completion.scrollbar.fg = alt_fg

# Color of the scrollbar in the completion view.
c.colors.completion.scrollbar.bg = default_bg

# Background color for the download bar.
c.colors.downloads.bar.bg = default_bg

# Color gradient start for download text.
c.colors.downloads.start.fg = default_bg

# Color gradient start for download backgrounds.
c.colors.downloads.start.bg = blue

# Color gradient end for download text.
c.colors.downloads.stop.fg = default_bg

# Color gradient stop for download backgrounds.
c.colors.downloads.stop.bg = cyan

# Foreground color for downloads with errors.
c.colors.downloads.error.fg = red

# Font color for hints.
c.colors.hints.fg = default_bg

# Background color for hints. Note that you can use a `rgba(...)` value
# for transparency.
c.colors.hints.bg = cyan

# Font color for the matched part of hints.
c.colors.hints.match.fg = alt_fg

# Text color for the keyhint widget.
c.colors.keyhint.fg = default_fg

# Highlight color for keys to complete the current keychain.
c.colors.keyhint.suffix.fg = blue

# Background color of the keyhint widget.
c.colors.keyhint.bg = default_bg

# Foreground color of an error message.
c.colors.messages.error.fg = default_bg

# Background color of an error message.
c.colors.messages.error.bg = red

# Border color of an error message.
c.colors.messages.error.border = red

# Foreground color of a warning message.
c.colors.messages.warning.fg = default_bg

# Background color of a warning message.
c.colors.messages.warning.bg = orange

# Border color of a warning message.
c.colors.messages.warning.border = orange

# Foreground color of an info message.
c.colors.messages.info.fg = default_fg

# Background color of an info message.
c.colors.messages.info.bg = default_bg

# Border color of an info message.
c.colors.messages.info.border = default_bg

# Foreground color for prompts.
c.colors.prompts.fg = default_fg

# Border used around UI elements in prompts.
c.colors.prompts.border = default_bg

# Background color for prompts.
c.colors.prompts.bg = default_bg

# Background color for the selected item in filename prompts.
c.colors.prompts.selected.bg = green

# Foreground color of the statusbar.
c.colors.statusbar.normal.fg = default_fg

# Background color of the statusbar.
c.colors.statusbar.normal.bg = default_bg

# Foreground color of the statusbar in insert mode.
c.colors.statusbar.insert.fg = green

# Background color of the statusbar in insert mode.
c.colors.statusbar.insert.bg = default_bg

# Foreground color of the statusbar in passthrough mode.
c.colors.statusbar.passthrough.fg = cyan

# Background color of the statusbar in passthrough mode.
c.colors.statusbar.passthrough.bg = default_bg

# Foreground color of the statusbar in private browsing mode.
c.colors.statusbar.private.fg = default_fg

# Background color of the statusbar in private browsing mode.
c.colors.statusbar.private.bg = orange

# Foreground color of the statusbar in command mode.
c.colors.statusbar.command.fg = default_fg

# Background color of the statusbar in command mode.
c.colors.statusbar.command.bg = default_bg

# Foreground color of the statusbar in private browsing + command mode.
c.colors.statusbar.command.private.fg = default_fg

# Background color of the statusbar in private browsing + command mode.
c.colors.statusbar.command.private.bg = orange

# Foreground color of the statusbar in caret mode.
c.colors.statusbar.caret.fg = orange

# Background color of the statusbar in caret mode.
c.colors.statusbar.caret.bg = default_bg

# Foreground color of the statusbar in caret mode with a selection.
c.colors.statusbar.caret.selection.fg = blue

# Background color of the statusbar in caret mode with a selection.
c.colors.statusbar.caret.selection.bg = default_bg

# Background color of the progress bar.
c.colors.statusbar.progress.bg = blue

# Default foreground color of the URL in the statusbar.
c.colors.statusbar.url.fg = default_fg

# Foreground color of the URL in the statusbar on error.
c.colors.statusbar.url.error.fg = red

# Foreground color of the URL in the statusbar for hovered links.
c.colors.statusbar.url.hover.fg = default_fg

# Foreground color of the URL in the statusbar on successful load
# (http).
c.colors.statusbar.url.success.http.fg = default_fg

# Foreground color of the URL in the statusbar on successful load
# (https).
c.colors.statusbar.url.success.https.fg = green

# Foreground color of the URL in the statusbar when there's a warning.
c.colors.statusbar.url.warn.fg = orange

# Background color of the tab bar.
c.colors.tabs.bar.bg = default_bg

# Color gradient start for the tab indicator.
c.colors.tabs.indicator.start = blue

# Color gradient end for the tab indicator.
c.colors.tabs.indicator.stop = cyan

# Color for the tab indicator on errors.
c.colors.tabs.indicator.error = red

# Foreground color of unselected odd tabs.
c.colors.tabs.odd.fg = default_fg

# Background color of unselected odd tabs.
c.colors.tabs.odd.bg = alt_bg

# Foreground color of unselected even tabs.
c.colors.tabs.even.fg = default_fg

# Background color of unselected even tabs.
c.colors.tabs.even.bg = alt_bg

# Foreground color of selected odd tabs.
c.colors.tabs.selected.odd.fg = default_bg

# Background color of selected odd tabs.
c.colors.tabs.selected.odd.bg = blue

# Foreground color of selected even tabs.
c.colors.tabs.selected.even.fg = default_bg

# Background color of selected even tabs.
c.colors.tabs.selected.even.bg = blue

c.hints.border = "1px solid " + cyan

# Background color for webpages if unset (or empty to use the theme's
# color).
# c.colors.webpage.bg = default_bg

c.auto_save.session = True

c.content.cookies.accept = "no-3rdparty"
c.content.autoplay = False
c.content.default_encoding = "utf-8"

c.messages.timeout = 4000

c.statusbar.hide = False
c.statusbar.padding = {"bottom": 3, "left": 5, "right": 5, "top": 3}
c.statusbar.position = "bottom"
c.statusbar.widgets = ["keypress", "url", "history", "progress"]

c.scrolling.bar = "when-searching"
c.scrolling.smooth = True

c.session.lazy_restore = True

c.tabs.background = True
c.tabs.close_mouse_button = "middle"
c.tabs.indicator.width = 0
c.tabs.last_close = "close"
c.tabs.max_width = 250
c.tabs.min_width = -1
c.tabs.mousewheel_switching = False
c.tabs.new_position.related = "next"
c.tabs.new_position.unrelated = "last"
c.tabs.padding = {"bottom": 3, "left": 5, "right": 5, "top": 3}
c.tabs.pinned.frozen = True
c.tabs.position = "top"
c.tabs.select_on_remove = "last-used"
c.tabs.show = "always"
c.url.searchengines = {
    "DEFAULT": "https://duckduckgo.com/?q={}",
    "aw": "https://wiki.archlinux.org/index.php?search={}",
    "p": "https://de.pons.com/%C3%BCbersetzung?q={}&l=deen&in=&lf=&qnac=",
    "y": "https://www.youtube.com/results?search_query={}",
    "g": "https://www.startpage.com/do/search?query={}",
    "sp": "https://www.startpage.com/do/search?query={}",
    "aur": "https://aur.archlinux.org/packages/?O=0&K={}"
}

<commit_msg>qutebrowser: update keybindings<commit_after>config.load_autoconfig()

default_bg = "#F5F6F7"
alt_bg = "#d9dde0"
default_fg = "#444444"
alt_fg = "#888888"
orange = "#F27835"
red = "#F04A50"
cyan = "#2E96C0"
blue = "#5294e2"
green = "#60942C"

# set qutebrowser colors

# Text color of the completion widget. May be a single color to use for
# all columns or a list of three colors, one for each column.
c.colors.completion.fg = default_fg

# Background color of the completion widget for odd rows.
c.colors.completion.odd.bg = default_bg

# Background color of the completion widget for even rows.
c.colors.completion.even.bg = default_bg

# Foreground color of completion widget category headers.
c.colors.completion.category.fg = blue

# Background color of the completion widget category headers.
c.colors.completion.category.bg = alt_bg

# Top border color of the completion widget category headers.
c.colors.completion.category.border.top = alt_bg

# Bottom border color of the completion widget category headers.
c.colors.completion.category.border.bottom = alt_bg

# Foreground color of the selected completion item.
c.colors.completion.item.selected.fg = default_fg

# Background color of the selected completion item.
c.colors.completion.item.selected.bg = alt_bg

# Top border color of the completion widget category headers.
c.colors.completion.item.selected.border.top = alt_bg

# Bottom border color of the selected completion item.
c.colors.completion.item.selected.border.bottom = alt_bg

# Foreground color of the matched text in the completion.
c.colors.completion.match.fg = blue

# Color of the scrollbar handle in the completion view.
c.colors.completion.scrollbar.fg = alt_fg

# Color of the scrollbar in the completion view.
c.colors.completion.scrollbar.bg = default_bg

# Background color for the download bar.
c.colors.downloads.bar.bg = default_bg

# Color gradient start for download text.
c.colors.downloads.start.fg = default_bg

# Color gradient start for download backgrounds.
c.colors.downloads.start.bg = blue

# Color gradient end for download text.
c.colors.downloads.stop.fg = default_bg

# Color gradient stop for download backgrounds.
c.colors.downloads.stop.bg = cyan

# Foreground color for downloads with errors.
c.colors.downloads.error.fg = red

# Font color for hints.
c.colors.hints.fg = default_bg

# Background color for hints. Note that you can use a `rgba(...)` value
# for transparency.
c.colors.hints.bg = cyan

# Font color for the matched part of hints.
c.colors.hints.match.fg = alt_fg

# Text color for the keyhint widget.
c.colors.keyhint.fg = default_fg

# Highlight color for keys to complete the current keychain.
c.colors.keyhint.suffix.fg = blue

# Background color of the keyhint widget.
c.colors.keyhint.bg = default_bg

# Foreground color of an error message.
c.colors.messages.error.fg = default_bg

# Background color of an error message.
c.colors.messages.error.bg = red

# Border color of an error message.
c.colors.messages.error.border = red

# Foreground color of a warning message.
c.colors.messages.warning.fg = default_bg

# Background color of a warning message.
c.colors.messages.warning.bg = orange

# Border color of a warning message.
c.colors.messages.warning.border = orange

# Foreground color of an info message.
c.colors.messages.info.fg = default_fg

# Background color of an info message.
c.colors.messages.info.bg = default_bg

# Border color of an info message.
c.colors.messages.info.border = default_bg

# Foreground color for prompts.
c.colors.prompts.fg = default_fg

# Border used around UI elements in prompts.
c.colors.prompts.border = default_bg

# Background color for prompts.
c.colors.prompts.bg = default_bg

# Background color for the selected item in filename prompts.
c.colors.prompts.selected.bg = green

# Foreground color of the statusbar.
c.colors.statusbar.normal.fg = default_fg

# Background color of the statusbar.
c.colors.statusbar.normal.bg = default_bg

# Foreground color of the statusbar in insert mode.
c.colors.statusbar.insert.fg = green

# Background color of the statusbar in insert mode.
c.colors.statusbar.insert.bg = default_bg

# Foreground color of the statusbar in passthrough mode.
c.colors.statusbar.passthrough.fg = cyan

# Background color of the statusbar in passthrough mode.
c.colors.statusbar.passthrough.bg = default_bg

# Foreground color of the statusbar in private browsing mode.
c.colors.statusbar.private.fg = default_fg

# Background color of the statusbar in private browsing mode.
c.colors.statusbar.private.bg = orange

# Foreground color of the statusbar in command mode.
c.colors.statusbar.command.fg = default_fg

# Background color of the statusbar in command mode.
c.colors.statusbar.command.bg = default_bg

# Foreground color of the statusbar in private browsing + command mode.
c.colors.statusbar.command.private.fg = default_fg

# Background color of the statusbar in private browsing + command mode.
c.colors.statusbar.command.private.bg = orange

# Foreground color of the statusbar in caret mode.
c.colors.statusbar.caret.fg = orange

# Background color of the statusbar in caret mode.
c.colors.statusbar.caret.bg = default_bg

# Foreground color of the statusbar in caret mode with a selection.
c.colors.statusbar.caret.selection.fg = blue

# Background color of the statusbar in caret mode with a selection.
c.colors.statusbar.caret.selection.bg = default_bg

# Background color of the progress bar.
c.colors.statusbar.progress.bg = blue

# Default foreground color of the URL in the statusbar.
c.colors.statusbar.url.fg = default_fg

# Foreground color of the URL in the statusbar on error.
c.colors.statusbar.url.error.fg = red

# Foreground color of the URL in the statusbar for hovered links.
c.colors.statusbar.url.hover.fg = default_fg

# Foreground color of the URL in the statusbar on successful load
# (http).
c.colors.statusbar.url.success.http.fg = default_fg

# Foreground color of the URL in the statusbar on successful load
# (https).
c.colors.statusbar.url.success.https.fg = green

# Foreground color of the URL in the statusbar when there's a warning.
c.colors.statusbar.url.warn.fg = orange

# Background color of the tab bar.
c.colors.tabs.bar.bg = default_bg

# Color gradient start for the tab indicator.
c.colors.tabs.indicator.start = blue

# Color gradient end for the tab indicator.
c.colors.tabs.indicator.stop = cyan

# Color for the tab indicator on errors.
c.colors.tabs.indicator.error = red

# Foreground color of unselected odd tabs.
c.colors.tabs.odd.fg = default_fg

# Background color of unselected odd tabs.
c.colors.tabs.odd.bg = alt_bg

# Foreground color of unselected even tabs.
c.colors.tabs.even.fg = default_fg

# Background color of unselected even tabs.
c.colors.tabs.even.bg = alt_bg

# Foreground color of selected odd tabs.
c.colors.tabs.selected.odd.fg = default_bg

# Background color of selected odd tabs.
c.colors.tabs.selected.odd.bg = blue

# Foreground color of selected even tabs.
c.colors.tabs.selected.even.fg = default_bg

# Background color of selected even tabs.
c.colors.tabs.selected.even.bg = blue

c.hints.border = "1px solid " + cyan

# Background color for webpages if unset (or empty to use the theme's
# color).
# c.colors.webpage.bg = default_bg

c.auto_save.session = True

c.content.cookies.accept = "no-3rdparty"
c.content.autoplay = False
c.content.default_encoding = "utf-8"

c.messages.timeout = 4000

c.statusbar.hide = False
c.statusbar.padding = {"bottom": 3, "left": 5, "right": 5, "top": 3}
c.statusbar.position = "bottom"
c.statusbar.widgets = ["keypress", "url", "history", "progress"]

c.scrolling.bar = "when-searching"
c.scrolling.smooth = True

c.session.lazy_restore = True

c.tabs.background = True
c.tabs.close_mouse_button = "middle"
c.tabs.indicator.width = 0
c.tabs.last_close = "close"
c.tabs.max_width = 250
c.tabs.min_width = -1
c.tabs.mousewheel_switching = False
c.tabs.new_position.related = "next"
c.tabs.new_position.unrelated = "last"
c.tabs.padding = {"bottom": 3, "left": 5, "right": 5, "top": 3}
c.tabs.pinned.frozen = True
c.tabs.position = "top"
c.tabs.select_on_remove = "last-used"
c.tabs.show = "always"
c.url.searchengines = {
    "DEFAULT": "https://duckduckgo.com/?q={}",
    "aw": "https://wiki.archlinux.org/index.php?search={}",
    "p": "https://de.pons.com/%C3%BCbersetzung?q={}&l=deen&in=&lf=&qnac=",
    "y": "https://www.youtube.com/results?search_query={}",
    "g": "https://www.startpage.com/do/search?query={}",
    "sp": "https://www.startpage.com/do/search?query={}",
    "aur": "https://aur.archlinux.org/packages/?O=0&K={}"
}

config.unbind("<Ctrl-w>", mode="normal")
config.unbind("gr", mode="normal")
config.bind("gl", "tab-move +", mode="normal")
config.bind("gh", "tab-move -", mode="normal")
<|endoftext|>


<commit_before>import validictory

from flask import json, Response, request
from flask.views import MethodView

from viaduct import application, db
from viaduct.helpers import Resource
from viaduct.helpers.api import make_api_response
from viaduct.models import Course, Education

class CourseAPI(Resource):
	@staticmethod
	def register():
		view = CourseAPI.as_view('course_api')

		application.add_url_rule('/api/courses/', view_func=view,
			methods=['DELETE', 'GET', 'POST'])

	@staticmethod
	def get():
		data = request.json
		schema = {'type': [{'type': 'integer'},
			{'type': 'array', 'items': {'type': 'integer'}}], 'required': False}
		course_ids = []
		results = []

		try:
			validictory.validate(data, schema)
		except Exception:
			return make_api_response(400, 'Data does not correspond to scheme.')

		if isinstance(data, list):
			course_ids = data
		elif isinstance(data, int):
			course_ids = [data]

		query = Course.query

		if len(course_ids) > 0:
			query = query.filter(Course.id.in_(course_ids))

		for course in query.all():
			results.append(course.to_dict())

		return results

	@staticmethod
	def post():
		data = request.json
		schema = {'type': 'object', 'properties':
			{'education_id': {'type': 'integer'},
			'name': {'type': 'string'},
			'description': {'type': 'string'}}
		}

		try:
			validictory.validate(data, schema)
		except Exception:
			return make_api_response(400, 'Data does not correspond to scheme.')

		if Education.query.filter(Education.id==data['education_id']).count() == 0:
			return make_api_response(400, 'No object has been associated with the education ID that has been specified.')

		if Course.query.filter(Course.name==data['name']).count() > 0:
			return make_api_response(400, 'There is already an object with the name that has been specified.')

		course = Course(data['name'], data['description'])
		db.session.add(course)
		db.session.commit()

		return course.to_dict(), '201 The object has been created.'

	@staticmethod
	def delete():
		data = request.json
		schema = {'type': [{'type': 'integer'},
			{'type': 'array', 'items': {'type': 'integer'}}]}

		try:
			validictory.validate(data, schema)
		except Exception:
			return make_api_response(400, 'Data does not correspond to scheme.')

		return data

<commit_msg>Added support to select all the course objects.<commit_after>import validictory

from flask import json, Response, request
from flask.views import MethodView

from viaduct import application, db
from viaduct.helpers import Resource
from viaduct.helpers.api import make_api_response
from viaduct.models import Course, Education

class CourseAPI(Resource):
	@staticmethod
	def register():
		view = CourseAPI.as_view('course_api')

		application.add_url_rule('/api/courses/', view_func=view,
			methods=['DELETE', 'GET', 'POST'])

	@staticmethod
	def get():
		data = request.json
		schema = {'type': [{'type': 'integer'}, {'type': 'object'},
			{'type': 'array', 'items': {'type': 'integer'}}], 'required': False}
		course_ids = []
		results = []

		try:
			validictory.validate(data, schema)
		except Exception:
			return make_api_response(400, 'Data does not correspond to scheme.')

		if isinstance(data, list):
			course_ids = data
		elif isinstance(data, int):
			course_ids = [data]

		query = Course.query

		if len(course_ids) > 0:
			query = query.filter(Course.id.in_(course_ids))

		for course in query.all():
			results.append(course.to_dict())

		return results

	@staticmethod
	def post():
		data = request.json
		schema = {'type': 'object', 'properties':
			{'education_id': {'type': 'integer'},
			'name': {'type': 'string'},
			'description': {'type': 'string'}}
		}

		try:
			validictory.validate(data, schema)
		except Exception:
			return make_api_response(400, 'Data does not correspond to scheme.')

		if Education.query.filter(Education.id==data['education_id']).count() == 0:
			return make_api_response(400, 'No object has been associated with the education ID that has been specified.')

		if Course.query.filter(Course.name==data['name']).count() > 0:
			return make_api_response(400, 'There is already an object with the name that has been specified.')

		course = Course(data['name'], data['description'])
		db.session.add(course)
		db.session.commit()

		return course.to_dict(), '201 The object has been created.'

	@staticmethod
	def delete():
		data = request.json
		schema = {'type': [{'type': 'integer'},
			{'type': 'array', 'items': {'type': 'integer'}}]}

		try:
			validictory.validate(data, schema)
		except Exception:
			return make_api_response(400, 'Data does not correspond to scheme.')

		return data

<|endoftext|>


<commit_before>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import jinja2
import flask

import views

class Krempelair(flask.Flask):
    jinja_options = {
        'extensions': ['jinja2.ext.autoescape'],
        'undefined': jinja2.StrictUndefined
    }

    def __init__(self):
        """(See `make_app` for parameter descriptions.)"""
        flask.Flask.__init__(self, __name__)

        self.setup_routes()

    def create_jinja_environment(self):
        """Called by Flask.__init__"""
        env = super(Krempelair, self).create_jinja_environment()
        for func in [
            'force_unicode',
            'timesince',
            'shorten_sha1',
            'shorten_message',
            'extract_author_name',
            'formattimestamp',
        ]:
            env.filters[func] = getattr(utils, func)

        return env

    def setup_routes(self):
        for endpoint, rule in [
            #Allgemeine Funktionen
            #('air_login',   '/login/<user>/<key>'),

            # Getter der Temperaturen und des Betriebsstatus
            ('air_get_status_betrieb',   '/'),
            ('air_get_status_stoerung',   '/stoerung'),
            ('air_get_temperaturen', '/lueftung/temperatur'),

            # Setters für Funktionen
            ('air_set_level', '/lueftung/stufe/<int:level>'),
            ('air_set_timer', '/lueftung/timer/<int:time>'),
            ('air_set_tempSoll', '/lueftung/temperatur/sollTemp/<float:temp>'),
            ('air_set_tempNAK', '/lueftung/temperatur/sollTempNAK/<float:temp>'),
            ('air_set_tempSoll', '/lueftung/temperatur/sollTemp/<int:temp>'),
            ('air_set_tempNAK', '/lueftung/temperatur/sollTempNAK/<int:temp>'),
            ('air_set_NAK', '/lueftung/NAK/<int:NAK>'),
            ('air_set_wrg', '/lueftung/wrg/<int:level>'),
            ('air_set_le', '/lueftung/le/<int:level>'),

            # Trend Funktionen
            ('air_log_tempIst', '/lueftung/log/tempIst/<float:temp>'),
            ('air_log_tempIst', '/lueftung/log/tempIst/<int:temp>'),
            ('air_get_trend_tempIst', '/lueftung/log/tempIst'),
            ('air_get_trend_tempIst', '/lueftung/log/tempSoll'),

        ]:
            self.add_url_rule(rule, view_func=getattr(views, endpoint))

if __name__ == "__main__":
    app = Krempelair()
    app.run(host="0.0.0.0", debug=True)
else:
    application = Krempelair()
<commit_msg>Update __init__.py<commit_after>#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import jinja2
import flask

import views

class Krempelair(flask.Flask):
    jinja_options = {
        'extensions': ['jinja2.ext.autoescape'],
        'undefined': jinja2.StrictUndefined
    }

    def __init__(self):
        """(See `make_app` for parameter descriptions.)"""
        flask.Flask.__init__(self, __name__)

        self.setup_routes()

    def create_jinja_environment(self):
        """Called by Flask.__init__"""
        env = super(Krempelair, self).create_jinja_environment()
        for func in [
            'force_unicode',
            'timesince',
            'shorten_sha1',
            'shorten_message',
            'extract_author_name',
            'formattimestamp',
        ]:
            env.filters[func] = getattr(utils, func)

        return env

    def setup_routes(self):
        for endpoint, rule in [
            #Allgemeine Funktionen
            #('air_login',   '/login/<user>/<key>'),

            # Getter der Temperaturen und des Betriebsstatus
            ('air_get_status_betrieb',   '/'),
            ('air_get_status_stoerung',   '/stoerung'),
            ('air_get_temperaturen', '/lueftung/temperatur'),

            # Setters für Funktionen
            ('air_set_level', '/lueftung/stufe/<int:level>'),
            ('air_set_timer', '/lueftung/timer/<int:time>'),
            ('air_set_tempSoll', '/lueftung/temperatur/sollTemp/<float:temp>'),
            ('air_set_tempNAK', '/lueftung/temperatur/sollTempNAK/<float:temp>'),
            ('air_set_tempSoll', '/lueftung/temperatur/sollTemp/<int:temp>'),
            ('air_set_tempNAK', '/lueftung/temperatur/sollTempNAK/<int:temp>'),
            ('air_set_NAK', '/lueftung/NAK/<int:NAK>'),
            ('air_set_wrg', '/lueftung/wrg/<int:level>'),
            ('air_set_le', '/lueftung/le/<int:level>'),

            # Trend Funktionen
            ('air_log_tempIst', '/lueftung/log/tempIst/<float:temp>'),
            ('air_log_tempIst', '/lueftung/log/tempIst/<int:temp>'),
            ('air_get_trend_tempIst', '/lueftung/log/tempIst'),
            ('air_get_trend_tempSoll', '/lueftung/log/tempSoll'),

        ]:
            self.add_url_rule(rule, view_func=getattr(views, endpoint))

if __name__ == "__main__":
    app = Krempelair()
    app.run(host="0.0.0.0", debug=True)
else:
    application = Krempelair()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

"""
Core.
"""

from __future__ import division, print_function, absolute_import

import math

import numpy as np
from scipy.optimize import brentq
from scipy.stats import (binom, ttest_ind, ttest_1samp)

from .utils import get_prng, binom_conf_interval

def corr(x, y, reps=10**4, seed=None):
    """
    Simulate permutation p-value for Spearman correlation coefficient

    Parameters
    ----------
    x : array-like
    y : array-like
    reps : int
    seed : RandomState instance or {None, int, RandomState instance}
        If None, the pseudorandom number generator is the RandomState
        instance used by `np.random`;
        If int, seed is the seed used by the random number generator;
        If RandomState instance, seed is the pseudorandom number generator

    Returns
    -------
    tuple
        Returns test statistic, left-sided p-value,
        right-sided p-value, two-sided p-value, simulated distribution
    """
    prng = get_prng(seed)
    tst = np.corrcoef(x, y)[0, 1]
    sims = [np.corrcoef(prng.permutation(x), y)[0, 1] for i in range(reps)]
    left_pv = np.sum(sims <= tst)/reps
    right_pv = np.sum(sims >= tst)/reps
    two_sided_pv = np.sum(np.abs(sims) >= np.abs(tst))/reps
    return tst, left_pv, right_pv, two_sided_pv, sims

def two_sample(x, y, reps=10**5, stat='mean', alternative="greater",
               keep_dist=False, interval=False, level=0.95, seed=None,
               shift=None):
    """
    One-sided or two-sided, two-sample permutation test for equality of
    two means, with p-value estimated by simulated random sampling with
    reps replications.

    Tests the hypothesis that x and y are a random partition of x,y
    against the alternative that x comes from a population with mean

    (a) greater than that of the population from which y comes,
        if side = 'greater'
    (b) less than that of the population from which y comes,
        if side = 'less'
    (c) different from that of the population from which y comes,
        if side = 'two-sided'

    If ``keep_dist``, return the distribution of values of the test statistic;
    otherwise, return only the number of permutations for which the value of
    the test statistic and p-value.

    Parameters
    ----------
    x : array-like
        Sample 1
    y : array-like
        Sample 2
    reps : int
        number of repetitions
    stat : {'mean', 't'}
        The test statistic.

        (a) If stat == 'mean', the test statistic is (mean(x) - mean(y))
            (equivalently, sum(x), since those are monotonically related)
        (b) If stat == 't', the test statistic is the two-sample t-statistic--
            but the p-value is still estimated by the randomization,
            approximating the permutation distribution.
            The t-statistic is computed using scipy.stats.ttest_ind
        (c) If stat is a function (a callable object), the test statistic is
            that function.  The function should take a permutation of the pooled
            data and compute the test function from it. For instance, if the
            test statistic is the Kolmogorov-Smirnov distance between the
            empirical distributions of the two samples, max_t |F_x(t) - F_y(t)|,
            the test statistic could be written:

            f = lambda u: np.max( \
                [abs(sum(u[:len(x)]<=v)/len(x)-sum(u[len(x):]<=v)/len(y)) for v in u]\
                )

    alternative : {'greater', 'less', 'two-sided'}
        The alternative hypothesis to test
    keep_dist : bool
        flag for whether to store and return the array of values
        of the irr test statistic
    interval : {'upper', 'lower', 'two-sided'}
        The type of confidence interval

        (a) If interval == 'upper', computes an upper confidence bound on the
            true p-value based on the simulations by inverting Binomial tests.
        (b) If interval == 'lower', computes a lower confidence bound on the
            true p-value based on the simulations by inverting Binomial tests.
        (c) If interval == 'two-sided', computes lower and upper confidence
            bounds on the true p-value based on the simulations by inverting
            Binomial tests.
    level : float in (0, 1)
        the confidence limit for the confidence bounds.
    seed : RandomState instance or {None, int, RandomState instance}
        If None, the pseudorandom number generator is the RandomState
        instance used by `np.random`;
        If int, seed is the seed used by the random number generator;
        If RandomState instance, seed is the pseudorandom number generator
    shift : int
        A constant scalar shift in the distribution of y. That is, x is equal
        in distribution to y + shift.
        If None, the shift is assumed to be 0. This is the null hypothesis one
        typically tests.
        If int, then shift is subtracted off of y before permuting, then added
        back in to compute the permutation test statistic.

    Returns
    -------
    float
        the estimated p-value
    float
        the test statistic
    tuple
        These values are only returned if `level` == True

        (a) confidence bound on p-value,
            if interval in {'lower','upper'}
        (b) [lower confidence bound, upper confidence bound],
            if interval == 'two-sided'
    list
        The distribution of test statistics.
        These values are only returned if `keep_dist` == True
    """
    prng = get_prng(seed)
    if shift is None:
        shift = 0
    z = np.concatenate([x, y])   # pooled responses

    # If stat is callable, use it as the test function. Otherwise, look in the dictionary

    stats = {
        'mean': lambda u: np.mean(u[:len(x)]) - np.mean(u[len(x):]),
        't': lambda u: ttest_ind(
            u[:len(x)], u[len(x):], equal_var=True)[0]
    }
    if callable(stat):
        tst_fun = stat
    else:
        tst_fun = stats[stat]

    theStat = {
        'greater': tst_fun,
        'less': lambda u: -tst_fun(u),
        'two-sided': lambda u: math.fabs(tst_fun(u))
    }

    tst = theStat[alternative](z)
    z[len(x):] = z[len(x):] - shift
    ind = np.concatenate([np.zeros(len(x)), np.ones(len(y))])
    if keep_dist:
        dist = np.empty(reps)
        for i in range(reps):
            dist[i] = theStat[alternative](prng.permutation(z) + ind*shift)
        hits = np.sum(dist >= tst)
        if interval in ["upper", "lower", "two-sided"]:
            return (hits/reps, tst,
                    binom_conf_interval(reps, hits, level, interval), dist)
        else:
            return hits/reps, tst, dist
    else:
        hits = np.sum([(theStat[alternative](prng.permutation(z) + ind*shift) >= tst)
                       for i in range(reps)])

    if interval in ["upper", "lower", "two-sided"]:
        return (hits/reps, tst,
                binom_conf_interval(reps, hits, level, interval))
    else:
        return hits/reps, tst

def two_sample_conf_int(x, y, cl=0.95, alternative="two-sided", seed=None,
                        reps=10**4, stat="mean", **kwargs):
    """
    One-sided or two-sided confidence interval for the two-sample statistic
    comparing two means, obtained by inverting the two-sample permutation test.

    Parameters
    ----------
    x : array-like
        Sample 1
    y : array-like
        Sample 2
    cl : float in (0, 1)
        The desired confidence level. Default 0.95.
    alternative : {"two-sided", "lower", "upper"}
        Indicates the alternative hypothesis.
    seed : RandomState instance or {None, int, RandomState instance}
        If None, the pseudorandom number generator is the RandomState
        instance used by `np.random`;
        If int, seed is the seed used by the random number generator;
        If RandomState instance, seed is the pseudorandom number generator
    reps : int
        number of repetitions in two_sample
    stat : {'mean', 't'}
        The test statistic.

        (a) If stat == 'mean', the test statistic is (mean(x) - mean(y))
            (equivalently, sum(x), since those are monotonically related)
        (b) If stat == 't', the test statistic is the two-sample t-statistic--
            but the p-value is still estimated by the randomization,
            approximating the permutation distribution.
            The t-statistic is computed using scipy.stats.ttest_ind
        (c) If stat is a function (a callable object), the test statistic is
            that function.  The function should take a permutation of the pooled
            data and compute the test function from it. For instance, if the
            test statistic is the Kolmogorov-Smirnov distance between the
            empirical distributions of the two samples, max_t |F_x(t) - F_y(t)|,
            the test statistic could be written:

            f = lambda u: np.max( \
                [abs(sum(u[:len(x)]<=v)/len(x)-sum(u[len(x):]<=v)/len(y)) for v in u]\
                )
    Returns
    -------
    tuple
        the estimated confidence limits
    Notes
    -----
    xtol : float
        Tolerance in brentq
    rtol : float
        Tolerance in brentq
    maxiter : int
        Maximum number of iterations in brentq
    """

    assert alternative in ("two-sided", "lower", "upper")
    prng = get_prng(seed)

    shift_limit = max(abs(max(x) - min(y)), abs(max(y) - min(x)))
    observed = np.mean(x) - np.mean(y)

    if alternative == 'two-sided':
        alpha = (1-cl)/2
    else:
        alpha = 1-cl

    if alternative != "upper":
        f = lambda q: alpha - two_sample(x, y, alternative="less", seed=seed, shift=q, reps=reps, stat=stat)[0]
        ci_low = brentq(f, observed, -shift_limit)
    if alternative != "lower":
        f = lambda q: alpha - two_sample(x, y, alternative="greater", seed=seed, shift=q, reps=reps, stat=stat)[0]
        ci_upp = brentq(f, observed, shift_limit)

    return ci_low, ci_upp

def one_sample(x, y=None, reps=10**5, stat='mean', alternative="greater",
               keep_dist=False, seed=None):
    """
    One-sided or two-sided, one-sample permutation test for the mean,
    with p-value estimated by simulated random sampling with
    reps replications.

    Alternatively, a permutation test for equality of means of two paired
    samples.

    Tests the hypothesis that x is distributed symmetrically symmetric about 0
    (or x and y have the same center) against the alternative that x comes from
    a population with mean

    (a) greater than 0 (greater than that of the population from which y comes),
        if side = 'greater'
    (b) less than 0 (less than that of the population from which y comes),
        if side = 'less'
    (c) different from 0 (different from that of the population from which y comes),
        if side = 'two-sided'

    If ``keep_dist``, return the distribution of values of the test statistic;
    otherwise, return only the number of permutations for which the value of
    the test statistic and p-value.

    Parameters
    ----------
    x : array-like
        Sample 1
    y : array-like
        Sample 2. Must preserve the order of pairs with x.
        If None, x is taken to be the one sample.
    reps : int
        number of repetitions
    stat : {'mean', 't'}
        The test statistic. The statistic is computed based on either z = x or
        z = x - y, if y is specified.

        (a) If stat == 'mean', the test statistic is mean(z).
        (b) If stat == 't', the test statistic is the t-statistic--
            but the p-value is still estimated by the randomization,
            approximating the permutation distribution.
        (c) If stat is a function (a callable object), the test statistic is
            that function.  The function should take a permutation of the
            data and compute the test function from it. For instance, if the
            test statistic is the maximum absolute value, max_i |z_i|,
            the test statistic could be written:

            f = lambda u: np.max(abs(u))
    alternative : {'greater', 'less', 'two-sided'}
        The alternative hypothesis to test
    keep_dist : bool
        flag for whether to store and return the array of values
        of the irr test statistic
    seed : RandomState instance or {None, int, RandomState instance}
        If None, the pseudorandom number generator is the RandomState
        instance used by `np.random`;
        If int, seed is the seed used by the random number generator;
        If RandomState instance, seed is the pseudorandom number generator

    Returns
    -------
    float
        the estimated p-value
    float
        the test statistic
    list
        The distribution of test statistics.
        These values are only returned if `keep_dist` == True
    """
    prng = get_prng(seed)

    if y is None:
        z = x
    elif len(x)!=len(y):
        raise ValueError('x and y must be pairs')
    else:
        z = np.array(x)-np.array(y)

    stats = {
        'mean': lambda u: np.mean(u),
        't': lambda u: ttest_1samp(u, 0)[0]
    }
    if callable(stat):
        tst_fun = stat
    else:
        tst_fun = stats[stat]

    theStat = {
        'greater': tst_fun,
        'less': lambda u: -tst_fun(u),
        'two-sided': lambda u: math.fabs(tst_fun(u))
    }

    tst = theStat[alternative](z)
    n = len(z)
    if keep_dist:
        dist = []
        for i in range(reps):
            dist.append(theStat[alternative](z*(1-2*prng.binomial(1,.5,size=n))))
        hits = np.sum(dist >= tst)
        return hits/reps, tst, dist
    else:
        hits = np.sum([(theStat[alternative](z*(1-2*prng.binomial(1,.5,size=n)))) >= tst
                       for i in range(reps)])
        return hits/reps, tst<commit_msg>BUG: fix bisection limits<commit_after># -*- coding: utf-8 -*-

"""
Core.
"""

from __future__ import division, print_function, absolute_import

import math

import numpy as np
from scipy.optimize import brentq
from scipy.stats import (binom, ttest_ind, ttest_1samp)

from .utils import get_prng, binom_conf_interval

def corr(x, y, reps=10**4, seed=None):
    """
    Simulate permutation p-value for Spearman correlation coefficient

    Parameters
    ----------
    x : array-like
    y : array-like
    reps : int
    seed : RandomState instance or {None, int, RandomState instance}
        If None, the pseudorandom number generator is the RandomState
        instance used by `np.random`;
        If int, seed is the seed used by the random number generator;
        If RandomState instance, seed is the pseudorandom number generator

    Returns
    -------
    tuple
        Returns test statistic, left-sided p-value,
        right-sided p-value, two-sided p-value, simulated distribution
    """
    prng = get_prng(seed)
    tst = np.corrcoef(x, y)[0, 1]
    sims = [np.corrcoef(prng.permutation(x), y)[0, 1] for i in range(reps)]
    left_pv = np.sum(sims <= tst)/reps
    right_pv = np.sum(sims >= tst)/reps
    two_sided_pv = np.sum(np.abs(sims) >= np.abs(tst))/reps
    return tst, left_pv, right_pv, two_sided_pv, sims

def two_sample(x, y, reps=10**5, stat='mean', alternative="greater",
               keep_dist=False, interval=False, level=0.95, seed=None,
               shift=None):
    """
    One-sided or two-sided, two-sample permutation test for equality of
    two means, with p-value estimated by simulated random sampling with
    reps replications.

    Tests the hypothesis that x and y are a random partition of x,y
    against the alternative that x comes from a population with mean

    (a) greater than that of the population from which y comes,
        if side = 'greater'
    (b) less than that of the population from which y comes,
        if side = 'less'
    (c) different from that of the population from which y comes,
        if side = 'two-sided'

    If ``keep_dist``, return the distribution of values of the test statistic;
    otherwise, return only the number of permutations for which the value of
    the test statistic and p-value.

    Parameters
    ----------
    x : array-like
        Sample 1
    y : array-like
        Sample 2
    reps : int
        number of repetitions
    stat : {'mean', 't'}
        The test statistic.

        (a) If stat == 'mean', the test statistic is (mean(x) - mean(y))
            (equivalently, sum(x), since those are monotonically related)
        (b) If stat == 't', the test statistic is the two-sample t-statistic--
            but the p-value is still estimated by the randomization,
            approximating the permutation distribution.
            The t-statistic is computed using scipy.stats.ttest_ind
        (c) If stat is a function (a callable object), the test statistic is
            that function.  The function should take a permutation of the pooled
            data and compute the test function from it. For instance, if the
            test statistic is the Kolmogorov-Smirnov distance between the
            empirical distributions of the two samples, max_t |F_x(t) - F_y(t)|,
            the test statistic could be written:

            f = lambda u: np.max( \
                [abs(sum(u[:len(x)]<=v)/len(x)-sum(u[len(x):]<=v)/len(y)) for v in u]\
                )

    alternative : {'greater', 'less', 'two-sided'}
        The alternative hypothesis to test
    keep_dist : bool
        flag for whether to store and return the array of values
        of the irr test statistic
    interval : {'upper', 'lower', 'two-sided'}
        The type of confidence interval

        (a) If interval == 'upper', computes an upper confidence bound on the
            true p-value based on the simulations by inverting Binomial tests.
        (b) If interval == 'lower', computes a lower confidence bound on the
            true p-value based on the simulations by inverting Binomial tests.
        (c) If interval == 'two-sided', computes lower and upper confidence
            bounds on the true p-value based on the simulations by inverting
            Binomial tests.
    level : float in (0, 1)
        the confidence limit for the confidence bounds.
    seed : RandomState instance or {None, int, RandomState instance}
        If None, the pseudorandom number generator is the RandomState
        instance used by `np.random`;
        If int, seed is the seed used by the random number generator;
        If RandomState instance, seed is the pseudorandom number generator
    shift : int
        A constant scalar shift in the distribution of y. That is, x is equal
        in distribution to y - shift.
        If None, the shift is assumed to be 0. This is the null hypothesis one
        typically tests.
        If int, then shift is subtracted off of y before permuting, then added
        back in to compute the permutation test statistic.

    Returns
    -------
    float
        the estimated p-value
    float
        the test statistic
    tuple
        These values are only returned if `level` == True

        (a) confidence bound on p-value,
            if interval in {'lower','upper'}
        (b) [lower confidence bound, upper confidence bound],
            if interval == 'two-sided'
    list
        The distribution of test statistics.
        These values are only returned if `keep_dist` == True
    """
    prng = get_prng(seed)
    if shift is None:
        shift = 0
    z = np.concatenate([x, y])   # pooled responses

    # If stat is callable, use it as the test function. Otherwise, look in the dictionary

    stats = {
        'mean': lambda u: np.mean(u[:len(x)]) - np.mean(u[len(x):]),
        't': lambda u: ttest_ind(
            u[:len(x)], u[len(x):], equal_var=True)[0]
    }
    if callable(stat):
        tst_fun = stat
    else:
        tst_fun = stats[stat]

    theStat = {
        'greater': tst_fun,
        'less': lambda u: -tst_fun(u),
        'two-sided': lambda u: math.fabs(tst_fun(u))
    }

    tst = theStat[alternative](z)
    z[len(x):] = z[:len(x)] - shift
    ind = np.concatenate([np.ones(len(x)), np.zeros(len(y))])
    if keep_dist:
        dist = np.empty(reps)
        for i in range(reps):
            dist[i] = theStat[alternative](prng.permutation(z) + ind*shift)
        hits = np.sum(dist >= tst)
        if interval in ["upper", "lower", "two-sided"]:
            return (hits/reps, tst,
                    binom_conf_interval(reps, hits, level, interval), dist)
        else:
            return hits/reps, tst, dist
    else:
        hits = np.sum([(theStat[alternative](prng.permutation(z) + ind*shift) >= tst)
                       for i in range(reps)])

    if interval in ["upper", "lower", "two-sided"]:
        return (hits/reps, tst,
                binom_conf_interval(reps, hits, level, interval))
    else:
        return hits/reps, tst

def two_sample_conf_int(x, y, cl=0.95, alternative="two-sided", seed=None,
                        reps=10**4, stat="mean", **kwargs):
    """
    One-sided or two-sided confidence interval for the two-sample statistic
    comparing two means, obtained by inverting the two-sample permutation test.

    Parameters
    ----------
    x : array-like
        Sample 1
    y : array-like
        Sample 2
    cl : float in (0, 1)
        The desired confidence level. Default 0.95.
    alternative : {"two-sided", "lower", "upper"}
        Indicates the alternative hypothesis.
    seed : RandomState instance or {None, int, RandomState instance}
        If None, the pseudorandom number generator is the RandomState
        instance used by `np.random`;
        If int, seed is the seed used by the random number generator;
        If RandomState instance, seed is the pseudorandom number generator
    reps : int
        number of repetitions in two_sample
    stat : {'mean', 't'}
        The test statistic.

        (a) If stat == 'mean', the test statistic is (mean(x) - mean(y))
            (equivalently, sum(x), since those are monotonically related)
        (b) If stat == 't', the test statistic is the two-sample t-statistic--
            but the p-value is still estimated by the randomization,
            approximating the permutation distribution.
            The t-statistic is computed using scipy.stats.ttest_ind
        (c) If stat is a function (a callable object), the test statistic is
            that function.  The function should take a permutation of the pooled
            data and compute the test function from it. For instance, if the
            test statistic is the Kolmogorov-Smirnov distance between the
            empirical distributions of the two samples, max_t |F_x(t) - F_y(t)|,
            the test statistic could be written:

            f = lambda u: np.max( \
                [abs(sum(u[:len(x)]<=v)/len(x)-sum(u[len(x):]<=v)/len(y)) for v in u]\
                )
    Returns
    -------
    tuple
        the estimated confidence limits
    Notes
    -----
    xtol : float
        Tolerance in brentq
    rtol : float
        Tolerance in brentq
    maxiter : int
        Maximum number of iterations in brentq
    """

    assert alternative in ("two-sided", "lower", "upper")
    prng = get_prng(seed)

    shift_limit = max(abs(max(x) - min(y)), abs(max(y) - min(x)))
    observed = np.mean(x) - np.mean(y)

    if alternative == 'two-sided':
        cl = 1 - (1-cl)/2

    if alternative != "upper":
        f = lambda q: cl - two_sample(x, y, alternative="less", seed=seed, shift=q, reps=reps, stat=stat)[0]
        ci_low = brentq(f, observed, -2*shift_limit)
    if alternative != "lower":
        f = lambda q: cl - two_sample(x, y, alternative="greater", seed=seed, shift=q, reps=reps, stat=stat)[0]
        ci_upp = brentq(f, 2*shift_limit, observed)

    return ci_low, ci_upp

def one_sample(x, y=None, reps=10**5, stat='mean', alternative="greater",
               keep_dist=False, seed=None):
    """
    One-sided or two-sided, one-sample permutation test for the mean,
    with p-value estimated by simulated random sampling with
    reps replications.

    Alternatively, a permutation test for equality of means of two paired
    samples.

    Tests the hypothesis that x is distributed symmetrically symmetric about 0
    (or x and y have the same center) against the alternative that x comes from
    a population with mean

    (a) greater than 0 (greater than that of the population from which y comes),
        if side = 'greater'
    (b) less than 0 (less than that of the population from which y comes),
        if side = 'less'
    (c) different from 0 (different from that of the population from which y comes),
        if side = 'two-sided'

    If ``keep_dist``, return the distribution of values of the test statistic;
    otherwise, return only the number of permutations for which the value of
    the test statistic and p-value.

    Parameters
    ----------
    x : array-like
        Sample 1
    y : array-like
        Sample 2. Must preserve the order of pairs with x.
        If None, x is taken to be the one sample.
    reps : int
        number of repetitions
    stat : {'mean', 't'}
        The test statistic. The statistic is computed based on either z = x or
        z = x - y, if y is specified.

        (a) If stat == 'mean', the test statistic is mean(z).
        (b) If stat == 't', the test statistic is the t-statistic--
            but the p-value is still estimated by the randomization,
            approximating the permutation distribution.
        (c) If stat is a function (a callable object), the test statistic is
            that function.  The function should take a permutation of the
            data and compute the test function from it. For instance, if the
            test statistic is the maximum absolute value, max_i |z_i|,
            the test statistic could be written:

            f = lambda u: np.max(abs(u))
    alternative : {'greater', 'less', 'two-sided'}
        The alternative hypothesis to test
    keep_dist : bool
        flag for whether to store and return the array of values
        of the irr test statistic
    seed : RandomState instance or {None, int, RandomState instance}
        If None, the pseudorandom number generator is the RandomState
        instance used by `np.random`;
        If int, seed is the seed used by the random number generator;
        If RandomState instance, seed is the pseudorandom number generator

    Returns
    -------
    float
        the estimated p-value
    float
        the test statistic
    list
        The distribution of test statistics.
        These values are only returned if `keep_dist` == True
    """
    prng = get_prng(seed)

    if y is None:
        z = x
    elif len(x)!=len(y):
        raise ValueError('x and y must be pairs')
    else:
        z = np.array(x)-np.array(y)

    stats = {
        'mean': lambda u: np.mean(u),
        't': lambda u: ttest_1samp(u, 0)[0]
    }
    if callable(stat):
        tst_fun = stat
    else:
        tst_fun = stats[stat]

    theStat = {
        'greater': tst_fun,
        'less': lambda u: -tst_fun(u),
        'two-sided': lambda u: math.fabs(tst_fun(u))
    }

    tst = theStat[alternative](z)
    n = len(z)
    if keep_dist:
        dist = []
        for i in range(reps):
            dist.append(theStat[alternative](z*(1-2*prng.binomial(1,.5,size=n))))
        hits = np.sum(dist >= tst)
        return hits/reps, tst, dist
    else:
        hits = np.sum([(theStat[alternative](z*(1-2*prng.binomial(1,.5,size=n)))) >= tst
                       for i in range(reps)])
        return hits/reps, tst<|endoftext|>