"""
Django settings for bbs project.

Generated by 'django-admin startproject' using Django 1.11.7.

For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '6gmpi&j6a5#sbn^d$v41)5xx8j@1yq5bi3_-p3%pu-!e=0m$r!'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'bbs.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'bbs.wsgi.application'

# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'


from keras_applications import get_submodules_from_kwargs

def Conv2dBn(
        filters,
        kernel_size,
        strides=(1, 1),
        padding='valid',
        data_format=None,
        dilation_rate=(1, 1),
        activation=None,
        activation_dtype=None,
        kernel_initializer='glorot_uniform',
        bias_initializer='zeros',
        kernel_regularizer=None,
        bias_regularizer=None,
        activity_regularizer=None,
        kernel_constraint=None,
        bias_constraint=None,
        use_batchnorm=False,
        **kwargs
):
    """Extension of Conv2D layer with batchnorm"""

    conv_name, act_name, bn_name = None, None, None
    block_name = kwargs.pop('name', None)
    backend, layers, models, keras_utils = get_submodules_from_kwargs(kwargs)

    if block_name is not None:
        conv_name = block_name + '_conv'

    if block_name is not None and activation is not None:
        act_str = activation.__name__ if callable(activation) else str(activation)
        act_name = block_name + '_' + act_str

    if block_name is not None and use_batchnorm:
        bn_name = block_name + '_bn'

    bn_axis = 3 if backend.image_data_format() == 'channels_last' else 1

    def wrapper(input_tensor):

        x = layers.Conv2D(
            filters=filters,
            kernel_size=kernel_size,
            strides=strides,
            padding=padding,
            data_format=data_format,
            dilation_rate=dilation_rate,
            activation=None,
            use_bias=not (use_batchnorm),
            kernel_initializer=kernel_initializer,
            bias_initializer=bias_initializer,
            kernel_regularizer=kernel_regularizer,
            bias_regularizer=bias_regularizer,
            activity_regularizer=activity_regularizer,
            kernel_constraint=kernel_constraint,
            bias_constraint=bias_constraint,
            name=conv_name,
        )(input_tensor)

        if use_batchnorm:
            x = layers.BatchNormalization(axis=bn_axis, name=bn_name)(x)

        if activation:
            if activation_dtype is None:
                x = layers.Activation(activation, name=act_name)(x)
            else:
                x = layers.Activation(activation, name=act_name, dtype=activation_dtype)(x)

        return x

    return wrapper


#!/usr/bin/env python3

import os
import random
import unittest
from math import exp, pi

import gpytorch
import torch
from gpytorch.distributions import MultivariateNormal
from gpytorch.kernels import RBFKernel, ScaleKernel
from gpytorch.likelihoods import GaussianLikelihood, FixedNoiseGaussianLikelihood
from gpytorch.means import ConstantMean
from gpytorch.priors import SmoothedBoxPrior
from gpytorch.test.utils import least_used_cuda_device
from torch import optim

class ExactGPModel(gpytorch.models.ExactGP):
    def __init__(self, train_inputs, train_targets, likelihood):
        super(ExactGPModel, self).__init__(train_inputs, train_targets, likelihood)
        self.mean_module = ConstantMean(prior=SmoothedBoxPrior(-1, 1))
        self.rbf_covar_module = RBFKernel(lengthscale_prior=SmoothedBoxPrior(exp(-3), exp(3), sigma=0.1))
        self.covar_module = ScaleKernel(self.rbf_covar_module)

    def forward(self, x):
        mean_x = self.mean_module(x)
        covar_x = self.covar_module(x)
        return MultivariateNormal(mean_x, covar_x)

class TestWhiteNoiseGPRegression(unittest.TestCase):
    def setUp(self):
        if os.getenv("UNLOCK_SEED") is None or os.getenv("UNLOCK_SEED").lower() == "false":
            self.rng_state = torch.get_rng_state()
            torch.manual_seed(1)
            if torch.cuda.is_available():
                torch.cuda.manual_seed_all(1)
            random.seed(1)

    def tearDown(self):
        if hasattr(self, "rng_state"):
            torch.set_rng_state(self.rng_state)

    def _get_data(self, cuda=False):
        device = torch.device("cuda") if cuda else torch.device("cpu")
        # Simple training data: let's try to learn a sine function
        train_x = torch.linspace(0, 1, 11, device=device)
        train_y = torch.sin(train_x * (2 * pi))
        test_x = torch.linspace(0, 1, 51, device=device)
        test_y = torch.sin(test_x * (2 * pi))
        return train_x, test_x, train_y, test_y

    def test_posterior_latent_gp_and_likelihood_without_optimization(self, cuda=False):
        train_x, test_x, train_y, test_y = self._get_data(cuda=cuda)
        with gpytorch.settings.debug(False):
            # We're manually going to set the hyperparameters to be ridiculous
            likelihood = FixedNoiseGaussianLikelihood(torch.ones(11) * 1e-8)
            gp_model = ExactGPModel(train_x, train_y, likelihood)
            # Update lengthscale prior to accommodate extreme parameters
            gp_model.rbf_covar_module.initialize(lengthscale=exp(-6))
            gp_model.mean_module.initialize(constant=0)

            if cuda:
                gp_model.cuda()
                likelihood.cuda()

            # Compute posterior distribution
            gp_model.eval()
            likelihood.eval()

            # Let's see how our model does, conditioned with weird hyperparams
            # The posterior should fit all the data
            function_predictions = likelihood(gp_model(train_x))

            self.assertLess(torch.norm(function_predictions.mean - train_y), 1e-3)
            self.assertLess(torch.norm(function_predictions.variance), 5e-3)

            # It shouldn't fit much else though
            test_function_predictions = gp_model(torch.tensor([1.1]).type_as(test_x))

            self.assertLess(torch.norm(test_function_predictions.mean - 0), 1e-4)
            self.assertLess(torch.norm(test_function_predictions.variance - gp_model.covar_module.outputscale), 1e-4)

    def test_posterior_latent_gp_and_likelihood_without_optimization_cuda(self):
        if torch.cuda.is_available():
            with least_used_cuda_device():
                self.test_posterior_latent_gp_and_likelihood_without_optimization(cuda=True)

    def test_posterior_latent_gp_and_likelihood_with_optimization(self, cuda=False):
        train_x, test_x, train_y, test_y = self._get_data(cuda=cuda)
        # We're manually going to set the hyperparameters to something they shouldn't be
        likelihood = FixedNoiseGaussianLikelihood(torch.ones(11) * 0.001)
        gp_model = ExactGPModel(train_x, train_y, likelihood)
        mll = gpytorch.ExactMarginalLogLikelihood(likelihood, gp_model)
        gp_model.rbf_covar_module.initialize(lengthscale=exp(1))
        gp_model.mean_module.initialize(constant=0)

        if cuda:
            gp_model.cuda()
            likelihood.cuda()

        # Find optimal model hyperparameters
        gp_model.train()
        likelihood.train()

        optimizer = optim.Adam(list(gp_model.parameters()) + list(likelihood.parameters()), lr=0.1)
        optimizer.n_iter = 0
        with gpytorch.settings.debug(False):
            for _ in range(75):
                optimizer.zero_grad()
                output = gp_model(train_x)
                loss = -mll(output, train_y)
                loss.backward()
                optimizer.n_iter += 1
                optimizer.step()

            for param in gp_model.parameters():
                self.assertTrue(param.grad is not None)
                self.assertGreater(param.grad.norm().item(), 0)
            for param in likelihood.parameters():
                self.assertTrue(param.grad is not None)
                self.assertGreater(param.grad.norm().item(), 0)
            optimizer.step()

            # Test the model
            gp_model.eval()
            likelihood.eval()
            test_function_predictions = likelihood(gp_model(test_x))
            mean_abs_error = torch.mean(torch.abs(test_y - test_function_predictions.mean))

        self.assertLess(mean_abs_error.squeeze().item(), 0.05)

    def test_posterior_latent_gp_and_likelihood_with_optimization_cuda(self):
        if torch.cuda.is_available():
            with least_used_cuda_device():
                self.test_posterior_latent_gp_and_likelihood_with_optimization(cuda=True)

    def test_posterior_latent_gp_and_likelihood_fast_pred_var(self, cuda=False):
        train_x, test_x, train_y, test_y = self._get_data(cuda=cuda)
        with gpytorch.settings.fast_pred_var(), gpytorch.settings.debug(False):
            # We're manually going to set the hyperparameters to something they shouldn't be
            likelihood = GaussianLikelihood(noise_prior=SmoothedBoxPrior(exp(-3), exp(3), sigma=0.1))
            gp_model = ExactGPModel(train_x, train_y, likelihood)
            mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, gp_model)
            gp_model.rbf_covar_module.initialize(lengthscale=exp(1))
            gp_model.mean_module.initialize(constant=0)
            likelihood.initialize(noise=exp(1))

            if cuda:
                gp_model.cuda()
                likelihood.cuda()

            # Find optimal model hyperparameters
            gp_model.train()
            likelihood.train()
            optimizer = optim.Adam(list(gp_model.parameters()) + list(likelihood.parameters()), lr=0.1)
            optimizer.n_iter = 0
            for _ in range(50):
                optimizer.zero_grad()
                output = gp_model(train_x)
                loss = -mll(output, train_y)
                loss.backward()
                optimizer.n_iter += 1
                optimizer.step()

            for param in gp_model.parameters():
                self.assertTrue(param.grad is not None)
                self.assertGreater(param.grad.norm().item(), 0)
            for param in likelihood.parameters():
                self.assertTrue(param.grad is not None)
                self.assertGreater(param.grad.norm().item(), 0)
            optimizer.step()

            # Test the model
            gp_model.eval()
            likelihood.eval()
            # Set the cache
            test_function_predictions = likelihood(gp_model(train_x))

            # Now bump up the likelihood to something huge
            # This will make it easy to calculate the variance
            likelihood.raw_noise.data.fill_(3)
            test_function_predictions = likelihood(gp_model(train_x))

            noise = likelihood.noise
            var_diff = (test_function_predictions.variance - noise).abs()

            self.assertLess(torch.max(var_diff / noise), 0.05)

    def test_posterior_latent_gp_and_likelihood_fast_pred_var_cuda(self):
        if torch.cuda.is_available():
            with least_used_cuda_device():
                self.test_posterior_latent_gp_and_likelihood_fast_pred_var(cuda=True)

if __name__ == "__main__":
    unittest.main()


"""
Interfaces for serializing Django objects.

Usage::

    from django.core import serializers
    json = serializers.serialize("json", some_query_set)
    objects = list(serializers.deserialize("json", json))

To add your own serializers, use the SERIALIZATION_MODULES setting::

    SERIALIZATION_MODULES = {
        "csv" : "path.to.csv.serializer",
        "txt" : "path.to.txt.serializer",
    }

"""

from django.conf import settings
from django.utils import importlib

# Built-in serializers
BUILTIN_SERIALIZERS = {
    "xml"    : "django.core.serializers.xml_serializer",
    "python" : "django.core.serializers.python",
    "json"   : "django.core.serializers.json",
}

# Check for PyYaml and register the serializer if it's available.
try:
    import yaml
    BUILTIN_SERIALIZERS["yaml"] = "django.core.serializers.pyyaml"
except ImportError:
    pass

_serializers = {}

def register_serializer(format, serializer_module, serializers=None):
    """"Register a new serializer.

    ``serializer_module`` should be the fully qualified module name
    for the serializer.

    If ``serializers`` is provided, the registration will be added
    to the provided dictionary.

    If ``serializers`` is not provided, the registration will be made
    directly into the global register of serializers. Adding serializers
    directly is not a thread-safe operation.
    """
    module = importlib.import_module(serializer_module)
    if serializers is None:
        _serializers[format] = module
    else:
        serializers[format] = module

def unregister_serializer(format):
    "Unregister a given serializer. This is not a thread-safe operation."
    del _serializers[format]

def get_serializer(format):
    if not _serializers:
        _load_serializers()
    return _serializers[format].Serializer

def get_serializer_formats():
    if not _serializers:
        _load_serializers()
    return _serializers.keys()

def get_public_serializer_formats():
    if not _serializers:
        _load_serializers()
    return [k for k, v in _serializers.iteritems() if not v.Serializer.internal_use_only]

def get_deserializer(format):
    if not _serializers:
        _load_serializers()
    return _serializers[format].Deserializer

def serialize(format, queryset, **options):
    """
    Serialize a queryset (or any iterator that returns database objects) using
    a certain serializer.
    """
    s = get_serializer(format)()
    s.serialize(queryset, **options)
    return s.getvalue()

def deserialize(format, stream_or_string):
    """
    Deserialize a stream or a string. Returns an iterator that yields ``(obj,
    m2m_relation_dict)``, where ``obj`` is a instantiated -- but *unsaved* --
    object, and ``m2m_relation_dict`` is a dictionary of ``{m2m_field_name :
    list_of_related_objects}``.
    """
    d = get_deserializer(format)
    return d(stream_or_string)

def _load_serializers():
    """
    Register built-in and settings-defined serializers. This is done lazily so
    that user code has a chance to (e.g.) set up custom settings without
    needing to be careful of import order.
    """
    global _serializers
    serializers = {}
    for format in BUILTIN_SERIALIZERS:
        register_serializer(format, BUILTIN_SERIALIZERS[format], serializers)
    if hasattr(settings, "SERIALIZATION_MODULES"):
        for format in settings.SERIALIZATION_MODULES:
            register_serializer(format, settings.SERIALIZATION_MODULES[format], serializers)
    _serializers = serializers


__copyright__ = "Copyright 2017, Georgia Institute of Technology"
__license__ = "MIT"
__version_info__ = ('0', '0', '1')
__version__ = '.'.join(__version_info__)
__maintainer__ = "Marat Dukhan"
__email__ = "maratek@gmail.com"

import logging
logger = logging.getLogger("confu")
logger.setLevel(logging.INFO)

console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)

class ConsoleFormatter(logging.Formatter):
    def __init__(self):
        super(ConsoleFormatter, self).__init__("%(message)s")

    def format(self, record):
        message = super(ConsoleFormatter, self).format(record)
        if record.levelname in ["DEBUG", "INFO"]:
            return message[0].upper() + message[1:]
        else:
            return {
                "WARNING": "Warning", "ERROR": "Error", "CRITICAL": "Fatal error"
            }[record.levelname] + ": " + message[0].lower() + message[1:]

console_formatter = ConsoleFormatter()
console_handler.setFormatter(console_formatter)
logger.addHandler(console_handler)

from confu.builds import Build
from confu.platform import Platform

def standard_parser(description="Confu configuration script"):
    import argparse

    from os import linesep
    from confu.platform import host, possible_targets

    parser = argparse.ArgumentParser(description=description,
        formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("--target", dest="target", metavar="PLATFORM", type=Platform,
        default=host.name,
        help="platform where the code will run. Potential options:" + linesep +
            "    " + host.name + " (default)" + linesep +
            linesep.join("    " + target for target in possible_targets[1:]))
    parser.add_argument("--toolchain", dest="toolchain", metavar="TOOLCHAIN",
        choices=["auto", "gnu", "clang"], default="auto",
        help="toolchain to use for compilation. Potential options:" + linesep +
            linesep.join("    " + name for name in ["auto (default)", "gnu", "clang"]))

    return parser


import pytest

from commitizen import BaseCommitizen, defaults, factory
from commitizen.config import BaseConfig
from commitizen.exceptions import NoCommitizenFoundException

def test_factory():
    config = BaseConfig()
    config.settings.update({"name": defaults.name})
    r = factory.commiter_factory(config)
    assert isinstance(r, BaseCommitizen)

def test_factory_fails():
    config = BaseConfig()
    config.settings.update({"name": "Nothing"})
    with pytest.raises(NoCommitizenFoundException) as excinfo:
        factory.commiter_factory(config)

    assert "The committer has not been found in the system." in str(excinfo)


import datetime
import zipfile
from os import chdir, getpid, getcwd, listdir, walk, path

def listdir_cwd():
    """
    Lazy listdir for cwd.
    :return:
    """
    return listdir(getcwd())

def f(x, fn):
    """
    Le Zip
    :param x:
    :param fn:
    :return:
    """
    with zipfile.ZipFile.open(fn, 'a', zipfile.ZIP_LZMA, True) as file:
        file.write(x)
    file.close()
    print(f'{getpid()}: {x}')
    return x

def utc_now_to_file_str():
    """
    Format UTC now to _YYYYmmdd_HHMMSS
    :return:
    """
    return datetime.datetime.strftime(datetime.datetime.utcnow(), '_%Y%m%d_%H%M%S')

def create_filename(prefix, extension):
    """
    Create filename to be used.
    :param prefix:
    :param extension:
    :return:
    """
    return f'{prefix}{utc_now_to_file_str()}.{extension}'

def log_folders_destination_targets(dest, targets, filename):
    """
    Log Folders, destination, and targets.
    :param dest:
    :param targets:
    :param filename:
    :return:
    """
    print(f'\n Destination Folder: {dest}'
          f'\n Targets: {str(len(targets))}'
          f'\n File: {filename}')

def get_all_file_locs(targets):
    """
    Gets all file locations.
    :return:
    """
    file_list = []
    for target in targets:
        chdir(target)
        for root, dirs, files in walk(target):
            for file in files:
                file_list.append(path.join(root, file))
    return file_list


import collections
import enum

from itertools import starmap, product

import six

from ibis.compat import suppress
import ibis.util as util
import ibis.common as com
import ibis.expr.types as ir
import ibis.expr.schema as sch
import ibis.expr.datatypes as dt

try:
    from cytoolz import curry, compose, identity
except ImportError:
    from toolz import curry, compose, identity

def highest_precedence_dtype(exprs):
    """Return the highest precedence type from the passed expressions

    Also verifies that there are valid implicit casts between any of the types
    and the selected highest precedence type.
    This is a thin wrapper around datatypes highest precedence check.

    Parameters
    ----------
    exprs : Iterable[ir.ValueExpr]
      A sequence of Expressions

    Returns
    -------
    dtype: DataType
      The highest precedence datatype
    """
    if not exprs:
        raise ValueError('Must pass at least one expression')

    return dt.highest_precedence(expr.type() for expr in exprs)

def castable(source, target):
    """Return whether source ir type is implicitly castable to target

    Based on the underlying datatypes and the value in case of Literals
    """
    op = source.op()
    value = getattr(op, 'value', None)
    return dt.castable(source.type(), target.type(), value=value)

def comparable(left, right):
    return castable(left, right) or castable(right, left)

def cast(source, target):
    """Currently Literal to *Scalar implicit casts are allowed"""
    import ibis.expr.operations as ops  # TODO: don't use ops here

    if not castable(source, target):
        raise com.IbisTypeError('Source is not castable to target type!')

    # currently it prevents column -> scalar implicit castings
    # however the datatypes are matching
    op = source.op()
    if not isinstance(op, ops.Literal):
        raise com.IbisTypeError('Only able to implicitly cast literals!')

    out_type = target.type().scalar_type()
    return out_type(op)

# ---------------------------------------------------------------------
# Input type validators / coercion functions

class validator(curry):

    def __repr__(self):
        return '{}({}{})'.format(
            self.func.__name__,
            repr(self.args)[1:-1],
            ', '.join('{}={!r}'.format(k, v) for k, v in self.keywords.items())
        )

noop = validator(identity)

@validator
def one_of(inners, arg):
    """At least one of the inner validators must pass"""
    for inner in inners:
        with suppress(com.IbisTypeError, ValueError):
            return inner(arg)

    rules_formatted = ', '.join(map(repr, inners))
    raise com.IbisTypeError(
        'Arg passes neither of the following rules: {}'.format(rules_formatted)
    )

@validator
def all_of(inners, arg):
    """All of the inner valudators must pass.

    The order of inner validators matters.

    Parameters
    ----------
    inners : List[validator]
      Functions are applied from right to left so allof([rule1, rule2], arg) is
      the same as rule1(rule2(arg)).
    arg : Any
      Value to be validated.

    Returns
    -------
    arg : Any
      Value maybe coerced by inner validators to the appropiate types
    """
    return compose(*inners)(arg)

@validator
def isin(values, arg):
    if arg not in values:
        raise ValueError(
            'Value with type {} is not in {!r}'.format(type(arg), values)
        )
    if isinstance(values, dict):  # TODO check for mapping instead
        return values[arg]
    else:
        return arg

@validator
def member_of(obj, arg):
    if isinstance(arg, enum.Enum):
        enum.unique(obj)  # check that enum has unique values
        arg = arg.name

    if not hasattr(obj, arg):
        raise com.IbisTypeError(
            'Value with type {} is not a member of {}'.format(type(arg), obj)
        )
    return getattr(obj, arg)

@validator
def list_of(inner, arg, min_length=0):
    if isinstance(arg, six.string_types) or not isinstance(
        arg, (collections.Sequence, ir.ListExpr)
    ):
        raise com.IbisTypeError('Argument must be a sequence')

    if len(arg) < min_length:
        raise com.IbisTypeError(
            'Arg must have at least {} number of elements'.format(min_length)
        )
    return ir.sequence(list(map(inner, arg)))

@validator
def datatype(arg):
    return dt.dtype(arg)

@validator
def instance_of(klass, arg):
    """Require that a value has a particular Python type."""
    if not isinstance(arg, klass):
        raise com.IbisTypeError(
            'Given argument with type {} is not an instance of {}'.format(
                type(arg), klass
            )
        )
    return arg

@validator
def value(dtype, arg):
    """Validates that the given argument is a Value with a particular datatype

    Parameters
    ----------
    dtype : DataType subclass or DataType instance
    arg : python literal or an ibis expression
      If a python literal is given the validator tries to coerce it to an ibis
      literal.

    Returns
    -------
    arg : AnyValue
      An ibis value expression with the specified datatype
    """
    if not isinstance(arg, ir.Expr):
        # coerce python literal to ibis literal
        arg = ir.literal(arg)

    if not isinstance(arg, ir.AnyValue):
        raise com.IbisTypeError('Given argument with type {} is not a value '
                                'expression'.format(type(arg)))

    # retrieve literal values for implicit cast check
    value = getattr(arg.op(), 'value', None)

    if isinstance(dtype, type) and isinstance(arg.type(), dtype):
        # dtype class has been specified like dt.Interval or dt.Decimal
        return arg
    elif dt.castable(arg.type(), dt.dtype(dtype), value=value):
        # dtype instance or string has been specified and arg's dtype is
        # implicitly castable to it, like dt.int8 is castable to dt.int64
        return arg
    else:
        raise com.IbisTypeError('Given argument with datatype {} is not '
                                'subtype of {} nor implicitly castable to '
                                'it'.format(arg.type(), dtype))

@validator
def scalar(inner, arg):
    return instance_of(ir.ScalarExpr, inner(arg))

@validator
def column(inner, arg):
    return instance_of(ir.ColumnExpr, inner(arg))

@validator
def array_of(inner, arg):
    val = arg if isinstance(arg, ir.Expr) else ir.literal(arg)
    argtype = val.type()
    if not isinstance(argtype, dt.Array):
        raise com.IbisTypeError(
            'Argument must be an array, got expression {} which is of type '
            '{}'.format(val, val.type()))
    return value(dt.Array(inner(val[0]).type()), val)

any = value(dt.any)
double = value(dt.double)
string = value(dt.string)
boolean = value(dt.boolean)
integer = value(dt.int64)
decimal = value(dt.Decimal)
floating = value(dt.float64)
date = value(dt.date)
time = value(dt.time)
timestamp = value(dt.Timestamp)
category = value(dt.category)
temporal = one_of([timestamp, date, time])

strict_numeric = one_of([integer, floating, decimal])
soft_numeric = one_of([integer, floating, decimal, boolean])
numeric = soft_numeric

set_ = value(dt.Set)
array = value(dt.Array)
struct = value(dt.Struct)
mapping = value(dt.Map(dt.any, dt.any))

@validator
def interval(arg, units=None):
    arg = value(dt.Interval, arg)
    unit = arg.type().unit
    if units is not None and unit not in units:
        msg = 'Interval unit `{}` is not among the allowed ones {}'
        raise com.IbisTypeError(msg.format(unit, units))
    return arg

@validator
def client(arg):
    from ibis.client import Client
    return instance_of(Client, arg)

# ---------------------------------------------------------------------
# Ouput type promoter functions

def promoter(fn):
    def wrapper(name_or_value, *args, **kwargs):
        if isinstance(name_or_value, str):
            return lambda self: fn(getattr(self, name_or_value),
                                   *args, **kwargs)
        else:
            return fn(name_or_value, *args, **kwargs)
    return wrapper

@promoter
def shape_like(arg, dtype=None):
    if isinstance(arg, (tuple, list, ir.ListExpr)):
        datatype = dtype or highest_precedence_dtype(arg)
        columnar = util.any_of(arg, ir.AnyColumn)
    else:
        datatype = dtype or arg.type()
        columnar = isinstance(arg, ir.AnyColumn)

    dtype = dt.dtype(datatype)

    if columnar:
        return dtype.array_type()
    else:
        return dtype.scalar_type()

@promoter
def scalar_like(arg):
    output_dtype = arg.type()
    return output_dtype.scalar_type()

@promoter
def array_like(arg):
    output_dtype = arg.type()
    return output_dtype.array_type()

column_like = array_like

@promoter
def typeof(arg):
    return arg._factory

@validator
def table(schema, arg):
    """A table argument.

    Parameters
    ----------
    schema : Union[sch.Schema, List[Tuple[str, dt.DataType]]
        A validator for the table's columns. Only column subset validators are
        currently supported. Accepts any arguments that `sch.schema` accepts.
        See the example for usage.
    arg : The validatable argument.

    Examples
    --------
    The following op will accept an argument named ``'table'``. Note that the
    ``schema`` argument specifies rules for columns that are required to be in
    the table: ``time``, ``group`` and ``value1``. These must match the types
    specified in the column rules. Column ``value2`` is optional, but if
    present it must be of the specified type. The table may have extra columns
    not specified in the schema.
    """
    assert isinstance(arg, ir.TableExpr)

    if arg.schema() >= sch.schema(schema):
        return arg

    raise com.IbisTypeError(
        'Argument is not a table with column subset of {}'.format(schema)
    )

# TODO: might just use bounds instead of actual literal values
# that could simplify interval binop output_type methods
def _promote_numeric_binop(exprs, op):
    bounds, dtypes = [], []
    for arg in exprs:
        dtypes.append(arg.type())
        if hasattr(arg.op(), 'value'):
            # arg.op() is a literal
            bounds.append([arg.op().value])
        else:
            bounds.append(arg.type().bounds)

    # In some cases, the bounding type might be int8, even though neither
    # of the types are that small. We want to ensure the containing type is
    # _at least_ as large as the smallest type in the expression.
    values = starmap(op, product(*bounds))
    dtypes += [dt.infer(value, allow_overflow=True) for value in values]

    return dt.highest_precedence(dtypes)

@promoter
def numeric_like(args, op):
    if util.all_of(args, ir.IntegerValue):
        dtype = _promote_numeric_binop(args, op)
        return shape_like(args, dtype=dtype)
    else:
        return shape_like(args)

# TODO: create varargs marker for impala udfs


"""

    Test Convex Breaking

"""

import pytest
import secrets

from convex_api.account import Account
from convex_api.api import API
from convex_api.exceptions import ConvexAPIError
from convex_api.utils import (
    add_0x_prefix,
    to_address
)

def test_convex_recursion(convex, test_account):
    chain_length = 4
    address_list = []
    for index in range(0, chain_length):
        contract = f"""
(def chain-{index}
    (deploy
        '(do
            (def stored-data
                ^{{:private? true}}
                nil
            )
            (def chain-address
                ^{{:private? true}}
                nil
            )
            (defn get
                ^{{:callable? true}}
                []
                (call chain-address (get))
            )
            (defn set
                ^{{:callable? true}}
                [x]
                ( if chain-address (call chain-address(set x)) (def stored-data x))
            )
            (defn set-chain-address
                ^{{:callable? true}}
                [x]
                (def chain-address x)
            )
        )
    )
)
"""
        convex.topup_account(test_account)
        result = convex.send(contract, test_account)
        address_list.append(to_address(result['value']))
    for index in range(0, chain_length):
        next_index = index + 1
        if next_index == chain_length:
            next_index = 0
        call_address = address_list[next_index]
        result = convex.send(f'(call chain-{index} (set-chain-address #{call_address}))', test_account)
        test_number = secrets.randbelow(1000)
        if index == chain_length - 1:
            with pytest.raises(ConvexAPIError, match='DEPTH'):
                result = convex.send(f'(call chain-{index} (set {test_number}))', test_account)
        else:
            result = convex.send(f'(call chain-0 (set {test_number}))', test_account)
            assert(result)
            assert(result['value'] == test_number)
    with pytest.raises(ConvexAPIError, match='DEPTH'):
        convex.query('(call chain-0 (get))', test_account)

def test_schedule_transfer(convex, test_account, other_account):
    # you can send coins to an actor , if it exports the receive-coin function

    contract = """
(def transfer-for-ever
    (deploy
        '(do
            (defn tx-delay
                ^{:callable? true}
                [to-address amount]
                (transfer to-address amount)
                (def call-address *address*)
                (schedule (+ *timestamp* 1000) (call call-address (tx-delay to-address amount)))
            )
            (defn tx-now
                ^{:callable? true}
                [to-address amount]
                (transfer to-address amount)
            )
            (defn show-schedule
                ^{:callable? true}
                []
                [(get *state* :schedule) *address*]
            )
            (defn receive-coin
                ^{:callable? true}
                [sender amount data]
                (accept amount)
            )
        )
    )
)
"""
# (call contract-address (tx-to to-address amount))

    convex.topup_account(test_account)
    convex.topup_account(other_account, 8000000)
    result = convex.send(contract, test_account)
    contract_address = to_address(result['value'])
    convex.transfer(contract_address, 800000, other_account)
    convex.topup_account(test_account)
    result = convex.send(f'(call #{contract_address} (tx-delay #{other_account.address} 1000))', test_account)
    print(result)
    result = convex.send(f'(call #{contract_address} (show-schedule))', test_account)
    print(result)


# Autores:
# Darlan de Castro Silva Filho
# Marcos Henrique Fernandes Marcone

from pandas import Series, DataFrame
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.graph_objs as go
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_table

# Funções de estilização e opções das bibliotecas utilizadas
plt.style.use('classic')
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)

# Função para o path das bases de dados
# Entrada: nome = string
# Saida: path = string

def path(nome):
    return './'+nome+'.csv'

# Importa os arquivos (bases de dados) utilizados
unidades = pd.read_csv(path('unidades'), sep=';')
docentes = pd.read_csv(path('docentes'), sep=';')
avaliacao = pd.read_csv(path('avaliacaoDocencia'), sep=';')

# Filtra os docentes que trabalham em Natal e que tenham a categoria de Professor do Magistério Superior
unidadesFiltradas = unidades.loc[:, [
    'id_unidade', 'municipio', 'unidade_responsavel']]
docentesComUnidadeAcademica = pd.merge(
    docentes, unidadesFiltradas, left_on="id_unidade_lotacao", right_on="id_unidade").drop('id_unidade', axis=1)
docentesNatalUnidadeAcademica = docentesComUnidadeAcademica[
    docentesComUnidadeAcademica['municipio'] == 'NATAL']
docentesNatalMSUnidadeAcademica = docentesNatalUnidadeAcademica[
    docentesNatalUnidadeAcademica['categoria'] == 'PROFESSOR DO MAGISTERIO SUPERIOR']

# Filtra as unidades_dirigentes não aceitas pela aplicação
docentesNatalMSUnidadeAcademica['unidade_dirigente'] = np.where(docentesNatalMSUnidadeAcademica['unidade_responsavel'] == 'UNIVERSIDADE FEDERAL DO RIO GRANDE DO NORTE', (
    docentesNatalMSUnidadeAcademica['lotacao']), (docentesNatalMSUnidadeAcademica['unidade_responsavel']))
unidadesNaoAceitas = ['PRÓ-REITORIA DE EXTENSÃO UNIVERSITÁRIA', 'MUSEU CÂMARA CASCUDO', 'UNIVERSIDADE FEDERAL DO RIO GRANDE DO NORTE', 'EDITORA UNIVERSITÁRIA', 'EMPRESA BRASILEIRA DE SERVICOS HOSPITALARES',
                      'REITORIA', 'INSTITUTO DE MEDICINA TROPICAL - IMT-RN', 'SECRETARIA DE EDUCAÇÃO A DISTÂNCIA', 'GABINETE DO REITOR', 'SUPERINTENDENCIA DE COMUNICACAO', 'PRÓ-REITORIA DE ADMINISTRAÇÃO (PROAD)']
docentesNatalMSUnidadeAcademica = docentesNatalMSUnidadeAcademica[~docentesNatalMSUnidadeAcademica['unidade_dirigente'].isin(
    unidadesNaoAceitas)]

# Gráfico de barras da distribuição dos docentes da UFRN por unidade acadêmica
quantidadeDocentesUnidadeDirigente = docentesNatalMSUnidadeAcademica['unidade_dirigente'].value_counts(
)
barraDocentesUnidadeDirigente = go.Bar(x=quantidadeDocentesUnidadeDirigente.index,
                                       y=quantidadeDocentesUnidadeDirigente.values, text=quantidadeDocentesUnidadeDirigente.values, textposition='auto')
layoutDocentesUnidadeDirigente = go.Layout(title='Gráfico de docentes por unidade responsável (UFRN 2021 - Unidades de Natal - Magistério Superior)', xaxis={
                                           'title': 'Unidade responsável'}, yaxis={'title': 'Número de docentes'})
figuraDocentesUnidadeDirigente = go.Figure(
    data=[barraDocentesUnidadeDirigente], layout=layoutDocentesUnidadeDirigente)

# Gráfico de pizza da distribuição dos docentes da UFRN por sexo
quantidadeDocentesSexo = docentesNatalMSUnidadeAcademica['sexo'].value_counts()
piechartSexo = go.Pie(labels=['Masculino', 'Feminino'], values=quantidadeDocentesSexo.values, text=quantidadeDocentesSexo.values, marker={
                      'colors': ['#665FD1', '#FFFF7E'], 'line': dict(color='#000000', width=2)})
layoutDocentesSexo = go.Layout(title='Gráfico de docentes por sexo (UFRN 2021 - Unidades de Natal - Magistério Superior)',
                               xaxis={'title': 'Docentes'}, yaxis={'title': 'Número de docentes'}, barmode='stack')
figuraDocentesSexo = go.Figure(data=piechartSexo, layout=layoutDocentesSexo)

# Gráfico de pizza da distribuição dos docentes da UFRN por formação acadêmica
quantidadeDocentesFormacao = docentesNatalMSUnidadeAcademica['formacao'].value_counts(
)
piechartFormacao = go.Pie(labels=quantidadeDocentesFormacao.index, values=quantidadeDocentesFormacao.values, text=quantidadeDocentesFormacao.values, marker={
                          'colors': ['#665FD1', '#FFFF7E', '#F5054F', '#3F012C'], 'line': dict(color='#000000', width=2)})
layoutDocentesFormacao = go.Layout(title='Gráfico de docentes por formação (UFRN 2021 - Unidades de Natal - Magistério Superior)',
                                   xaxis={'title': 'Formação'}, yaxis={'title': 'Número de docentes'})
figuraDocentesFormacao = go.Figure(
    data=[piechartFormacao], layout=layoutDocentesFormacao)

# Gráfico de pizza da distribuição dos docentes da UFRN por classe funcional
quantidadeDocentesClasseFuncional = docentesNatalMSUnidadeAcademica['classe_funcional'].value_counts(
).sort_index()
piechartClasseFuncional = go.Pie(labels=quantidadeDocentesClasseFuncional.index, values=quantidadeDocentesClasseFuncional.values,
                                 text=quantidadeDocentesClasseFuncional.values, marker={'colors': px.colors.qualitative.Dark24, 'line': dict(color='#000000', width=2)})
barraDocentesClasseFuncional = go.Bar(x=quantidadeDocentesClasseFuncional.index, y=quantidadeDocentesClasseFuncional.values,
                                      text=quantidadeDocentesClasseFuncional.values, textposition='auto', marker={'color': '#5D21D0'})
layoutDocentesClasseFuncional = go.Layout(title='Gráfico de docentes por classe funcional (UFRN 2021 - Unidades de Natal - Magistério Superior)', xaxis={
                                          'title': 'Classe funcional'}, yaxis={'title': 'Número de docentes'}, height=450)
figuraDocentesClasseFuncional = go.Figure(
    data=[piechartClasseFuncional], layout=layoutDocentesClasseFuncional)

# Cria gráfico para ressaltar os dados de classe funcional dos docentes agrupados por unidade_dirigente
filtroClasseFuncional = ['unidade_dirigente', 'classe_funcional']
docentesClasseGroupBy = docentesNatalMSUnidadeAcademica.groupby(
    filtroClasseFuncional).count().reset_index().loc[:, filtroClasseFuncional + ['nome']]
docentesClasseGroupBy['quantidade'] = docentesClasseGroupBy['nome']
del docentesClasseGroupBy['nome']
figClasseDetalhe = px.bar(docentesClasseGroupBy, x="unidade_dirigente", y="quantidade", color="classe_funcional",
                          text='quantidade', color_discrete_sequence=px.colors.qualitative.Bold, height=800)

# Cria gráfico para ressaltar os dados de sexo dos docentes agrupados por unidade_dirigente
filtroSexo = ['unidade_dirigente', 'sexo']
docentesSexoGroupBy = docentesNatalMSUnidadeAcademica.groupby(
    filtroSexo).count().reset_index().loc[:, filtroSexo + ['nome']]
docentesSexoGroupBy['quantidade'] = docentesSexoGroupBy['nome']
del docentesSexoGroupBy['nome']
figSexoDetalhe = px.bar(docentesSexoGroupBy, x="unidade_dirigente", y="quantidade",
                        color="sexo", text='quantidade', color_discrete_sequence=px.colors.qualitative.Bold)

# Cria gráfico para ressaltar os dados de formação acadêmica dos docentes agrupados por unidade_dirigente
filtroFormacao = ['unidade_dirigente', 'formacao']
docentesFormacaoGroupBy = docentesNatalMSUnidadeAcademica.groupby(
    filtroFormacao).count().reset_index().loc[:, filtroFormacao + ['nome']]
docentesFormacaoGroupBy['quantidade'] = docentesFormacaoGroupBy['nome']
del docentesFormacaoGroupBy['nome']
figFormacaoDetalhe = px.bar(docentesFormacaoGroupBy, x="unidade_dirigente",
                            y="quantidade", color="formacao", text='quantidade', range_y=[0, 400])

# Cria um dicionário com os dados indexados por unidade_dirigente
unidadesDirigentes = docentesNatalMSUnidadeAcademica['unidade_dirigente'].unique(
)
unidadesDirigentes
dfUnidadesDirigentes = {}
for unidadeDirigente in unidadesDirigentes:
    df = docentesNatalMSUnidadeAcademica[docentesNatalMSUnidadeAcademica['unidade_dirigente'] == unidadeDirigente]
    dfUnidadesDirigentes[unidadeDirigente] = df

# Função utilizada na filtragem de um dataFrame agrupando os dados por uma propriedade e o filtrando por outras duas
# Entradas: df = DataFrame, title = string, x = string, y = string, cor = ['rgb(a,b,c)','rgb(d,e,f)'...]
# Saídas: figAdmissao = Gráfico de barras

def filtrarDFPorUnidadeDirigente(df, title, x, y, cor=px.colors.qualitative.Bold):
    dfFinal = df[title]
    filtro = [x, y]
    docentesFiltroGroupBy = dfFinal.groupby(
        filtro).count().reset_index().loc[:, filtro + ['nome']]
    docentesFiltroGroupBy['quantidade'] = docentesFiltroGroupBy['nome']
    del docentesFiltroGroupBy['nome']
    figAdmissao = px.bar(docentesFiltroGroupBy, x=x, y="quantidade", color=y,
                         text='quantidade', color_discrete_sequence=cor, title=title)
    return figAdmissao

# Cria e formata um dataFrame geral com todos os professores e os atributos necessários para a geração dos gráficos e da tabela por média
avaliacaoDocentesFiltro = avaliacao[avaliacao['nome_docente'].isin(
    docentesNatalMSUnidadeAcademica['nome'])]
avaliacaoDocentesFiltro['total_postura'] = avaliacaoDocentesFiltro['postura_profissional_media'] * \
    avaliacaoDocentesFiltro['qtd_discentes']
avaliacaoDocentesFiltro['total_atuacao'] = avaliacaoDocentesFiltro['atuacao_profissional_media'] * \
    avaliacaoDocentesFiltro['qtd_discentes']
docentesMedias = avaliacaoDocentesFiltro.loc[:, [
    'nome_docente', 'qtd_discentes', 'total_postura', 'total_atuacao']]
docentesMediasGroupBy = docentesMedias.groupby(['nome_docente']).sum()
docentesMediasGroupBy['media_postura'] = docentesMediasGroupBy['total_postura'] / \
    docentesMediasGroupBy['qtd_discentes']
docentesMediasGroupBy['media_atuacao'] = docentesMediasGroupBy['total_atuacao'] / \
    docentesMediasGroupBy['qtd_discentes']
docentesMediasGroupBy['media_alunos'] = avaliacaoDocentesFiltro.groupby(
    ['nome_docente']).mean().loc[:, 'autoavaliacao_aluno_media']
docentesMediasNatalMSUnidadeAcademica = pd.merge(
    docentesNatalMSUnidadeAcademica, docentesMediasGroupBy, left_on="nome", right_on="nome_docente").round(3)

# Exclui os campos não necessários para a geração da tabela de notas e assinala os campos restantes para um novo dataFrame
docenteParaTabelaNotas = docentesMediasNatalMSUnidadeAcademica.loc[:, [
    'nome', 'media_postura', 'media_atuacao', 'media_alunos', 'unidade_dirigente', 'lotacao', 'qtd_discentes']]

# Faz a filtragem e formatação de um dataFrame para agrupas os dados da media_postura, media_atuacao e media_alunos por undade_dirigente
docentesMediaUnidadeDirigente = docentesMediasNatalMSUnidadeAcademica.groupby(
    'unidade_dirigente').mean().loc[:, ['media_postura', 'media_atuacao', 'media_alunos']]
docentesMediaUnidadeDirigente['unidade_dirigente'] = docentesMediaUnidadeDirigente.index

# Faz a filtragem e formatação de um dataFrame para conter as informações da media_postura, media_atuacao e media_alunos a serem apresentas no gráfico de linha por evolução temporal
docentesMediasAno = avaliacaoDocentesFiltro.loc[:, [
    'nome_docente', 'qtd_discentes', 'total_postura', 'total_atuacao', 'ano']]
docentesMediasAnoGroupBy = docentesMediasAno.groupby(['ano']).sum()
docentesMediasAnoGroupBy['media_postura'] = docentesMediasAnoGroupBy['total_postura'] / \
    docentesMediasAnoGroupBy['qtd_discentes']
docentesMediasAnoGroupBy['media_atuacao'] = docentesMediasAnoGroupBy['total_atuacao'] / \
    docentesMediasAnoGroupBy['qtd_discentes']
docentesMediasAnoGroupBy['media_alunos'] = avaliacaoDocentesFiltro.groupby(
    ['ano']).mean().loc[:, 'autoavaliacao_aluno_media']
docentesMediasAnoGroupBy['ano'] = docentesMediasAnoGroupBy.index

# Cria o gráfico de linhas da evolução temporal da media_postura, media_atuacao e media_alunos
figuraMediasAnoGroupBy = go.Figure()
figuraMediasAnoGroupBy.add_trace(go.Scatter(x=docentesMediasAnoGroupBy['ano'], y=docentesMediasAnoGroupBy['media_postura'],
                                            mode='lines',
                                            name='media_postura'))
figuraMediasAnoGroupBy.add_trace(go.Scatter(x=docentesMediasAnoGroupBy['ano'], y=docentesMediasAnoGroupBy['media_atuacao'],
                                            mode='lines',
                                            name='media_atuacao'))
figuraMediasAnoGroupBy.add_trace(go.Scatter(x=docentesMediasAnoGroupBy['ano'], y=docentesMediasAnoGroupBy['media_alunos'],
                                            mode='lines',
                                            name='media_alunos'))
figuraMediasAnoGroupBy.update_layout(
    title='Evolução da avaliação dos discentes e docentes do magistério superior da UFRN nos anos de 2013 à 2019')

# Define as opções de unidades dirigentes que serão mostradas no 'dropdown-1'
indicadoresDropdown1 = [
    'GERAL'] + list(docentesNatalMSUnidadeAcademica['unidade_dirigente'].unique())

# Estilos das divs dos gráficos iniciais
estilosDivGraficosIniciais = {'width': '95%',
                              'display': 'inline-block', 'padding': '0 20'}

# Cria a variável app e escolhe os stylesheets da aplicação
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

# Define o layout a ser apresentado na página web
app.layout = html.Div([
    html.H1(children='Análise dos dados dos docentes do magistério superior da UFRN das unidades de Natal no ano de 2021'),
    html.Div([
        dcc.Markdown('''
Trabalho referente à disciplina DCA-0131, Ciência de Dados, ministrada pelo professor Luiz Affonso Hederson Guedes de Oliveira.

Plataforma desenvolvida pelos discentes Darlan de Castro e Marcos Henrique, alunos do curso de Engenharia Computação da UFRN.

A aplicação web desenvolvida consiste em uma análise exploratória dos dados sobre os docentes do magistério superior das unidades de Natal da Universidade Federal do Rio Grande do Norte (UFRN) no ano de 2021.

Os dados utilizados aqui podem ser acessados pelo seguinte site: [http://dados.ufrn.br](http://dados.ufrn.br)

As principais tecnologias usadas para o desenvolvimento da plataforma foram:

* Linguagem Python;
* Pacotes Pandas, Plotly e Dash;
* Heroku (deploy da aplicação).
''')
    ]),
    html.H2(
        children='Divisão dos docentes do magistério superior da UFRN no ano de 2021'),
    html.Div([

        html.Div([
            dcc.Markdown('''
            Nesta seção da aplicação pode-se acompanhar a divisão dos docentes através de difentes categorias, como sexo, formação e classe funcional, assim como ver como eles estão distribuídos por cada unidade responsável na UFRN.

            Na primeira caixa de seleção pode-se escolher qual unidade responsável deseja-se analisar. Assim, são atualizados os três primeiros gráficos com informações das divisões dos decentes referentes a cada lotação que compõe aquela unidade responsável.

            Se a opção for escolhida for "GERAL", então pode-se mostar gráficos gerais sobre toda as unidades de Natal da UFRN, ou gráficos detalhados mostrando a divisão por unidades responsáveis.
            '''),
            dcc.Dropdown(
                id='dropdown-1',
                options=[{'label': i, 'value': i}
                         for i in indicadoresDropdown1],
                value='GERAL'
            ),
            dcc.RadioItems(
                id='radioitems-1',
                options=[{'label': i, 'value': i}
                         for i in ['GERAL', 'DETALHADA']],
                value='GERAL',
                labelStyle={'display': 'inline-block'}
            )
        ],
            style={'width': '80%', 'display': 'inline-block'}),

        html.Div([
            dcc.Graph(
                id='grafico-sexo')
        ], style=estilosDivGraficosIniciais),
        html.Div([
            dcc.Graph(
                id='grafico-formacao')
        ], style=estilosDivGraficosIniciais),
        html.Div([
            dcc.Graph(
                id='grafico-classe')
        ], style=estilosDivGraficosIniciais),
        html.Div([
            dcc.Graph(
                id='grafico-sobra',
                figure=figuraDocentesUnidadeDirigente)
        ], style=estilosDivGraficosIniciais, id='div-grafico-sobra'),
    ]),

    html.H2(children='Estatísticas das avaliações dos docentes do magistério superior da UFRN (campus Natal) nos anos de 2013 à 2019'),
    dcc.Markdown('''
    Nesta seção da aplicação pode-se acompanhar dados sobre as avaliações dos docentes da UFRN e da autoavalição dos alunos feita a cada fim de semestre. Os dados disponibilizados constam do período de 2013 à 2019.

    Ao todo são três dados importantes a serem considerados a média de postura dos docentes, a média de atuação dos docentes e autoavaliação dos alunos.

    No primeiro gráfico pode-se acompanhar a média desses três quesitos por cada unidade responsável.
    '''),
    html.Div([
        dcc.Graph(
            id='grafico-nota-1')
    ], style={'width': '95%', 'display': 'inline-block', 'padding': '0 20'}),
    html.Div([
        dcc.Slider(
            id='slider-grafico-nota-1',
            min=1,
            max=3,
            value=1,
            marks={str(i): str(i) for i in [1, 2, 3]},
            step=None)],
        style={'width': '80%', 'padding': '0px 15px 15px 15px'}),

    dcc.Markdown('''
    * Opção 1 - Média de atuação dos docentes;
    * Opção 2 - Média de postura dos docentes;
    * Opção 3 - Média da autoavaliação dos discentes.
    '''),

    dcc.Markdown('''
    No segundo gráfico há dados sobre a evolução das médias de postura e atuação dos docentes e autoavaliação dos discentes ao longo dos anos.
            '''),

    html.Div([
        dcc.Graph(
            id='grafico-nota-2',
            figure=figuraMediasAnoGroupBy)
    ], style={'width': '95%', 'display': 'inline-block', 'padding': '0 20'}),

    dcc.Markdown('''
    No terceito gráfico pode-se ver um histograma com a frequência das médias de postura e atuação dos docentes dividida por sexo.
            '''),

    html.Div([
        dcc.Graph(
            id='grafico-histograma')
    ], style={'width': '95%', 'display': 'inline-block', 'padding': '0 20'}),
    html.Div([
        dcc.Slider(
            id='slider-grafico-histograma',
            min=1,
            max=2,
            value=1,
            marks={str(i): str(i) for i in [1, 2]},
            step=None)],
        style={'width': '80%', 'padding': '0px 15px 15px 15px'}),

    dcc.Markdown('''
        * Opção 1 - Média de atuação dos docentes;
        * Opção 2 - Média de postura dos docentes.
            '''),

    dcc.Markdown('''
    Nesta parte, pode-se selecionar uma unidade responsável (primeira caixa de seleção) e a partir dela escolher uma lotação (segunda caixa de seleção) para verificar a média de atuação e postura de cada profressor, assim como da autoavaliação dos discentes das turmas desses docentes e quantidade de discentes que passaram por eles, para cada departamento da UFRN.
    '''),
    html.Div([
        dcc.Dropdown(
            id='dropdown-2',
            options=[{'label': i, 'value': i}
                     for i in docenteParaTabelaNotas['unidade_dirigente'].unique()],
            value=docenteParaTabelaNotas['unidade_dirigente'].iloc[0]
        )],
        style={'width': '80%', 'display': 'inline-block'}),

    html.Div([
        dcc.Dropdown(
            id='dropdown-3',
        )],
        style={'width': '80%', 'display': 'inline-block'}),

    html.Div([
        dash_table.DataTable(
            id='table-nota',
            columns=[{"name": i, "id": i} for i in [
                'nome', 'media_postura', 'media_atuacao', 'media_alunos', 'qtd_discentes']],
            style_cell={'textAlign': 'left'},
        )
    ], style={'width': '95%', 'display': 'inline-block', 'padding': '0 20'}),

])

# Callback para atualização do estilo dos gráfico de barras (quatantidadeDocente x unidade_dirigente)
# Entradas: 'value' - 'dropdown-1', 'value' - 'radioitems-1'
# Saída: 'figure' - 'grafico-classe'

@app.callback(
    dash.dependencies.Output('div-grafico-sobra', 'style'),
    [dash.dependencies.Input('dropdown-1', 'value'),
     dash.dependencies.Input('radioitems-1', 'value')])
def visibility_graficoSobra(dropValue, radioValue):
    if(radioValue == 'GERAL' and dropValue == 'GERAL'):
        estilosDivGraficosIniciais['display'] = 'inline-block'
        return estilosDivGraficosIniciais
    estilosDivGraficosIniciais['display'] = 'none'
    return estilosDivGraficosIniciais

# Callback para atualização da 'figure' no gráfico por sexo.
# Entradas: 'value' - 'dropdown-1', 'value' - 'radioitems-1'
# Saída: 'figure' - 'grafico-sexo'

@app.callback(
    dash.dependencies.Output('grafico-sexo', 'figure'),
    [dash.dependencies.Input('dropdown-1', 'value'),
     dash.dependencies.Input('radioitems-1', 'value')])
def att_sexo(dropValue, radioValue):
    if(radioValue == 'GERAL' and dropValue == 'GERAL'):
        return figuraDocentesSexo
    elif(radioValue == 'DETALHADA' and dropValue == 'GERAL'):
        return figSexoDetalhe
    return filtrarDFPorUnidadeDirigente(dfUnidadesDirigentes, dropValue, 'lotacao', 'sexo')

# Callback para atualização da 'figure' no gráfico por formação
# Entradas: 'value' - 'dropdown-1', 'value' - 'radioitems-1'
# Saída: 'figure' - 'grafico-formacao'

@app.callback(
    dash.dependencies.Output('grafico-formacao', 'figure'),
    [dash.dependencies.Input('dropdown-1', 'value'),
     dash.dependencies.Input('radioitems-1', 'value')])
def att_formacao(dropValue, radioValue):
    if(radioValue == 'GERAL' and dropValue == 'GERAL'):
        return figuraDocentesFormacao
    elif(radioValue == 'DETALHADA' and dropValue == 'GERAL'):
        return figFormacaoDetalhe
    return filtrarDFPorUnidadeDirigente(dfUnidadesDirigentes, dropValue, 'lotacao', 'formacao')

# Callback para atualização da 'figure' no gráfico por classe
# Entradas: 'value' - 'dropdown-1', 'value' - 'radioitems-1'
# Saída: 'figure' - 'grafico-classe'

@app.callback(
    dash.dependencies.Output('grafico-classe', 'figure'),
    [dash.dependencies.Input('dropdown-1', 'value'),
     dash.dependencies.Input('radioitems-1', 'value')])
def att_classe(dropValue, radioValue):
    if(radioValue == 'GERAL' and dropValue == 'GERAL'):
        return figuraDocentesClasseFuncional
    elif(radioValue == 'DETALHADA' and dropValue == 'GERAL'):
        return figClasseDetalhe
    return filtrarDFPorUnidadeDirigente(dfUnidadesDirigentes, dropValue, 'lotacao', 'classe_funcional')

# Callback para atualização da 'figure' no gráfico por nota
# Entradas: 'value' - 'slider-grafico-nota-1'
# Saída: 'figure' - 'grafico-nota-1'

@app.callback(
    dash.dependencies.Output('grafico-nota-1', 'figure'),
    [dash.dependencies.Input('slider-grafico-nota-1', 'value')])
def att_nota1(sliderValue):
    var = 'media_atuacao'
    if sliderValue == 2:
        var = 'media_postura'
    elif sliderValue == 3:
        var = 'media_alunos'
    return px.scatter(docentesMediaUnidadeDirigente, x="unidade_dirigente", y=var,
                      size=var, hover_name="unidade_dirigente", color="unidade_dirigente")

# Callback para atualização da 'figure' no histograma
# Entradas: 'value' - 'slider-grafico-histograma'
# Saída: 'figure' - 'grafico-histograma'

@app.callback(
    dash.dependencies.Output('grafico-histograma', 'figure'),
    [dash.dependencies.Input('slider-grafico-histograma', 'value')])
def att_histograma(sliderValue):
    var = 'media_atuacao'
    if sliderValue == 2:
        var = 'media_postura'
    return px.histogram(docentesMediasNatalMSUnidadeAcademica, x=var, color="sexo", title='Histograma da avaliação dos docentes do magistério superior da UFRN nos anos de 2013 à 2019')

# Callback para atualização das 'options' no dropdown por lotação da tabela
# Entradas: 'value' - 'dropdown-2'
# Saída: 'options' - 'dropdown-3'

@app.callback(
    dash.dependencies.Output('dropdown-3', 'options'),
    [dash.dependencies.Input('dropdown-2', 'value')])
def att_dropdown3Options(dropValue):
    df = docenteParaTabelaNotas[docenteParaTabelaNotas['unidade_dirigente'] == dropValue]
    del df['unidade_dirigente']
    return [{'label': 'GERAL', 'value': 'GERAL'}] + [{'label': i, 'value': i} for i in df['lotacao'].unique()]

# Callback para atualização do 'value' no dropdown por lotação da tabela
# Entradas: 'value' - 'dropdown-2'
# Saída: 'value' - 'dropdown-3'

@app.callback(
    dash.dependencies.Output('dropdown-3', 'value'),
    [dash.dependencies.Input('dropdown-2', 'value')])
def att_dropdown3Value(dropValue):
    return 'GERAL'

# Callback para atualização da 'data' na tabela de exposição das notas dos professores por unidade_dirigente e lotação
# Entradas: 'value' - 'dropdown-2', value' - 'dropdown-3'
# Saída: 'data' - 'table-nota'

@app.callback(
    dash.dependencies.Output('table-nota', 'data'),
    [dash.dependencies.Input('dropdown-2', 'value'),
     dash.dependencies.Input('dropdown-3', 'value')])
def att_table(dropValue2, dropValue3):
    df = docenteParaTabelaNotas[docenteParaTabelaNotas['unidade_dirigente'] == dropValue2]
    del df['unidade_dirigente']
    if dropValue3 == 'GERAL':
        del df['lotacao']
        return df.to_dict("records")
    df = docenteParaTabelaNotas[docenteParaTabelaNotas['lotacao'] == dropValue3]
    del df['lotacao']
    return df.to_dict("records")

# Atribui o servidor da aplicação a variável server
server = app.server

if __name__ == '__main__':
    app.run_server(debug=True)


# exported from PySB model 'model'

from pysb import Model, Monomer, Parameter, Expression, Compartment, Rule, Observable, Initial, MatchOnce, Annotation, ANY, WILD

Model()

Monomer('Ligand', ['Receptor'])
Monomer('ParpU', ['C3A'])
Monomer('C8A', ['BidU', 'C3pro'])
Monomer('SmacM', ['BaxA'])
Monomer('BaxM', ['BidM', 'BaxA'])
Monomer('Apop', ['C3pro', 'Xiap'])
Monomer('Fadd', ['Receptor', 'C8pro'])
Monomer('SmacC', ['Xiap'])
Monomer('ParpC')
Monomer('Xiap', ['SmacC', 'Apop', 'C3A'])
Monomer('C9')
Monomer('C3ub')
Monomer('C8pro', ['Fadd', 'C6A'])
Monomer('C6A', ['C8pro'])
Monomer('C3pro', ['Apop', 'C8A'])
Monomer('CytoCM', ['BaxA'])
Monomer('CytoCC')
Monomer('BaxA', ['BaxM', 'BaxA_1', 'BaxA_2', 'SmacM', 'CytoCM'])
Monomer('ApafI')
Monomer('BidU', ['C8A'])
Monomer('BidT')
Monomer('C3A', ['Xiap', 'ParpU', 'C6pro'])
Monomer('ApafA')
Monomer('BidM', ['BaxM'])
Monomer('Receptor', ['Ligand', 'Fadd'])
Monomer('C6pro', ['C3A'])

Parameter('bind_0_Ligand_binder_Receptor_binder_target_2kf', 1.0)
Parameter('bind_0_Ligand_binder_Receptor_binder_target_1kr', 1.0)
Parameter('bind_0_Receptor_binder_Fadd_binder_target_2kf', 1.0)
Parameter('bind_0_Receptor_binder_Fadd_binder_target_1kr', 1.0)
Parameter('substrate_binding_0_Fadd_catalyzer_C8pro_substrate_2kf', 1.0)
Parameter('substrate_binding_0_Fadd_catalyzer_C8pro_substrate_1kr', 1.0)
Parameter('catalytic_step_0_Fadd_catalyzer_C8pro_substrate_C8A_product_1kc', 1.0)
Parameter('catalysis_0_C8A_catalyzer_BidU_substrate_BidT_product_2kf', 1.0)
Parameter('catalysis_0_C8A_catalyzer_BidU_substrate_BidT_product_1kr', 1.0)
Parameter('catalysis_1_C8A_catalyzer_BidU_substrate_BidT_product_1kc', 1.0)
Parameter('conversion_0_CytoCC_subunit_d_ApafI_subunit_c_ApafA_complex_2kf', 1.0)
Parameter('conversion_0_CytoCC_subunit_d_ApafI_subunit_c_ApafA_complex_1kr', 1.0)
Parameter('inhibition_0_SmacC_inhibitor_Xiap_inh_target_2kf', 1.0)
Parameter('inhibition_0_SmacC_inhibitor_Xiap_inh_target_1kr', 1.0)
Parameter('conversion_0_C9_subunit_d_ApafA_subunit_c_Apop_complex_2kf', 1.0)
Parameter('conversion_0_C9_subunit_d_ApafA_subunit_c_Apop_complex_1kr', 1.0)
Parameter('catalysis_0_Apop_catalyzer_C3pro_substrate_C3A_product_2kf', 1.0)
Parameter('catalysis_0_Apop_catalyzer_C3pro_substrate_C3A_product_1kr', 1.0)
Parameter('catalysis_1_Apop_catalyzer_C3pro_substrate_C3A_product_1kc', 1.0)
Parameter('inhibition_0_Xiap_inhibitor_Apop_inh_target_2kf', 1.0)
Parameter('inhibition_0_Xiap_inhibitor_Apop_inh_target_1kr', 1.0)
Parameter('catalysis_0_Xiap_catalyzer_C3A_substrate_C3ub_product_2kf', 1.0)
Parameter('catalysis_0_Xiap_catalyzer_C3A_substrate_C3ub_product_1kr', 1.0)
Parameter('catalysis_1_Xiap_catalyzer_C3A_substrate_C3ub_product_1kc', 1.0)
Parameter('catalysis_0_C3A_catalyzer_ParpU_substrate_ParpC_product_2kf', 1.0)
Parameter('catalysis_0_C3A_catalyzer_ParpU_substrate_ParpC_product_1kr', 1.0)
Parameter('catalysis_1_C3A_catalyzer_ParpU_substrate_ParpC_product_1kc', 1.0)
Parameter('equilibration_0_BidT_equil_a_BidM_equil_b_1kf', 1.0)
Parameter('equilibration_0_BidT_equil_a_BidM_equil_b_1kr', 1.0)
Parameter('catalysis_0_BidM_catalyzer_BaxM_substrate_BaxA_product_2kf', 1.0)
Parameter('catalysis_0_BidM_catalyzer_BaxM_substrate_BaxA_product_1kr', 1.0)
Parameter('catalysis_1_BidM_catalyzer_BaxM_substrate_BaxA_product_1kc', 1.0)
Parameter('self_catalyze_0_BaxA_self_catalyzer_BaxM_self_substrate_2kf', 1.0)
Parameter('self_catalyze_0_BaxA_self_catalyzer_BaxM_self_substrate_1kr', 1.0)
Parameter('self_catalyze_1_BaxA_self_catalyzer_BaxM_self_substrate_1kc', 1.0)
Parameter('pore_formation_0_BaxA_pore_2kf', 1.0)
Parameter('pore_formation_0_BaxA_pore_1kr', 1.0)
Parameter('pore_formation_1_BaxA_pore_2kf', 1.0)
Parameter('pore_formation_1_BaxA_pore_1kr', 1.0)
Parameter('pore_formation_2_BaxA_pore_2kf', 1.0)
Parameter('pore_formation_2_BaxA_pore_1kr', 1.0)
Parameter('transport_0_BaxA_pore_SmacM_cargo_M_SmacC_cargo_C_2kf', 1.0)
Parameter('transport_0_BaxA_pore_SmacM_cargo_M_SmacC_cargo_C_1kr', 1.0)
Parameter('transport_1_BaxA_pore_SmacM_cargo_M_SmacC_cargo_C_1kc', 1.0)
Parameter('transport_0_BaxA_pore_CytoCM_cargo_M_CytoCC_cargo_C_2kf', 1.0)
Parameter('transport_0_BaxA_pore_CytoCM_cargo_M_CytoCC_cargo_C_1kr', 1.0)
Parameter('transport_1_BaxA_pore_CytoCM_cargo_M_CytoCC_cargo_C_1kc', 1.0)
Parameter('catalysis_0_C8A_catalyzer_C3pro_substrate_C3A_product_2kf', 1.0)
Parameter('catalysis_0_C8A_catalyzer_C3pro_substrate_C3A_product_1kr', 1.0)
Parameter('catalysis_1_C8A_catalyzer_C3pro_substrate_C3A_product_1kc', 1.0)
Parameter('catalysis_0_C3A_catalyzer_C6pro_substrate_C6A_product_2kf', 1.0)
Parameter('catalysis_0_C3A_catalyzer_C6pro_substrate_C6A_product_1kr', 1.0)
Parameter('catalysis_1_C3A_catalyzer_C6pro_substrate_C6A_product_1kc', 1.0)
Parameter('catalysis_0_C6A_catalyzer_C8pro_substrate_C8A_product_2kf', 1.0)
Parameter('catalysis_0_C6A_catalyzer_C8pro_substrate_C8A_product_1kr', 1.0)
Parameter('catalysis_1_C6A_catalyzer_C8pro_substrate_C8A_product_1kc', 1.0)
Parameter('Ligand_0', 1000.0)
Parameter('ParpU_0', 1000000.0)
Parameter('C8A_0', 0.0)
Parameter('SmacM_0', 100000.0)
Parameter('BaxM_0', 40000.0)
Parameter('Apop_0', 0.0)
Parameter('Fadd_0', 130000.0)
Parameter('SmacC_0', 0.0)
Parameter('ParpC_0', 0.0)
Parameter('Xiap_0', 122250.0)
Parameter('C9_0', 100000.0)
Parameter('C3ub_0', 0.0)
Parameter('C8pro_0', 130000.0)
Parameter('C6A_0', 0.0)
Parameter('C3pro_0', 21000.0)
Parameter('CytoCM_0', 500000.0)
Parameter('CytoCC_0', 0.0)
Parameter('BaxA_0', 0.0)
Parameter('ApafI_0', 100000.0)
Parameter('BidU_0', 171000.0)
Parameter('BidT_0', 0.0)
Parameter('C3A_0', 0.0)
Parameter('ApafA_0', 0.0)
Parameter('BidM_0', 0.0)
Parameter('Receptor_0', 100.0)
Parameter('C6pro_0', 100.0)

Observable('Ligand_obs', Ligand())
Observable('ParpU_obs', ParpU())
Observable('C8A_obs', C8A())
Observable('SmacM_obs', SmacM())
Observable('BaxM_obs', BaxM())
Observable('Apop_obs', Apop())
Observable('Fadd_obs', Fadd())
Observable('SmacC_obs', SmacC())
Observable('ParpC_obs', ParpC())
Observable('Xiap_obs', Xiap())
Observable('C9_obs', C9())
Observable('C3ub_obs', C3ub())
Observable('C8pro_obs', C8pro())
Observable('C6A_obs', C6A())
Observable('C3pro_obs', C3pro())
Observable('CytoCM_obs', CytoCM())
Observable('CytoCC_obs', CytoCC())
Observable('BaxA_obs', BaxA())
Observable('ApafI_obs', ApafI())
Observable('BidU_obs', BidU())
Observable('BidT_obs', BidT())
Observable('C3A_obs', C3A())
Observable('ApafA_obs', ApafA())
Observable('BidM_obs', BidM())
Observable('Receptor_obs', Receptor())
Observable('C6pro_obs', C6pro())

Rule('bind_0_Ligand_binder_Receptor_binder_target', Ligand(Receptor=None) + Receptor(Ligand=None, Fadd=None) | Ligand(Receptor=1) % Receptor(Ligand=1, Fadd=None), bind_0_Ligand_binder_Receptor_binder_target_2kf, bind_0_Ligand_binder_Receptor_binder_target_1kr)
Rule('bind_0_Receptor_binder_Fadd_binder_target', Receptor(Ligand=ANY, Fadd=None) + Fadd(Receptor=None, C8pro=None) | Receptor(Ligand=ANY, Fadd=1) % Fadd(Receptor=1, C8pro=None), bind_0_Receptor_binder_Fadd_binder_target_2kf, bind_0_Receptor_binder_Fadd_binder_target_1kr)
Rule('substrate_binding_0_Fadd_catalyzer_C8pro_substrate', Fadd(Receptor=ANY, C8pro=None) + C8pro(Fadd=None, C6A=None) | Fadd(Receptor=ANY, C8pro=1) % C8pro(Fadd=1, C6A=None), substrate_binding_0_Fadd_catalyzer_C8pro_substrate_2kf, substrate_binding_0_Fadd_catalyzer_C8pro_substrate_1kr)
Rule('catalytic_step_0_Fadd_catalyzer_C8pro_substrate_C8A_product', Fadd(Receptor=ANY, C8pro=1) % C8pro(Fadd=1, C6A=None) >> Fadd(Receptor=ANY, C8pro=None) + C8A(BidU=None, C3pro=None), catalytic_step_0_Fadd_catalyzer_C8pro_substrate_C8A_product_1kc)
Rule('catalysis_0_C8A_catalyzer_BidU_substrate_BidT_product', C8A(BidU=None, C3pro=None) + BidU(C8A=None) | C8A(BidU=1, C3pro=None) % BidU(C8A=1), catalysis_0_C8A_catalyzer_BidU_substrate_BidT_product_2kf, catalysis_0_C8A_catalyzer_BidU_substrate_BidT_product_1kr)
Rule('catalysis_1_C8A_catalyzer_BidU_substrate_BidT_product', C8A(BidU=1, C3pro=None) % BidU(C8A=1) >> C8A(BidU=None, C3pro=None) + BidT(), catalysis_1_C8A_catalyzer_BidU_substrate_BidT_product_1kc)
Rule('conversion_0_CytoCC_subunit_d_ApafI_subunit_c_ApafA_complex', ApafI() + CytoCC() | ApafA(), conversion_0_CytoCC_subunit_d_ApafI_subunit_c_ApafA_complex_2kf, conversion_0_CytoCC_subunit_d_ApafI_subunit_c_ApafA_complex_1kr)
Rule('inhibition_0_SmacC_inhibitor_Xiap_inh_target', SmacC(Xiap=None) + Xiap(SmacC=None, Apop=None, C3A=None) | SmacC(Xiap=1) % Xiap(SmacC=1, Apop=None, C3A=None), inhibition_0_SmacC_inhibitor_Xiap_inh_target_2kf, inhibition_0_SmacC_inhibitor_Xiap_inh_target_1kr)
Rule('conversion_0_C9_subunit_d_ApafA_subunit_c_Apop_complex', ApafA() + C9() | Apop(C3pro=None, Xiap=None), conversion_0_C9_subunit_d_ApafA_subunit_c_Apop_complex_2kf, conversion_0_C9_subunit_d_ApafA_subunit_c_Apop_complex_1kr)
Rule('catalysis_0_Apop_catalyzer_C3pro_substrate_C3A_product', Apop(C3pro=None, Xiap=None) + C3pro(Apop=None, C8A=None) | Apop(C3pro=1, Xiap=None) % C3pro(Apop=1, C8A=None), catalysis_0_Apop_catalyzer_C3pro_substrate_C3A_product_2kf, catalysis_0_Apop_catalyzer_C3pro_substrate_C3A_product_1kr)
Rule('catalysis_1_Apop_catalyzer_C3pro_substrate_C3A_product', Apop(C3pro=1, Xiap=None) % C3pro(Apop=1, C8A=None) >> Apop(C3pro=None, Xiap=None) + C3A(Xiap=None, ParpU=None, C6pro=None), catalysis_1_Apop_catalyzer_C3pro_substrate_C3A_product_1kc)
Rule('inhibition_0_Xiap_inhibitor_Apop_inh_target', Xiap(SmacC=None, Apop=None, C3A=None) + Apop(C3pro=None, Xiap=None) | Xiap(SmacC=None, Apop=1, C3A=None) % Apop(C3pro=None, Xiap=1), inhibition_0_Xiap_inhibitor_Apop_inh_target_2kf, inhibition_0_Xiap_inhibitor_Apop_inh_target_1kr)
Rule('catalysis_0_Xiap_catalyzer_C3A_substrate_C3ub_product', Xiap(SmacC=None, Apop=None, C3A=None) + C3A(Xiap=None, ParpU=None, C6pro=None) | Xiap(SmacC=None, Apop=None, C3A=1) % C3A(Xiap=1, ParpU=None, C6pro=None), catalysis_0_Xiap_catalyzer_C3A_substrate_C3ub_product_2kf, catalysis_0_Xiap_catalyzer_C3A_substrate_C3ub_product_1kr)
Rule('catalysis_1_Xiap_catalyzer_C3A_substrate_C3ub_product', Xiap(SmacC=None, Apop=None, C3A=1) % C3A(Xiap=1, ParpU=None, C6pro=None) >> Xiap(SmacC=None, Apop=None, C3A=None) + C3ub(), catalysis_1_Xiap_catalyzer_C3A_substrate_C3ub_product_1kc)
Rule('catalysis_0_C3A_catalyzer_ParpU_substrate_ParpC_product', C3A(Xiap=None, ParpU=None, C6pro=None) + ParpU(C3A=None) | C3A(Xiap=None, ParpU=1, C6pro=None) % ParpU(C3A=1), catalysis_0_C3A_catalyzer_ParpU_substrate_ParpC_product_2kf, catalysis_0_C3A_catalyzer_ParpU_substrate_ParpC_product_1kr)
Rule('catalysis_1_C3A_catalyzer_ParpU_substrate_ParpC_product', C3A(Xiap=None, ParpU=1, C6pro=None) % ParpU(C3A=1) >> C3A(Xiap=None, ParpU=None, C6pro=None) + ParpC(), catalysis_1_C3A_catalyzer_ParpU_substrate_ParpC_product_1kc)
Rule('equilibration_0_BidT_equil_a_BidM_equil_b', BidT() | BidM(BaxM=None), equilibration_0_BidT_equil_a_BidM_equil_b_1kf, equilibration_0_BidT_equil_a_BidM_equil_b_1kr)
Rule('catalysis_0_BidM_catalyzer_BaxM_substrate_BaxA_product', BidM(BaxM=None) + BaxM(BidM=None, BaxA=None) | BidM(BaxM=1) % BaxM(BidM=1, BaxA=None), catalysis_0_BidM_catalyzer_BaxM_substrate_BaxA_product_2kf, catalysis_0_BidM_catalyzer_BaxM_substrate_BaxA_product_1kr)
Rule('catalysis_1_BidM_catalyzer_BaxM_substrate_BaxA_product', BidM(BaxM=1) % BaxM(BidM=1, BaxA=None) >> BidM(BaxM=None) + BaxA(BaxM=None, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None), catalysis_1_BidM_catalyzer_BaxM_substrate_BaxA_product_1kc)
Rule('self_catalyze_0_BaxA_self_catalyzer_BaxM_self_substrate', BaxA(BaxM=None, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None) + BaxM(BidM=None, BaxA=None) | BaxA(BaxM=1, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None) % BaxM(BidM=None, BaxA=1), self_catalyze_0_BaxA_self_catalyzer_BaxM_self_substrate_2kf, self_catalyze_0_BaxA_self_catalyzer_BaxM_self_substrate_1kr)
Rule('self_catalyze_1_BaxA_self_catalyzer_BaxM_self_substrate', BaxA(BaxM=1, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None) % BaxM(BidM=None, BaxA=1) >> BaxA(BaxM=None, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None) + BaxA(BaxM=None, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None), self_catalyze_1_BaxA_self_catalyzer_BaxM_self_substrate_1kc)
Rule('pore_formation_0_BaxA_pore', BaxA(BaxM=None, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None) + BaxA(BaxM=None, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None) | BaxA(BaxM=None, BaxA_1=None, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=None, SmacM=None, CytoCM=None), pore_formation_0_BaxA_pore_2kf, pore_formation_0_BaxA_pore_1kr)
Rule('pore_formation_1_BaxA_pore', BaxA(BaxM=None, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None) + BaxA(BaxM=None, BaxA_1=None, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=None, SmacM=None, CytoCM=None) | BaxA(BaxM=None, BaxA_1=3, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None), pore_formation_1_BaxA_pore_2kf, pore_formation_1_BaxA_pore_1kr)
Rule('pore_formation_2_BaxA_pore', BaxA(BaxM=None, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None) + BaxA(BaxM=None, BaxA_1=3, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None) | BaxA(BaxM=None, BaxA_1=4, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=3, BaxA_2=4, SmacM=None, CytoCM=None), pore_formation_2_BaxA_pore_2kf, pore_formation_2_BaxA_pore_1kr)
Rule('transport_0_BaxA_pore_SmacM_cargo_M_SmacC_cargo_C', BaxA(BaxM=None, BaxA_1=4, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=3, BaxA_2=4, SmacM=None, CytoCM=None) + SmacM(BaxA=None) | BaxA(BaxM=None, BaxA_1=4, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=3, BaxA_2=4, SmacM=5, CytoCM=None) % SmacM(BaxA=5), transport_0_BaxA_pore_SmacM_cargo_M_SmacC_cargo_C_2kf, transport_0_BaxA_pore_SmacM_cargo_M_SmacC_cargo_C_1kr)
Rule('transport_1_BaxA_pore_SmacM_cargo_M_SmacC_cargo_C', BaxA(BaxM=None, BaxA_1=4, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=3, BaxA_2=4, SmacM=5, CytoCM=None) % SmacM(BaxA=5) >> BaxA(BaxM=None, BaxA_1=4, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=3, BaxA_2=4, SmacM=None, CytoCM=None) + SmacC(Xiap=None), transport_1_BaxA_pore_SmacM_cargo_M_SmacC_cargo_C_1kc)
Rule('transport_0_BaxA_pore_CytoCM_cargo_M_CytoCC_cargo_C', BaxA(BaxM=None, BaxA_1=4, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=3, BaxA_2=4, SmacM=None, CytoCM=None) + CytoCM(BaxA=None) | BaxA(BaxM=None, BaxA_1=4, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=3, BaxA_2=4, SmacM=None, CytoCM=5) % CytoCM(BaxA=5), transport_0_BaxA_pore_CytoCM_cargo_M_CytoCC_cargo_C_2kf, transport_0_BaxA_pore_CytoCM_cargo_M_CytoCC_cargo_C_1kr)
Rule('transport_1_BaxA_pore_CytoCM_cargo_M_CytoCC_cargo_C', BaxA(BaxM=None, BaxA_1=4, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=3, BaxA_2=4, SmacM=None, CytoCM=5) % CytoCM(BaxA=5) >> BaxA(BaxM=None, BaxA_1=4, BaxA_2=1, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=1, BaxA_2=2, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=2, BaxA_2=3, SmacM=None, CytoCM=None) % BaxA(BaxM=None, BaxA_1=3, BaxA_2=4, SmacM=None, CytoCM=None) + CytoCC(), transport_1_BaxA_pore_CytoCM_cargo_M_CytoCC_cargo_C_1kc)
Rule('catalysis_0_C8A_catalyzer_C3pro_substrate_C3A_product', C8A(BidU=None, C3pro=None) + C3pro(Apop=None, C8A=None) | C8A(BidU=None, C3pro=1) % C3pro(Apop=None, C8A=1), catalysis_0_C8A_catalyzer_C3pro_substrate_C3A_product_2kf, catalysis_0_C8A_catalyzer_C3pro_substrate_C3A_product_1kr)
Rule('catalysis_1_C8A_catalyzer_C3pro_substrate_C3A_product', C8A(BidU=None, C3pro=1) % C3pro(Apop=None, C8A=1) >> C8A(BidU=None, C3pro=None) + C3A(Xiap=None, ParpU=None, C6pro=None), catalysis_1_C8A_catalyzer_C3pro_substrate_C3A_product_1kc)
Rule('catalysis_0_C3A_catalyzer_C6pro_substrate_C6A_product', C3A(Xiap=None, ParpU=None, C6pro=None) + C6pro(C3A=None) | C3A(Xiap=None, ParpU=None, C6pro=1) % C6pro(C3A=1), catalysis_0_C3A_catalyzer_C6pro_substrate_C6A_product_2kf, catalysis_0_C3A_catalyzer_C6pro_substrate_C6A_product_1kr)
Rule('catalysis_1_C3A_catalyzer_C6pro_substrate_C6A_product', C3A(Xiap=None, ParpU=None, C6pro=1) % C6pro(C3A=1) >> C3A(Xiap=None, ParpU=None, C6pro=None) + C6A(C8pro=None), catalysis_1_C3A_catalyzer_C6pro_substrate_C6A_product_1kc)
Rule('catalysis_0_C6A_catalyzer_C8pro_substrate_C8A_product', C6A(C8pro=None) + C8pro(Fadd=None, C6A=None) | C6A(C8pro=1) % C8pro(Fadd=None, C6A=1), catalysis_0_C6A_catalyzer_C8pro_substrate_C8A_product_2kf, catalysis_0_C6A_catalyzer_C8pro_substrate_C8A_product_1kr)
Rule('catalysis_1_C6A_catalyzer_C8pro_substrate_C8A_product', C6A(C8pro=1) % C8pro(Fadd=None, C6A=1) >> C6A(C8pro=None) + C8A(BidU=None, C3pro=None), catalysis_1_C6A_catalyzer_C8pro_substrate_C8A_product_1kc)

Initial(Ligand(Receptor=None), Ligand_0)
Initial(ParpU(C3A=None), ParpU_0)
Initial(C8A(BidU=None, C3pro=None), C8A_0)
Initial(SmacM(BaxA=None), SmacM_0)
Initial(BaxM(BidM=None, BaxA=None), BaxM_0)
Initial(Apop(C3pro=None, Xiap=None), Apop_0)
Initial(Fadd(Receptor=None, C8pro=None), Fadd_0)
Initial(SmacC(Xiap=None), SmacC_0)
Initial(ParpC(), ParpC_0)
Initial(Xiap(SmacC=None, Apop=None, C3A=None), Xiap_0)
Initial(C9(), C9_0)
Initial(C3ub(), C3ub_0)
Initial(C8pro(Fadd=None, C6A=None), C8pro_0)
Initial(C6A(C8pro=None), C6A_0)
Initial(C3pro(Apop=None, C8A=None), C3pro_0)
Initial(CytoCM(BaxA=None), CytoCM_0)
Initial(CytoCC(), CytoCC_0)
Initial(BaxA(BaxM=None, BaxA_1=None, BaxA_2=None, SmacM=None, CytoCM=None), BaxA_0)
Initial(ApafI(), ApafI_0)
Initial(BidU(C8A=None), BidU_0)
Initial(BidT(), BidT_0)
Initial(C3A(Xiap=None, ParpU=None, C6pro=None), C3A_0)
Initial(ApafA(), ApafA_0)
Initial(BidM(BaxM=None), BidM_0)
Initial(Receptor(Ligand=None, Fadd=None), Receptor_0)
Initial(C6pro(C3A=None), C6pro_0)


#!/usr/bin/env python
# -*- coding: utf-8 -*-

def main():
    """Lists as piles
    """

    # Create a stack
    my_stack = [1, 2, 3, 4]
    print("my_stack", my_stack)

    # Push values on the stack
    my_stack.append(5)
    my_stack.append(6)
    my_stack.append(7)
    print("my_stack", my_stack)

    # Pop values from the stack
    print("Poped value", my_stack.pop())
    print("my_stack", my_stack)
    print("Poped value", my_stack.pop())
    print("my_stack", my_stack)
    print("Poped value", my_stack.pop())
    print("my_stack", my_stack)
    print("Poped value", my_stack.pop())
    print("my_stack", my_stack)

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-
"""
    werkzeug.testapp
    ~~~~~~~~~~~~~~~~

    Provide a small test application that can be used to test a WSGI server
    and check it for WSGI compliance.

    :copyright: (c) 2013 by the Werkzeug Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
"""
import os
import sys
import werkzeug
from textwrap import wrap
from werkzeug.wrappers import BaseRequest as Request, BaseResponse as Response
from werkzeug.utils import escape
import base64

logo = Response(base64.b64decode(
'''R0lGODlhoACgAOMIAAEDACwpAEpCAGdgAJaKAM28AOnVAP3rAP/////////
//////////////////////yH5BAEKAAgALAAAAACgAKAAAAT+EMlJq704680R+F0ojmRpnuj0rWnrv
nB8rbRs33gu0bzu/0AObxgsGn3D5HHJbCUFyqZ0ukkSDlAidctNFg7gbI9LZlrBaHGtzAae0eloe25
7w9EDOX2fst/xenyCIn5/gFqDiVVDV4aGeYiKkhSFjnCQY5OTlZaXgZp8nJ2ekaB0SQOjqphrpnOiq
ncEn65UsLGytLVmQ6m4sQazpbtLqL/HwpnER8bHyLrLOc3Oz8PRONPU1crXN9na263dMt/g4SzjMeX
m5yDpLqgG7OzJ4u8lT/P69ej3JPn69kHzN2OIAHkB9RUYSFCFQYQJFTIkCDBiwoXWGnowaLEjRm7+G
p9A7Hhx4rUkAUaSLJlxHMqVMD/aSycSZkyTplCqtGnRAM5NQ1Ly5OmzZc6gO4d6DGAUKA+hSocWYAo
SlM6oUWX2O/o0KdaVU5vuSQLAa0ADwQgMEMB2AIECZhVSnTno6spgbtXmHcBUrQACcc2FrTrWS8wAf
78cMFBgwIBgbN+qvTt3ayikRBk7BoyGAGABAdYyfdzRQGV3l4coxrqQ84GpUBmrdR3xNIDUPAKDBSA
ADIGDhhqTZIWaDcrVX8EsbNzbkvCOxG8bN5w8ly9H8jyTJHC6DFndQydbguh2e/ctZJFXRxMAqqPVA
tQH5E64SPr1f0zz7sQYjAHg0In+JQ11+N2B0XXBeeYZgBZFx4tqBToiTCPv0YBgQv8JqA6BEf6RhXx
w1ENhRBnWV8ctEX4Ul2zc3aVGcQNC2KElyTDYyYUWvShdjDyMOGMuFjqnII45aogPhz/CodUHFwaDx
lTgsaOjNyhGWJQd+lFoAGk8ObghI0kawg+EV5blH3dr+digkYuAGSaQZFHFz2P/cTaLmhF52QeSb45
Jwxd+uSVGHlqOZpOeJpCFZ5J+rkAkFjQ0N1tah7JJSZUFNsrkeJUJMIBi8jyaEKIhKPomnC91Uo+NB
yyaJ5umnnpInIFh4t6ZSpGaAVmizqjpByDegYl8tPE0phCYrhcMWSv+uAqHfgH88ak5UXZmlKLVJhd
dj78s1Fxnzo6yUCrV6rrDOkluG+QzCAUTbCwf9SrmMLzK6p+OPHx7DF+bsfMRq7Ec61Av9i6GLw23r
idnZ+/OO0a99pbIrJkproCQMA17OPG6suq3cca5ruDfXCCDoS7BEdvmJn5otdqscn+uogRHHXs8cbh
EIfYaDY1AkrC0cqwcZpnM6ludx72x0p7Fo/hZAcpJDjax0UdHavMKAbiKltMWCF3xxh9k25N/Viud8
ba78iCvUkt+V6BpwMlErmcgc502x+u1nSxJSJP9Mi52awD1V4yB/QHONsnU3L+A/zR4VL/indx/y64
gqcj+qgTeweM86f0Qy1QVbvmWH1D9h+alqg254QD8HJXHvjQaGOqEqC22M54PcftZVKVSQG9jhkv7C
JyTyDoAJfPdu8v7DRZAxsP/ky9MJ3OL36DJfCFPASC3/aXlfLOOON9vGZZHydGf8LnxYJuuVIbl83y
Az5n/RPz07E+9+zw2A2ahz4HxHo9Kt79HTMx1Q7ma7zAzHgHqYH0SoZWyTuOLMiHwSfZDAQTn0ajk9
YQqodnUYjByQZhZak9Wu4gYQsMyEpIOAOQKze8CmEF45KuAHTvIDOfHJNipwoHMuGHBnJElUoDmAyX
c2Qm/R8Ah/iILCCJOEokGowdhDYc/yoL+vpRGwyVSCWFYZNljkhEirGXsalWcAgOdeAdoXcktF2udb
qbUhjWyMQxYO01o6KYKOr6iK3fE4MaS+DsvBsGOBaMb0Y6IxADaJhFICaOLmiWTlDAnY1KzDG4ambL
cWBA8mUzjJsN2KjSaSXGqMCVXYpYkj33mcIApyhQf6YqgeNAmNvuC0t4CsDbSshZJkCS1eNisKqlyG
cF8G2JeiDX6tO6Mv0SmjCa3MFb0bJaGPMU0X7c8XcpvMaOQmCajwSeY9G0WqbBmKv34DsMIEztU6Y2
KiDlFdt6jnCSqx7Dmt6XnqSKaFFHNO5+FmODxMCWBEaco77lNDGXBM0ECYB/+s7nKFdwSF5hgXumQe
EZ7amRg39RHy3zIjyRCykQh8Zo2iviRKyTDn/zx6EefptJj2Cw+Ep2FSc01U5ry4KLPYsTyWnVGnvb
UpyGlhjBUljyjHhWpf8OFaXwhp9O4T1gU9UeyPPa8A2l0p1kNqPXEVRm1AOs1oAGZU596t6SOR2mcB
Oco1srWtkaVrMUzIErrKri85keKqRQYX9VX0/eAUK1hrSu6HMEX3Qh2sCh0q0D2CtnUqS4hj62sE/z
aDs2Sg7MBS6xnQeooc2R2tC9YrKpEi9pLXfYXp20tDCpSP8rKlrD4axprb9u1Df5hSbz9QU0cRpfgn
kiIzwKucd0wsEHlLpe5yHXuc6FrNelOl7pY2+11kTWx7VpRu97dXA3DO1vbkhcb4zyvERYajQgAADs
='''), mimetype='image/png')

TEMPLATE = u'''\
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<title>WSGI Information</title>

WSGI Information

    This page displays all available information about the WSGI server and
    the underlying Python interpreter.

Python Interpreter

      Python Version
      %(python_version)s

      Platform
      %(platform)s [%(os)s]

      API Version
      %(api_version)s

      Byteorder
      %(byteorder)s

      Werkzeug Version
      %(werkzeug_version)s

WSGI Environment

%(wsgi_env)s

Installed Eggs

    The following python packages were installed on the system as
    Python eggs:

%(python_eggs)s

System Path

    The following paths are the current contents of the load path.  The
    following entries are looked up for Python packages.  Note that not
    all items in this path are folders.  Gray and underlined items are
    entries pointing to invalid resources or used by custom import hooks
    such as the zip importer.

    Items with a bright background were expanded for display from a relative
    path.  If you encounter such paths in the output you might want to check
    your setup as relative paths are usually problematic in multithreaded
    environments.

%(sys_path)s

'''

def iter_sys_path():
    if os.name == 'posix':
        def strip(x):
            prefix = os.path.expanduser('~')
            if x.startswith(prefix):
                x = '~' + x[len(prefix):]
            return x
    else:
        strip = lambda x: x

    cwd = os.path.abspath(os.getcwd())
    for item in sys.path:
        path = os.path.join(cwd, item or os.path.curdir)
        yield strip(os.path.normpath(path)), \
              not os.path.isdir(path), path != item

def render_testapp(req):
    try:
        import pkg_resources
    except ImportError:
        eggs = ()
    else:
        eggs = sorted(pkg_resources.working_set,
                      key=lambda x: x.project_name.lower())
    python_eggs = []
    for egg in eggs:
        try:
            version = egg.version
        except (ValueError, AttributeError):
            version = 'unknown'
        python_eggs.append('
%s [%s]' % (
            escape(egg.project_name),
            escape(version)
        ))

    wsgi_env = []
    sorted_environ = sorted(req.environ.items(),
                            key=lambda x: repr(x[0]).lower())
    for key, value in sorted_environ:
        wsgi_env.append('
%s%s' % (
            escape(str(key)),
            ' '.join(wrap(escape(repr(value))))
        ))

    sys_path = []
    for item, virtual, expanded in iter_sys_path():
        class_ = []
        if virtual:
            class_.append('virtual')
        if expanded:
            class_.append('exp')
        sys_path.append('
%s' % (
            class_ and ' class="%s"' % ' '.join(class_) or '',
            escape(item)
        ))

    return (TEMPLATE % {
        'python_version':   '
'.join(escape(sys.version).splitlines()),
        'platform':         escape(sys.platform),
        'os':               escape(os.name),
        'api_version':      sys.api_version,
        'byteorder':        sys.byteorder,
        'werkzeug_version': werkzeug.__version__,
        'python_eggs':      '\n'.join(python_eggs),
        'wsgi_env':         '\n'.join(wsgi_env),
        'sys_path':         '\n'.join(sys_path)
    }).encode('utf-8')

def test_app(environ, start_response):
    """Simple test application that dumps the environment.  You can use
    it to check if Werkzeug is working properly:

    .. sourcecode:: pycon

        >>> from werkzeug.serving import run_simple
        >>> from werkzeug.testapp import test_app
        >>> run_simple('localhost', 3000, test_app)
         * Running on http://localhost:3000/

    The application displays important information from the WSGI environment,
    the Python interpreter and the installed libraries.
    """
    req = Request(environ, populate_request=False)
    if req.args.get('resource') == 'logo':
        response = logo
    else:
        response = Response(render_testapp(req), mimetype='text/html')
    return response(environ, start_response)

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 5000, test_app, use_reloader=True)


# -*- coding: utf-8 -*-
import pandas as pd

from .ecg_eventrelated import ecg_eventrelated
from .ecg_intervalrelated import ecg_intervalrelated

def ecg_analyze(data, sampling_rate=1000, method="auto"):
    """Performs ECG analysis on either epochs (event-related
    analysis) or on longer periods of data such as resting-state data.

    Parameters
    ----------
    data : dict, DataFrame
        A dictionary of epochs, containing one DataFrame per epoch,
        usually obtained via `epochs_create()`, or a DataFrame
        containing all epochs, usually obtained via `epochs_to_df()`.
        Can also take a DataFrame of processed signals from
        a longer period of data, typically generated by `ecg_process()`
        or `bio_process()`. Can also take a dict containing sets of
        separate periods of data.
    sampling_rate : int
        The sampling frequency of the signal (in Hz, i.e., samples/second).
        Defaults to 1000Hz.
    method : str
        Can be one of 'event-related' for event-related analysis on epochs,
        or 'interval-related' for analysis on longer periods of data. Defaults
        to 'auto' where the right method will be chosen based on the
        mean duration of the data ('event-related' for duration under 10s).

    Returns
    -------
    DataFrame
        A dataframe containing the analyzed ECG features. If
        event-related analysis is conducted, each epoch is indicated
        by the `Label` column. See `ecg_eventrelated()` and
        `ecg_intervalrelated()` docstrings for details.

    See Also
    --------
    bio_process, ecg_process, epochs_create, ecg_eventrelated, ecg_intervalrelated

    Examples
    ----------
    >>> import neurokit2 as nk
    >>>
    >>> # Example 1: Download the data for event-related analysis
    >>> data = nk.data("bio_eventrelated_100hz")
    >>>
    >>> # Process the data for event-related analysis
    >>> df, info = nk.bio_process(ecg=data["ECG"], sampling_rate=100)
    >>> events = nk.events_find(data["Photosensor"],
                                threshold_keep='below',
                                event_conditions=["Negative",
                                                  "Neutral",
                                                  "Neutral",
                                                  "Negative"])
    >>> epochs = nk.epochs_create(df, events,
                                  sampling_rate=100,
                                  epochs_start=-0.1, epochs_end=1.9)
    >>> nk.ecg_analyze(epochs, sampling_rate=100)
    >>>
    >>> # Example 2: Download the resting-state data
    >>> data = nk.data("bio_resting_5min_100hz")
    >>>
    >>> # Process the data
    >>> df, info = nk.ecg_process(data["ECG"], sampling_rate=100)
    >>>
    >>> # Analyze
    >>> nk.ecg_analyze(df, sampling_rate=100)
    """
    method = method.lower()

    # Event-related analysis
    if method in ["event-related", "event", "epoch"]:
        # Sanity checks
        if isinstance(data, dict):
            for i in data:
                colnames = data[i].columns.values
        elif isinstance(data, pd.DataFrame):
            colnames = data.columns.values

        if len([i for i in colnames if "Label" in i]) == 0:
            raise ValueError("NeuroKit error: ecg_analyze(): Wrong input"
                             "or method, we couldn't extract"
                             "extract epochs features.")
        else:
            features = ecg_eventrelated(data)

    # Interval-related analysis
    elif method in ["interval-related", "interval", "resting-state"]:
        features = ecg_intervalrelated(data)

    # Auto
    elif method in ["auto"]:

        if isinstance(data, dict):
            for i in data:
                duration = len(data[i]) / sampling_rate
            if duration >= 10:
                features = ecg_intervalrelated(data)
            else:
                features = ecg_eventrelated(data)

        if isinstance(data, pd.DataFrame):
            if 'Label' in data.columns:
                epoch_len = data['Label'].value_counts()[0]
                duration = epoch_len / sampling_rate
            else:
                duration = len(data) / sampling_rate
            if duration >= 10:
                features = ecg_intervalrelated(data)
            else:
                features = ecg_eventrelated(data)

    return features


# Q6
I = (dt_true['income'] < 0.5)
dt_true.loc[I, ['consumption']] = 0.5
dt_true['consumption'].mean()


# 47. Permutations II

class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        """
        Given a collection of numbers that might contain duplicates, return all possible unique permutations.
        """
        permutations = set()
        self.helper(nums, [], permutations)
        return permutations

    def helper(self, array, currentPermutation, permutations):
        if not len(array) and len(currentPermutation):
            permutations.add(tuple(currentPermutation))
        else:
            for index in range(len(array)):
                newArray = array[: index] + array[index + 1:]
                newPermutation = currentPermutation + [array[index]]
                self.helper(newArray, newPermutation, permutations)