# uncompyle6 version 3.7.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /tmp/pip-install-n_sfyb/Django/django/utils/text.py
# Compiled at: 2019-02-14 00:35:17
from __future__ import unicode_literals
import re, unicodedata
from gzip import GzipFile
from io import BytesIO
from django.utils import six
from django.utils.encoding import force_text
from django.utils.functional import SimpleLazyObject, keep_lazy, keep_lazy_text, lazy
from django.utils.safestring import SafeText, mark_safe
from django.utils.six.moves import html_entities
from django.utils.translation import pgettext, ugettext as _, ugettext_lazy
if six.PY2:
    from django.utils.encoding import force_unicode

@keep_lazy_text
def capfirst(x):
    """Capitalize the first letter of a string."""
    return x and force_text(x)[0].upper() + force_text(x)[1:]

re_words = re.compile(b'<.*?>|((?:\\w[-\\w]*|&.*?;)+)', re.U | re.S)
re_chars = re.compile(b'<.*?>|(.)', re.U | re.S)
re_tag = re.compile(b'<(/)?(\\S+?)(?:(\\s*/)|\\s.*?)?>', re.S)
re_newlines = re.compile(b'\\r\\n|\\r')
re_camel_case = re.compile(b'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))')

@keep_lazy_text
def wrap(text, width):
    """
    A word-wrap function that preserves existing line breaks. Expects that
    existing line breaks are posix newlines.

    All white space is preserved except added line breaks consume the space on
    which they break the line.

    Long words are not wrapped, so the output text may have lines longer than
    ``width``.
    """
    text = force_text(text)

    def _generator():
        for line in text.splitlines(True):
            max_width = min(line.endswith(b'\n') and width + 1 or width, width)
            while len(line) > max_width:
                space = line[:max_width + 1].rfind(b' ') + 1
                if space == 0:
                    space = line.find(b' ') + 1
                    if space == 0:
                        yield line
                        line = b''
                        break
                yield b'%s\n' % line[:space - 1]
                line = line[space:]
                max_width = min(line.endswith(b'\n') and width + 1 or width, width)

            if line:
                yield line

    return (b'').join(_generator())

class Truncator(SimpleLazyObject):
    """
    An object used to truncate text, either by characters or words.
    """

    def __init__(self, text):
        super(Truncator, self).__init__(lambda : force_text(text))

    def add_truncation_text(self, text, truncate=None):
        if truncate is None:
            truncate = pgettext(b'String to return when truncating text', b'%(truncated_text)s...')
        truncate = force_text(truncate)
        if b'%(truncated_text)s' in truncate:
            return truncate % {b'truncated_text': text}
        else:
            if text.endswith(truncate):
                return text
            return b'%s%s' % (text, truncate)

    def chars(self, num, truncate=None, html=False):
        """
        Returns the text truncated to be no longer than the specified number
        of characters.

        Takes an optional argument of what should be used to notify that the
        string has been truncated, defaulting to a translatable string of an
        ellipsis (...).
        """
        self._setup()
        length = int(num)
        text = unicodedata.normalize(b'NFC', self._wrapped)
        truncate_len = length
        for char in self.add_truncation_text(b'', truncate):
            if not unicodedata.combining(char):
                truncate_len -= 1
                if truncate_len == 0:
                    break

        if html:
            return self._truncate_html(length, truncate, text, truncate_len, False)
        return self._text_chars(length, truncate, text, truncate_len)

    def _text_chars(self, length, truncate, text, truncate_len):
        """
        Truncates a string after a certain number of chars.
        """
        s_len = 0
        end_index = None
        for i, char in enumerate(text):
            if unicodedata.combining(char):
                continue
            s_len += 1
            if end_index is None and s_len > truncate_len:
                end_index = i
            if s_len > length:
                return self.add_truncation_text(text[:end_index or 0], truncate)

        return text

    def words(self, num, truncate=None, html=False):
        """
        Truncates a string after a certain number of words. Takes an optional
        argument of what should be used to notify that the string has been
        truncated, defaulting to ellipsis (...).
        """
        self._setup()
        length = int(num)
        if html:
            return self._truncate_html(length, truncate, self._wrapped, length, True)
        return self._text_words(length, truncate)

    def _text_words(self, length, truncate):
        """
        Truncates a string after a certain number of words.

        Newlines in the string will be stripped.
        """
        words = self._wrapped.split()
        if len(words) > length:
            words = words[:length]
            return self.add_truncation_text((b' ').join(words), truncate)
        return (b' ').join(words)

    def _truncate_html(self, length, truncate, text, truncate_len, words):
        """
        Truncates HTML to a certain number of chars (not counting tags and
        comments), or, if words is True, then to a certain number of words.
        Closes opened tags if they were correctly closed in the given HTML.

        Newlines in the HTML are preserved.
        """
        if words and length <= 0:
            return b''
        html4_singlets = ('br', 'col', 'link', 'base', 'img', 'param', 'area', 'hr',
                          'input')
        pos = 0
        end_text_pos = 0
        current_len = 0
        open_tags = []
        regex = re_words if words else re_chars
        while current_len <= length:
            m = regex.search(text, pos)
            if not m:
                break
            pos = m.end(0)
            if m.group(1):
                current_len += 1
                if current_len == truncate_len:
                    end_text_pos = pos
                continue
            tag = re_tag.match(m.group(0))
            if not tag or current_len >= truncate_len:
                continue
            closing_tag, tagname, self_closing = tag.groups()
            tagname = tagname.lower()
            if self_closing or tagname in html4_singlets:
                pass
            elif closing_tag:
                try:
                    i = open_tags.index(tagname)
                except ValueError:
                    pass
                else:
                    open_tags = open_tags[i + 1:]

            else:
                open_tags.insert(0, tagname)

        if current_len <= length:
            return text
        out = text[:end_text_pos]
        truncate_text = self.add_truncation_text(b'', truncate)
        if truncate_text:
            out += truncate_text
        for tag in open_tags:
            out += b'</%s>' % tag

        return out

@keep_lazy_text
def get_valid_filename(s):
    """
    Returns the given string converted to a string that can be used for a clean
    filename. Specifically, leading and trailing spaces are removed; other
    spaces are converted to underscores; and anything that is not a unicode
    alphanumeric, dash, underscore, or dot, is removed.
    >>> get_valid_filename("john's portrait in 2004.jpg")
    'johns_portrait_in_2004.jpg'
    """
    s = force_text(s).strip().replace(b' ', b'_')
    return re.sub(b'(?u)[^-\\w.]', b'', s)

@keep_lazy_text
def get_text_list(list_, last_word=ugettext_lazy(b'or')):
    """
    >>> get_text_list(['a', 'b', 'c', 'd'])
    'a, b, c or d'
    >>> get_text_list(['a', 'b', 'c'], 'and')
    'a, b and c'
    >>> get_text_list(['a', 'b'], 'and')
    'a and b'
    >>> get_text_list(['a'])
    'a'
    >>> get_text_list([])
    ''
    """
    if len(list_) == 0:
        return b''
    if len(list_) == 1:
        return force_text(list_[0])
    return b'%s %s %s' % (
     _(b', ').join(force_text(i) for i in list_[:-1]),
     force_text(last_word), force_text(list_[(-1)]))

@keep_lazy_text
def normalize_newlines(text):
    """Normalizes CRLF and CR newlines to just LF."""
    text = force_text(text)
    return re_newlines.sub(b'\n', text)

@keep_lazy_text
def phone2numeric(phone):
    """Converts a phone number with letters into its numeric equivalent."""
    char2number = {b'a': b'2',
       b'b': b'2', b'c': b'2', b'd': b'3', b'e': b'3', b'f': b'3', b'g': b'4', b'h': b'4',
       b'i': b'4', b'j': b'5', b'k': b'5', b'l': b'5', b'm': b'6', b'n': b'6', b'o': b'6',
       b'p': b'7', b'q': b'7', b'r': b'7', b's': b'7', b't': b'8', b'u': b'8', b'v': b'8',
       b'w': b'9', b'x': b'9', b'y': b'9', b'z': b'9'}
    return (b'').join(char2number.get(c, c) for c in phone.lower())

def compress_string(s):
    zbuf = BytesIO()
    with GzipFile(mode=b'wb', compresslevel=6, fileobj=zbuf, mtime=0) as (zfile):
        zfile.write(s)
    return zbuf.getvalue()

class StreamingBuffer(object):

    def __init__(self):
        self.vals = []

    def write(self, val):
        self.vals.append(val)

    def read(self):
        if not self.vals:
            return b''
        ret = (b'').join(self.vals)
        self.vals = []
        return ret

    def flush(self):
        pass

    def close(self):
        pass

def compress_sequence(sequence):
    buf = StreamingBuffer()
    with GzipFile(mode=b'wb', compresslevel=6, fileobj=buf, mtime=0) as (zfile):
        yield buf.read()
        for item in sequence:
            zfile.write(item)
            data = buf.read()
            if data:
                yield data

    yield buf.read()

smart_split_re = re.compile(b'\n    ((?:\n        [^\\s\'"]*\n        (?:\n            (?:"(?:[^"\\\\]|\\\\.)*" | \'(?:[^\'\\\\]|\\\\.)*\')\n            [^\\s\'"]*\n        )+\n    ) | \\S+)\n', re.VERBOSE)

def smart_split(text):
    r"""
    Generator that splits a string by spaces, leaving quoted phrases together.
    Supports both single and double quotes, and supports escaping quotes with
    backslashes. In the output, strings will keep their initial and trailing
    quote marks and escaped quotes will remain escaped (the results can then
    be further processed with unescape_string_literal()).

    >>> list(smart_split(r'This is "a person\'s" test.'))
    ['This', 'is', '"a person\\\'s"', 'test.']
    >>> list(smart_split(r"Another 'person\'s' test."))
    ['Another', "'person\\'s'", 'test.']
    >>> list(smart_split(r'A "\"funky\" style" test.'))
    ['A', '"\\"funky\\" style"', 'test.']
    """
    text = force_text(text)
    for bit in smart_split_re.finditer(text):
        yield bit.group(0)

def _replace_entity(match):
    text = match.group(1)
    if text[0] == b'#':
        text = text[1:]
        try:
            if text[0] in b'xX':
                c = int(text[1:], 16)
            else:
                c = int(text)
            return six.unichr(c)
        except ValueError:
            return match.group(0)

    else:
        try:
            return six.unichr(html_entities.name2codepoint[text])
        except (ValueError, KeyError):
            return match.group(0)

_entity_re = re.compile(b'&(#?[xX]?(?:[0-9a-fA-F]+|\\w{1,8}));')

@keep_lazy_text
def unescape_entities(text):
    return _entity_re.sub(_replace_entity, force_text(text))

@keep_lazy_text
def unescape_string_literal(s):
    r"""
    Convert quoted string literals to unquoted strings with escaped quotes and
    backslashes unquoted::

        >>> unescape_string_literal('"abc"')
        'abc'
        >>> unescape_string_literal("'abc'")
        'abc'
        >>> unescape_string_literal('"a \"bc\""')
        'a "bc"'
        >>> unescape_string_literal("'\'ab\' c'")
        "'ab' c"
    """
    if s[0] not in b'"\'' or s[(-1)] != s[0]:
        raise ValueError(b'Not a string literal: %r' % s)
    quote = s[0]
    return s[1:-1].replace(b'\\%s' % quote, quote).replace(b'\\\\', b'\\')

@keep_lazy(six.text_type, SafeText)
def slugify(value, allow_unicode=False):
    """
    Convert to ASCII if 'allow_unicode' is False. Convert spaces to hyphens.
    Remove characters that aren't alphanumerics, underscores, or hyphens.
    Convert to lowercase. Also strip leading and trailing whitespace.
    """
    value = force_text(value)
    if allow_unicode:
        value = unicodedata.normalize(b'NFKC', value)
        value = re.sub(b'[^\\w\\s-]', b'', value, flags=re.U).strip().lower()
        return mark_safe(re.sub(b'[-\\s]+', b'-', value, flags=re.U))
    value = unicodedata.normalize(b'NFKD', value).encode(b'ascii', b'ignore').decode(b'ascii')
    value = re.sub(b'[^\\w\\s-]', b'', value).strip().lower()
    return mark_safe(re.sub(b'[-\\s]+', b'-', value))

def camel_case_to_spaces(value):
    """
    Splits CamelCase and converts to lower case. Also strips leading and
    trailing whitespace.
    """
    return re_camel_case.sub(b' \\1', value).strip().lower()

def _format_lazy(format_string, *args, **kwargs):
    """
    Apply str.format() on 'format_string' where format_string, args,
    and/or kwargs might be lazy.
    """
    return format_string.format(*args, **kwargs)

format_lazy = lazy(_format_lazy, six.text_type)


import torch
import numpy as np
from einops import rearrange
import torch.nn.functional as F

from padertorch.base import Module
from padertorch.ops.mappings import ACTIVATION_FN_MAP
from padertorch.modules.normalization import Normalization
from padertorch.ops.sequence.mask import compute_mask
from padertorch.contrib.je.modules.rnn import reverse_sequence
from padertorch.contrib.je.modules.conv import CNN1d, CNNTranspose1d

def scaled_dot_product_attention(q, k, v, seq_len=None, bidirectional=False, mask=None):
    """
    >>> q = torch.zeros((2, 3, 4))
    >>> k = torch.zeros((2, 6, 4))
    >>> v = torch.randn((2, 6, 8))
    >>> x, _ = scaled_dot_product_attention(q, k, v, bidirectional=True)
    >>> x.shape
    torch.Size([2, 3, 8])
    >>> q = torch.zeros((2, 6, 4))
    >>> x, _ = scaled_dot_product_attention(q, k, v, bidirectional=False)
    >>> (x[0,0] == v[0,0]).all()
    tensor(True)
    >>> (torch.abs(x[0,-1] - v[0].mean(0)) < 1e-6).all()
    tensor(True)
    >>> x, _ = scaled_dot_product_attention(q, k, v, seq_len=[6,4], bidirectional=True)
    """
    y = q@k.transpose(-2, -1)/np.sqrt(k.shape[-1])
    if mask is not None:
        y = y + torch.log((mask > 0).float())
    if not bidirectional:
        mask = get_causal_mask(y)
        y = y + torch.log((mask > 0).float())
    elif seq_len is not None:
        mask = compute_mask(y, seq_len, sequence_axis=-1)
        y = y + torch.log((mask > 0).float())
    y = torch.softmax(y, dim=-1)
    return y@v, y

class MultiHeadAttention(Module):
    """
    https://arxiv.org/abs/1706.03762

    >>> q = torch.randn((2, 3, 4))
    >>> k = torch.randn((2, 6, 6))
    >>> v = torch.randn((2, 6, 8))
    >>> attn = MultiHeadAttention(4, 6, 8, 4, 4)
    >>> y, w = attn(q, k, v)
    >>> y.shape
    torch.Size([2, 3, 4])
    >>> attn = MultiHeadAttention(4, 6, 8, 4, 4, num_heads=2)
    >>> y, w = attn(q, k, v)
    >>> y.shape
    torch.Size([2, 3, 4])
    """
    def __init__(
            self, queue_size, key_size, value_size, hidden_size, output_size, num_heads=1, bidirectional=False
    ):
        super().__init__()
        self.queue_size = queue_size
        self.hidden_size = hidden_size
        self.output_size = output_size
        self.num_heads = num_heads
        self.bidirectional = bidirectional
        self.lin_queue = torch.nn.Linear(queue_size, self.hidden_size)
        self.lin_key = torch.nn.Linear(key_size, self.hidden_size)
        self.lin_value = torch.nn.Linear(value_size, self.hidden_size)
        self.out = torch.nn.Linear(self.hidden_size, self.output_size)

    def forward(self, q, k, v, seq_len=None, mask=None):
        B, Tq, _ = q.shape
        B, Tk, _ = k.shape
        q = self.lin_queue(q).view(
            B, Tq, self.num_heads, self.hidden_size//self.num_heads
        ).transpose(1, 2)
        k = self.lin_key(k).view(
            B, Tk, self.num_heads, self.hidden_size//self.num_heads
        ).transpose(1, 2)
        v = self.lin_value(v).view(
            B, Tk, self.num_heads, self.hidden_size//self.num_heads
        ).transpose(1, 2)
        x, attention_weights = scaled_dot_product_attention(
            q, k, v, seq_len=seq_len, bidirectional=self.bidirectional, mask=mask
        )
        x = x.transpose(1, 2).contiguous().view(B, Tq, self.hidden_size)
        return self.out(x), attention_weights

class TransformerBlock(Module):
    """
    https://arxiv.org/abs/1706.03762
    """
    def __init__(
            self, input_size, hidden_size, output_size, num_heads=1,
            bidirectional=False, cross_attention=False,
            norm='layer', norm_kwargs={}, activation='relu', dropout=.0,
    ):
        super().__init__()
        self.activation = ACTIVATION_FN_MAP[activation]()
        self.dropout = dropout
        self.multi_head_self_attention = MultiHeadAttention(
            input_size, input_size, input_size, hidden_size, hidden_size,
            num_heads=num_heads, bidirectional=bidirectional
        )
        self.cross_attention = cross_attention
        self.hidden = torch.nn.Linear(hidden_size, hidden_size)
        self.out = torch.nn.Linear(hidden_size, output_size)

        if norm is None:
            self.self_attention_norm = None
            self.output_norm = None
        else:
            norm_kwargs = {
                "data_format": 'btc',
                "shape": (None, None, hidden_size),
                'eps': 1e-2,
                **norm_kwargs
            }
            if norm == 'batch':
                norm_kwargs['statistics_axis'] = 'bt'
            elif norm == 'layer':
                norm_kwargs['statistics_axis'] = 'c'
            else:
                raise ValueError(f'{norm} normalization not known.')
            norm_kwargs["shape"] = (None, None, hidden_size)
            self.self_attention_norm = Normalization(**norm_kwargs)
            norm_kwargs["shape"] = (None, None, output_size)
            self.output_norm = Normalization(**norm_kwargs)

        if cross_attention:
            self.multi_head_cross_attention = MultiHeadAttention(
                hidden_size*num_heads, hidden_size*num_heads, hidden_size*num_heads,
                hidden_size, hidden_size*num_heads,
                num_heads, bidirectional=True
            )
            if norm is None:
                self.cross_attention_norm = None
            else:
                norm_kwargs["shape"] = (None, None, hidden_size)
                self.cross_attention_norm = Normalization(**norm_kwargs)

    def forward(self, x, seq_len, v=None, seq_len_v=None, state=None):
        x_ = x if state is None else torch.cat([state, x], 1)
        h, _ = self.multi_head_self_attention(x, x_, x_, seq_len=seq_len)
        if self.training and self.dropout > 0.:
            h = F.dropout(h, self.dropout)
        if h.shape == x.shape:
            h = h + x
        if self.self_attention_norm is not None:
            h = self.self_attention_norm(h, sequence_lengths=seq_len)
        if self.cross_attention:
            assert v is not None
            q = h
            h, _ = self.multi_head_cross_attention(q, v, v, seq_len=seq_len_v)
            if self.training and self.dropout > 0.:
                h = F.dropout(h, self.dropout)
            if h.shape == q.shape:
                h = h + q
            if self.cross_attention_norm is not None:
                h = self.cross_attention_norm(h, sequence_lengths=seq_len)
        y = self.out(self.activation(self.hidden(h)))
        if self.training and self.dropout > 0.:
            y = F.dropout(y, self.dropout)
        if h.shape == y.shape:
            y = y + h
        if self.output_norm is not None:
            y = self.output_norm(y, sequence_lengths=seq_len)
        return y, x_

class TransformerStack(Module):
    def __init__(
            self, input_size, hidden_size, output_net=None, num_heads=1,
            num_layers=1, bidirectional=False, reverse=False, cross_attention=False,
            activation='relu', norm='layer', norm_kwargs={},
            positional_encoding=True, dropout=0.,
            return_state=False,
    ):
        """
        https://arxiv.org/abs/1706.03762

        Args:
            input_size:
            hidden_size:
            output_size:
            num_heads:
            bidirectional:
            cross_attention:
            activation:
            norm:
            norm_kwargs:

        Returns:

        >>> x = torch.zeros((2, 3, 8))
        >>> attn = TransformerStack(8, 6, 6, 1, 2, bidirectional=True)
        >>> attn(x, seq_len=[1, 2]).shape
        torch.Size([2, 3, 6])
        >>> attn = TransformerStack(8, 6, 6, 2, 2, bidirectional=True)
        >>> attn(x, seq_len=[1, 2]).shape
        torch.Size([2, 3, 6])
        >>> attn(x, seq_len=None, state=[torch.zeros((2, 6, 8)), torch.zeros((2, 6, 6))]).shape
        torch.Size([2, 3, 6])
        >>> attn = TransformerStack(8, 6, 6, 2, 2, bidirectional=False)
        >>> attn(x, seq_len=None).shape
        torch.Size([2, 3, 6])
        >>> attn(x, seq_len=None, state=[torch.zeros((2, 6, 8)), torch.zeros((2, 6, 6))]).shape
        torch.Size([2, 3, 6])
        """
        super().__init__()
        self.reverse = reverse
        self.positional_encoding = positional_encoding
        self.dropout = dropout
        self.return_state = return_state
        stack = list()
        for i in range(num_layers):
            stack.append(
                TransformerBlock(
                    input_size, hidden_size, hidden_size, num_heads,
                    bidirectional=bidirectional, cross_attention=cross_attention,
                    activation=activation, norm=norm, norm_kwargs=norm_kwargs,
                    dropout=dropout,
                )
            )
            input_size = hidden_size
        self.stack = torch.nn.ModuleList(stack)
        self.output_net = output_net

    def add_positional_encoding(self, x):
        b, t, d = x.shape
        assert d % 2 == 0, x.shape
        positions = torch.arange(t, device=x.device)[:, None]
        dimensions = torch.arange(d//2, device=x.device)
        cos_encodings = torch.cos(positions/(10000**(2*dimensions/d)))
        sin_encodings = torch.sin(positions/(10000**(2*dimensions/d)))
        pos_encodings = torch.stack((cos_encodings, sin_encodings), dim=-1)
        pos_encodings = rearrange(pos_encodings, 't d1 d2 -> t (d1 d2)')
        return x + pos_encodings

    def forward(self, x, seq_len, v=None, seq_len_v=None, state=None):
        x = rearrange(x, 'b f t -> b t f')
        if self.reverse:
            x = reverse_sequence(x, seq_len=seq_len)
        new_state = []
        if self.positional_encoding:
            x = self.add_positional_encoding(x)
        if self.training and self.dropout > 0.:
            x = F.dropout(x, self.dropout)
        for i, layer in enumerate(self.stack):
            x, x_ = layer(
                x, seq_len=seq_len, v=v, seq_len_v=seq_len_v,
                state=None if state is None else state[i],
            )
            new_state.append(x_)
        if self.reverse:
            x = reverse_sequence(x, seq_len=seq_len)
        x = rearrange(x, 'b t f -> b f t')
        if self.output_net is not None:
            x, seq_len = self.output_net(x, seq_len)
        if self.return_state:
            return x, seq_len, new_state
        return x, seq_len

    @classmethod
    def finalize_dogmatic_config(cls, config):
        if config['output_net'] is not None:
            config['output_net']['factory'] = CNN1d
            if config['output_net']['factory'] in [CNN1d, CNNTranspose1d]:
                config['output_net']['in_channels'] = config['hidden_size']
            else:
                raise ValueError(f'output_net factory {config["output_net"]["factory"]} not allowed.')

def get_causal_mask(x):
    return torch.tril(torch.ones_like(x), diagonal=(x.shape[-1] - x.shape[-2]))


from mongoengine.base.datastructures import BaseList
import numpy as np
import mongoengine

class Geom(dict):
    """
    Geometric object defining a population e.g. a threshold or rectangular gate

    Parameters
    -----------
    shape: str
        Shape of the geometric object, must be one of ['ellipse', 'rect', 'threshold', '2d_threshold', 'poly', 'sml',
        'sub']
    x: str
        Name of the x-axis plane
    y: str, optional
        Name of the y-axis plane
    kwargs:
        Any additional keyword arguments
    """
    def __init__(self,
                 shape: str,
                 x: str,
                 y: str or None = None,
                 **kwargs):
        super().__init__()
        err = 'Invalid shape, must be one of: ellipse, rect, threshold, 2d_threshold', 'poly'
        assert shape in ['ellipse', 'rect', 'threshold', '2d_threshold', 'poly', 'sml', 'sub'], err
        self.shape = shape
        self.x = x
        self.y = y
        for k, v in kwargs.items():
            self[k] = v

    def as_dict(self) -> dict:
        """
        Converts object to base class (Python dictionary)

        Returns
        -------
        dict
        """
        self.update({'shape': self.shape, 'x': self.x, 'y': self.y})
        return self

def _validate_input(gate_type: str,
                    **kwargs) -> dict:
    """
    Called on init to validate input for child population definition. If valid, keyword arguments
    returned as dictionary. If invalid an assertion error is raised.

    gate_type: str
        the gate type of the intended gate to generate this child population. Must be one of:
        'threshold', 'threshold_2d', 'cluster', 'geom'.
    kwargs:
        arguments for population definition

    Returns
    --------
    dict
        True if valid else False
    """
    # Check keyword arguments
    err = f'For a {gate_type} gate child population must be defined with keys `definition` and `name`; ' \
          f'{kwargs.keys()} provided'
    if gate_type in ['threshold_1d', 'threshold_2d', 'geom']:
        assert kwargs.keys() == {'definition', 'name'}, err
    if gate_type in ['threshold_1d', 'geom']:
        definition = kwargs.get('definition')
        assert type(definition) == str, f'ChildPopulation definition should be of type str; ' \
                                        f'invalid definition {definition}'
        assert definition in ['-', '+'], f'For a {gate_type} `definition` must be one of [+, -] ' \
                                         f'not {kwargs["definition"]}'

    if gate_type == 'threshold_2d':
        definition = kwargs.get('definition')
        err = 'Invalid definition for threshold_2d, must be a string or list of strings where valid values are' \
              '[++, --, -+, +-]'
        if type(definition) == list or type(definition) == mongoengine.base.datastructures.BaseList:
            assert len(definition) > 0, err
            assert all(x in ['++', '--', '-+', '+-'] for x in definition), err
        else:
            assert definition in ['++', '--', '-+', '+-'], err

    if gate_type == 'cluster':
        assert kwargs.keys() == {'target', 'weight', 'name'}, f'For cluster gating child population must contain ' \
                                                              f'keys [target, weight, name]; {kwargs.keys()} provided'
        assert type(kwargs.get('weight')) in [float, int], 'Weight must be of type int or float'
        target = kwargs.get('target')
        err = f'Invalid target provided for child population, must be a tuple or list of values of type float or in ' \
              f'and of length 2, not {target}'
        assert len(target) == 2, err
        assert all(isinstance(x, int) or isinstance(x, float) for x in target), err
        assert isinstance(kwargs.get('weight'), int), f'Invalid data type provided for weight of child population, ' \
                                                      f'must be of type Integer'
    return kwargs

class ChildPopulation:
    """
    Representation of a single population that is to be stored in a ChildPopulationCollection. Contains the state
    of a population being generated by some gating operation.

    Parameters
    -----------
    gate_type: str
        Type of gate that generates the population
    kwargs:
        Additional keyword arguments for generating population

    """
    def __init__(self,
                 gate_type: str,
                 **kwargs):
        self.gate_type = gate_type
        self.properties = _validate_input(gate_type, **kwargs)
        self.index = np.array([])
        self.geom = None

    def update_index(self,
                     idx: np.array) -> None:
        """
        Update the index values of this population

        Parameters
        -----------
        idx: Numpy.array
            index values corresponding to events data

        Returns
        --------
        None
        """
        self.index = np.array(idx, dtype=np.int)

    def update_geom(self,
                    x: str or None,
                    shape: str or None = None,
                    y: str or None = None,
                    **kwargs):
        """
        Update geom associated to this child population instance

        Parameters
        -----------

        shape: str, optional
            type of shape generated, must be one of ['ellipse', 'rect', 'threshold', '2d_threshold', 'poly', 'sml',
            'sub']
        x: str
            name of x-axis plane
        y: str, optional
            name of y-axis plane
        kwargs:
            Other parameters that describe this geometric object

        Returns
        --------
        None
        """
        self.geom = Geom(shape, x, y, **kwargs)

class ChildPopulationCollection:
    """
    Collection of child populations. This is the standard input handed to the Gate object prior to gating. It defines
    the expected output of the operation.

    Parameters
    -----------
    gate_type: str, optional
        the gate type of the intended gate to generate this child population. Must be one of:
        ['threshold_1d', 'threshold_2d', 'cluster', 'geom', 'sml', 'sub', 'merge', None]
    json_dict: dict
        dictionary to populate ChildPopulationCollection
    """
    def __init__(self,
                 gate_type=None,
                 json_dict=None):
        self.populations = dict()
        if json_dict is not None:
            self.deserialise(json_dict)
        else:
            valid = ['threshold_1d', 'threshold_2d', 'cluster', 'geom', 'sml', 'sub', 'merge', None]
            try:
                assert gate_type in valid
                self.gate_type = gate_type
            except AssertionError:
                print(f'Invalid gate type, must be one of: {valid}')

    def serialise(self) -> dict:
        """
        Using the current properties and the populations, creates a dictionary representation
        of population data

        Returns
        -------
        dict
        """
        serialised = dict(gate_type=self.gate_type, populations=list())
        for pop in self.populations.keys():
            serialised['populations'].append(self.populations[pop].properties)
        return serialised

    def deserialise(self,
                    json_dict: dict) -> None:
        """
        Given some dictionary representation of a ChildPopulationCollection, populate the object
        with properties and populations.

        Parameters
        ----------
        json_dict: dict

        Returns
        -------
        None
        """
        self.gate_type = json_dict['gate_type']
        for pop in json_dict['populations']:
            self.add_population(**pop)

    def add_population(self,
                       name: str,
                       **kwargs) -> None:
        """
        Add a new population to this collection

        Parameters
        -----------
        name: str
            name of the population
        kwargs:
            arguments for population definition. Will differ depending on gate type:
            threshold_1d:
                - definition: one of ['+', '-']. Defines how the population is identified in
                respect to the gate's resulting threshold(s)
            threshold_2d:
                - definition: one or more of ['++', '--', '-+', '-+']. Defines how the population is identified in
                respect to the gate's resulting threshold(s)
            cluster:
                - target: 2d coordinate of expected population medoid
                - weight: integer value for populations ranked priority (used in case of merged populations)
            geom:
                - definition: one of ['+', '-']. Defines how the population is identified in respect
                to the gate's resulting geom
        :return: None
        """
        if name in self.populations.keys():
            print(f'Error: a population with name {name} has already been associated to this '
                  f'ChildPopulationCollection')
            return None
        if self.gate_type == 'threshold_1d' or self.gate_type == 'threshold_2d':
            try:
                current_definitions = list()
                for _, d in self.populations.items():
                    if type(d.properties['definition']) == list:
                        current_definitions = current_definitions + d.properties['definition']
                    else:
                        current_definitions.append(d.properties['definition'])
                if any([kwargs['definition'] == x for x in current_definitions]):
                    print(f"Error: definition {kwargs['definition']} has already been assigned to a population "
                          f"in this collection")
            except KeyError:
                print(f'Invalid input for child population construction for gate type {self.gate_type}')
        self.populations[name] = ChildPopulation(name=name, gate_type=self.gate_type, **kwargs)

    def remove_population(self, name: str) -> None:
        """
        Remove population from collection

        Parameters
        ----------
        name: str
            name of population to remove

        Returns
        --------
        None
        """
        if name not in self.populations.keys():
            print(f'Error: population {name} does not exist')
        self.populations.pop(name)

    def fetch_by_definition(self,
                            definition: str):
        """
        Given a population definition e.g. '+' or ['++', '+-'] return the name of the corresponding population

        Parameters
        ----------
        definition: str
            population definition e.g. '+' or ['++', '+-']

        Returns
        -------
        str
        """
        for name, d in self.populations.items():
            if type(d.properties['definition']) == list or type(d.properties['definition']) == BaseList:
                if definition in d.properties['definition']:
                    return name
            else:
                if definition == d.properties['definition']:
                    return name
        return None


import datetime
import re

from reach.refparse.settings import settings

VALID_YEARS = (1800, datetime.date.today().year + 1)

def split_reference(reference):
    """Split up one individual reference into reference components.
    Each component is numbered by the reference it came from.
    """
    if not reference:
        return []

    # To do: Check whether removing strip is having an impact
    components = [
        elem.strip()
        for elem in re.split('[,?!.]', reference)
        if elem
    ]

    return components

def merge_components(reference_components):
    """With the predicted components of one reference, decide which of
    these should be used for each component i.e. if there are multiple
    authors predicted and they arent next to each other, then decide which
    one to use.
    """
    if not reference_components:
        return []

    # Add a group number for components that are next to components
    #   with same category. For example title next to a title.
    group_index = 1
    for i, comp in enumerate(reference_components[:-1]):
        comp['Group'] = group_index
        next_comp = reference_components[i+1]
        if next_comp['Predicted Category'] != comp['Predicted Category']:
            group_index += 1
    reference_components[-1]['Group'] = group_index

    structured_reference = {}
    categories =  settings.REF_CLASSES
    for category in categories:

        merged_component = ""

        category_components = [
            comp for comp in reference_components
            if comp['Predicted Category']==category
        ]
        if category_components:
            max_prob_component = max(category_components, key=lambda x: x['Prediction Probability'])
            max_prob_group = max_prob_component['Group']

            group_components = [
                comp for comp in category_components
                if comp['Group'] == max_prob_group
            ]
            merged_component = ", ".join([
                comp['Reference component'] for comp in group_components
            ])

        structured_reference.update({category: merged_component})

    return structured_reference

def is_year(component):
    if len(component) == 6:
        component = component[1:5]
    return component.isdecimal() and VALID_YEARS[0] <= int(component) < VALID_YEARS[1]

def predict_components(model, reference_components):
    """
    Predicts the categories for a list of reference components.
    Input:
    - model: The trained multinomial naive Bayes model for predicting the categories of reference components
    - reference_components: A list of reference components
    Output:
    - A list of dicts [{"Predicted Category": , "Prediction Probability": } ...]
    """

    if not reference_components:
        return []

    component_predictions = model.predict(reference_components)
    component_predictions_probs = [
        p.max() for p in model.predict_proba(reference_components)
    ]

    predicted_components = []
    for i, component in enumerate(reference_components):
        if is_year(component):
            cat = 'PubYear'
            prob = 1
        else:
            cat = component_predictions[i]
            prob = component_predictions_probs[i]

        predicted_components.append({
            'Reference component': component,
            'Predicted Category': cat,
            'Prediction Probability': prob
        })

    return predicted_components

def structure_reference(model, reference):
    splitted_components = split_reference(reference)

    predicted_components = predict_components(
        model,
        splitted_components
    )

    structured_reference = merge_components(predicted_components)

    return structured_reference


from dryresources import SCREEN_SIZE

from pygame.display import set_mode as pg_create_screen_sized
from pygame.image import load as pg_load_image
from pygame.locals import RLEACCEL
from pygame import init as initialize_pygame

from os.path import join

class GraphicResources(object):
    def __init__(self):
        initialize_pygame()
        self.screen = pg_create_screen_sized(SCREEN_SIZE)
        self.player_image = self.image("player1.bmp", colorkey=-1)
        self.grass_tile = self.image("grass.bmp")
        self.water_tile = self.image("water.bmp")
    @staticmethod
    def image(filename, colorkey=None):
        path = join("data", filename)
        image = pg_load_image(path).convert()
        if colorkey == -1:
            colorkey = image.get_at((0, 0))
        image.set_colorkey(colorkey, RLEACCEL)
        return image


from django import forms
from products.models import Product

class ProductModelForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = [
            'name',
            'category',
            'short_text',
            'long_text',
            'now_price',
            'old_price',
            'currency',
            'product_marker',
            'image',
            ]


import numpy as np
import scipy.stats as stats
import pylab as pl
import argparse
import matplotlib.pyplot as plt

def populate(filename):
    with open(filename) as txt:
        data = [int(line.split()[1]) for line in txt]
    #print (data)
    s = sorted(data)
    return s

def plot_normal(h):
    x1 = np.amin(h)
    x2 = np.amax(h)
    mu = np.mean(h)
    sigma = np.std(h)
    print(mu, sigma, x1, x2)
    # calculate the z-transform
    z1 = ( x1 - mu ) / sigma
    z2 = ( x2 - mu ) / sigma

    x = np.arange(z1, z2, 1) # range of x in spec
    y = stats.norm.pdf(x,0,1)

    fig, ax = plt.subplots(figsize=(9,6))
    #plt.style.use('fivethirtyeight')
    ax.plot(x,y)
    # fit = stats.norm.pdf(h, Mean, Std)  #this is a fitting indeed
    #pl.hist(h)      #use this to draw histogram of your data
    plt.show()

"""
	This function assumes the input data is of the form
	[0] [1] where [0] indicates index and [1] indicates value.
"""
def __main():
    ag = argparse.ArgumentParser(description="Plotter.")
    ag.add_argument("--t", required=True, help="Require Extracted Trace text log")
    arguments = ag.parse_args()
    trace = arguments.t

    d = []
    d = populate(trace)
    plot_normal(d)

__main()


# -*- coding: utf-8 -*-
"""
Module
"""

import numpy as np
import matplotlib.pyplot as plt
import datetime
import pandas as pd
import seaborn as sns

def HeatMap(df):
    """
    La procédure Heatmap crée... une heatmap. Elle est basée sur la matrice de corrélation.
    Seules les variables numériques doivent être prises en compte.
    INPUT : un dataframe
    RESULT : Dessin d'une heatmap
    """
    NewDF = pd.DataFrame()
    i=1 # L'ID de la colonne dans le nouveau dataframe
    ColList = [] # La liste des colonnes incluses dans le nouveau DF
    for column in df.columns:
        Col = df[column].to_list() # Nous allons analyser la colonne sous forme de liste
        Check = True # Cette variable prend la valeur True par défaut et sera Fausse si la colonne n'est pas du bon type.
        for element in Col:
            if (isinstance(element, int) or isinstance(element,float)) == False:
                Check = False
        if Check == True:
            NewDF[str(i)] = df[column]
            i += 1
            ColList.append(column)
    print("Colonnes conservées : \n",ColList)
    corr = NewDF.corr()
    mask = np.triu(np.ones_like(corr, dtype=bool))
    f, ax = plt.subplots(figsize=(11, 9))
    cmap = sns.diverging_palette(230, 20, as_cmap=True)
    graph = sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,
            square=True, linewidths=.5, cbar_kws={"shrink": .5})

class LROLS():
    """
    La class 'Linear Regression - Ordinary Least Squares' (ou LROLS) nous permet de calculer les
    éléments propres à cette technique d'estimation. Il convient toutefois d'utiliser sklearn ou
    statmodels pour un résultat optimal.
    """

    # Attributs
    def __init__(self,X,Y,Label="OLS"):
        self.X = X
        self.Y = Y # Nous voulons récupérer deux dataframes X et Y
        self.Label = Label

    # Méthodes

    def VarGraph(self):
        """
        La procédure VarGraph va dessiner l'histogramme et le graphique d'une variable dont le nom
        est indiqué dans la variable var. L'objectif est de constater visuellement la constance des
        deux premiers moments et la potentielle présence d'outliers.
        """
        fig = plt.plot(self.Y)
        plt.title("Variable dépendante")
        plt.show()
        i=0
        for col in self.X.columns:
            fig = plt.plot(self.X[col])
            plt.title(self.X.columns[i])
            i+=1
            plt.show()

    def CorrGraph(self):
        """
        La procédure CorrGraph va dessiner des scatter plots pour déctecter une tendance linéaire.
        """
        y = self.Y.to_list()
        Nex = int(len(self.X.columns)) # Nombre de variables explicatives
        if Nex%2 == 0: # Nous allons mettre plusieurs graphiques en même temps. Nous cherchons la
            nrows = int(Nex/2) # configuration optimale pour le plcement des scatter plots.
            ncols = int(2)
            fig,axes = plt.subplots(nrows,ncols)
            fig.tight_layout() # Sert à espacer les graphiques.
            ind=0
            for row in range(0,nrows,1): # Pour chaque ligne ...
                for column in range(0,ncols,1): # ... pour chaque colonne ...
                    axes[row,column].scatter(self.X[self.X.columns[ind]],y,s=0.05) # ... on crée un scatter.
                    axes[row,column].set_title(str(self.X.columns[ind]))
                    ind +=1
            plt.show()
        elif Nex == 2 or Nex == 3:
            fig,axes = plt.subplots(Nex,1)
            fig.tight_layout() # Sert à espacer les graphiques.
            for i in range(0,Nex):
                axes[i].scatter(self.X[self.X.columns[i]],y,s=0.05)
                axes[i].set_title(str(self.X.columns[i]))
            plt.show()
        elif Nex%3 == 0:
            ncols = int(3)
            nrows = int(Nex/3)
            fig,axes = plt.subplots(nrows,ncols)
            fig.tight_layout() # Sert à espacer les graphiques.
            ind=0
            for row in range(0,nrows): # Pour chaque ligne ...
                for column in range(0,ncols): # ... pour chaque colonne ...
                    axes[row,column].scatter(self.X[self.X.columns[ind]],y,s=0.05) # ... on crée un scatter.
                    axes[row,column].set_title(str(self.X.columns[ind]))
                    ind +=1
            plt.show() # On montre le premier graphique, le subplot avec les n-1 variables
        else:
            ncols = int(2)
            nrows = int(Nex/2-0.5) # On édite les n-1 premiers graphiques
            fig,axes = plt.subplots(nrows,ncols)
            fig.tight_layout() # Sert à espacer les graphiques.
            ind=0
            for row in range(0,nrows): # Pour chaque ligne ...
                for column in range(0,ncols): # ... pour chaque colonne ...
                    axes[row,column].scatter(self.X[self.X.columns[ind]],y,s=0.05) # ... on crée un scatter.
                    axes[row,column].set_title(str(self.X.columns[ind]))
                    ind +=1
            plt.show() # On montre le premier graphique, le subplot avec les n-1 variables
            fig = plt.scatter(self.X[-1],y,s=0.05)
            fig.set_title(str(self.X.columns[-1]))

    def GetCoeffs(self):
        """
        La fonction GetCoeffs nous donne les coefficients calculés par les moindre carrés ordinaires.
        """
        # La première étape est de transformer le dataframe en une matrice gérée par Numpy.
        y = np.transpose(self.Y.to_numpy())
        nlines = self.X.shape[0] # Nombre de lignes du DF
        cteline = np.ones((nlines,1)) # Un vecteur de 1 qui materialisera la constante
        semX = self.X.to_numpy()
        X = np.concatenate((cteline,semX),axis=1)
        Inter1 = np.linalg.inv(np.dot(np.transpose(X),X))
        Inter2 = np.dot(np.transpose(X),y)
        Beta = np.dot(Inter1,Inter2)# Beta = (X'X)^{-1}X'Y
        return Beta.tolist()

    def GetResiduals(self):
        """
        La fonction GetResiduals renvoie les rédidus.
        """
        Beta = self.GetCoeffs()
        nlines = self.X.shape[0] # Nombre de lignes du DF
        cteline = np.ones((nlines,1)) # Un vecteur de 1 qui materialisera la constante
        semX = self.X.to_numpy()
        X = np.concatenate((cteline,semX),axis=1)
        Yest = [] # Cette liste contiendra les prédictions pour y
        for row in X: # Pour chaque observation
            Yest.append(np.dot(X,Beta)) # On ajoute XB la prédiction
        y = np.transpose(self.Y.to_numpy())
        res = y - Yest
        res = res.tolist()[0] # On met un index car ça nous renvoie une liste contenant une autre liste.
        return res

    def GetSD(self):
        """
        La fonction GetSD nous renvoie les écarts-types estimés des coefficients.
        """
        nlines = self.X.shape[0] # Nombre de lignes du DF
        cteline = np.ones((nlines,1)) # Un vecteur de 1 qui materialisera la constante
        semX = self.X.to_numpy()
        X = np.concatenate((cteline,semX),axis=1)
        Res = self.GetResiduals() # Nous allons calculer SSR
        SSR = 0
        for element in Res:
            SSR += element**2
        VarEs = SSR/(X.shape[0]-len(self.GetCoeffs())) # Estimation de la variance des aléas
        Mat = np.linalg.inv(np.dot(np.transpose(X),X)) # Mat est la matrice (X'X)^{-1}
        VCov = np.dot(VarEs,Mat) # Estimation de la matrice de variance-covariance des coefficients.
        Liste = []
        for el in range(0,len(self.GetCoeffs())): # Nous nous attendons à avoir une liste de même longueur
            sd = np.sqrt(VCov[el,el]) # que celle des coefficients.
            Liste.append(sd)
        return Liste

    def GetTStats(self):
        """
        La fonction GetTStats nous renvoie les t-statistiques des coefficients.
        """
        Coeffs = self.GetCoeffs()
        Sd = self.GetSD()
        Liste = []
        for el in range(0,len(Sd)):
            T = Coeffs[el]/Sd[el]
            Liste.append(T)
        return Liste

    def PlotResiduals(self):
        """
        La procédure PlotResiduals() trace le graphique des résidus.
        """
        Res = self.GetResiduals()
        fig = plt.plot(Res)
        plt.title("Graphique des résidus, modèle "+str(self.Label))
        plt.show()

    def GetR2(self):
        """
        La fonction GetR2 nous renvoie le coefficient de détermination de la régression et le coefficient
        de détermination ajusté.
        """
        ymean = self.Y.describe()["mean"] # moyenne de la variable dépendante
        ylist = self.Y.to_list()
        SCT = 0
        for i in range(0,len(self.Y)): # Nous réalisons la somme des carrés totaux
            SCT += (ylist[i] - ymean)**2
        res = self.GetResiduals()
        SCR = 0
        for i in range(0,len(res)): # Et la somme du carré des résidus
            SCR += res[i]**2
        R2 = 1-SCR/SCT
        N = self.X.shape[0] # Nombre d'observations
        K = self.X.shape[1] + 1 # Nombre de régresseurs, p+1
        R2adj = 1-(SCR/(N-K))/(SCT/(N-1))
        print(R2adj)
        return (R2,R2adj)

    def WhiteS(self):
        """
        La fonction WhiteReduced permet de faire un test de White simplifié. Le carré des résidus du
        modèle est expliqué par la prédiction et son carré, les coefficients étant estimés par les MCO.
        La statistique de test NR^{2} suit asymptoptiquement un khi-2 à 2 degrés de liberté.

        Le test de White permet d'indiquer si les résidus sont dans une configuration homoscédastique ou
        hétéroscédastique. Dans le second cas, les MCO ne sont pas optimaux et le modèle précedemment
        construit est invalidé.
        """
        nlines = self.X.shape[0] # Nombre de lignes du DF
        cteline = np.ones((nlines,1)) # Un vecteur de 1 qui materialisera la constante
        semX = self.X.to_numpy()
        X = np.concatenate((cteline,semX),axis=1)
        Beta = self.GetCoeffs()
        Liste=[]
        for i in range(0,len(Beta)):
            Liste.append([Beta[i]])
        Beta = np.array(Liste) # Beta est une liste à l'origine, nous le transformons en vecteur
        Ypred = np.dot(X,Beta) # Nous avons les prédictions pour y
        Ypred2 = []
        for i in range(0,len(Ypred)): # Et nous créons leurs carrés
            Ypred2.append(Ypred[i]**2)
        Ypred2 = np.array(Ypred2) # Ypred2 devient un vecteur vertical
        one = np.ones((Ypred.shape[0],1),dtype=int)
        X2 = np.concatenate((one,Ypred),axis=1)
        X2 = np.concatenate((X2,Ypred2),axis=1) # Nous créons notre nouvelle matrice X
        res = self.GetResiduals() # Nous avons les résidus ...
        res2 = [] #... que nous élevons au carré.
        for i in range(0,len(res)):
            el = res[i]**2
            res2.append([el]) # el est dans une liste pour que numpy comprenne qu'il faut créer un vecteur
        res2 = np.array(res2) # vertical
        Beta2 = np.dot(np.linalg.inv(np.dot(np.transpose(X2),X2)),np.dot(np.transpose(X2),
                        res2)) # Estimation MCO des beta de la régression auxiliaire
        SCT = 0
        mean = np.mean(res2) # Nous calculons SCT
        for i in range(0,len(res2)):
            SCT += (res2[i]-mean)**2
        SCT = float(SCT[0]) # SCT a été stocké dans une liste, nous le retirons.
        res2pred = np.dot(X2,Beta2) # Les prédictions du modèle auxiliaire.
        Sresiduals = ((res2 - res2pred)**2).tolist()  # Contient les résidus de la régression auxiliaires.
        SCR = 0 # Calculons SCR
        for i in range(0,len(Sresiduals)):
            SCR += Sresiduals[i][0] # Chaque obs. étant elle-même dans une sous-liste.
        R2 = 1 - (SCR/SCT) # Nous avons désormais de quoi créer la stat de White.
        StatCal = X2.shape[0]*R2
        CriticalValue = 5.99 # Observée à 5% et 2 ddl
        if StatCal >= CriticalValue:
            print("La statistique calculée "+str(round(StatCal,3))+" est supérieure à la valeur critique",
                  str(CriticalValue)+" observée au seuil de 5% et à deux degrés de liberté. Au",
                  "risque de première espèce de 5%, il y a hétéroscédasticité.", "\n")
            return True # Il y a hétéroscédasticité.
        elif StatCal < CriticalValue:
            print("La statistique calculée "+str(round(StatCal,3))+" est inférieure à la valeur critique",
                  str(CriticalValue)+" observée au seuil de 5% et à deux degrés de liberté. Au",
                  "risque de première espèce de 5%, il y a homoscédasticité.", "\n")
            return False # Il n'y en a pas
        else:
            print("Une erreur imprévue est survenue.", "\n")
            return

    def DurbinWatson(self):
        """
        La méthode DurbinWatson réalise le test de Durbin Watson pour vérifier si les résidus de la
        régression suivent un processus AR(1). Attention, ce test présente quelques défauts et doit
        être complété avec plusieurs autres. Les valeurs des statistiques sont pour 3 explicatives.
        """
        Residuals = self.GetResiduals() # On récupère les résidus
        SSR = 0
        for i in range(0,len(Residuals)): # Calcul de SSR
            SSR += Residuals[i]**2
        SSD = 0
        for i in range(1,len(Residuals)): # Calcul du numérateur
            SSD += (Residuals[i] - Residuals[i-1])**2
        DW = SSD/SSR
        dL = 1.73
        dU = 1.80 # Stats de la table de Durbin-Watson
        if DW >= 0 and DW < dL:
            print("DW = "+str(round(DW,3))+", il y a une autocorrélation positive.", "\n")
            return 1
        elif (DW >= dL and DW < dU) or (DW > (4-dU) and DW <= (4-dL)):
            print("DW = "+str(round(DW,3))+", il y a un doute.", "\n")
            return 2
        elif DW >= dU and DW <= (4-dU):
            print("DW = "+str(round(DW,3))+", il n'y a pas d'autocorrélation.", "\n")
            return 3
        elif DW > (4-dL) and DW < 4:
            print("DW = "+str(round(DW,3))+", il y a une autocorrélation positive.", "\n")
            return 4
        else:
            print("DW = "+str(round(DW,3))+", une erreur inattendue est survenue.", "\n")
            return

    def ExportResults(self,filename="RésultatsOLS"):
        """
        La méthode ExportResults exporte les résultats de la régression dans un fichier texte.
        Plusieurs régressions peuvent être exportées.
        """
        try:
            os.mkdir(".//Exports")
        except:
            pass
        coeff = self.GetCoeffs()
        tstats = self.GetTStats()
        colList = self.X.columns.to_list()
        with open(".//Exports//OLS.txt","a+") as dataFile:
            dataFile.write("\n\n=============================================================\n\n")
            dataFile.write(" Rapport de la régression "+self.Label+"  \n")
            dataFile.write(" Date et heure : "+str(datetime.datetime.now())+"\n\n")
            dataFile.write("=============================================================\n\n")
            dataFile.write("Les variables explicatives sont : "+str(colList)+". \n\n")
            dataFile.write("Les coefficients MCO sont : "+str(coeff)+". \n\n")
            dataFile.write("Les t-stat estimés sont : "+str(tstats)+". \n\n")
            dataFile.write("Le R2 estimé est : "+str(round(self.GetR2()[0],3))+". \n\n")
            dataFile.write("Le R2 ajusté estimé est : "+str(round(self.GetR2()[1],3))+". \n\n")
            if self.WhiteS() == True:
                dataFile.write("Attention, de l'hétéroscédasticité a été détectée.\n")
            else:
                dataFile.write("Le test de White simplifié n'a pas décelé d'hétéroscédasticité.\n")
            if self.DurbinWatson() == 1:
                dataFile.write("Attention, les résidus seraient positivement autocorrélés.\n\n")
            elif self.DurbinWatson() == 2:
                dataFile.write("Attention, il se pourrait que les résidus soient autocorrélés.\n\n")
            elif self.DurbinWatson() == 3:
                dataFile.write("Le test de Durbin-Watson n'a détecté aucune autocorrélation des résidus.\n\n")
            elif self.DurbinWatson() == 4:
                dataFile.write("Attention, les résidus seraient négativement autocorrélés.\n\n")
            dataFile.write("--------------------------------------------------------------")
        print("Le fichier a été créé / mis à jour.")


import json
# flask libaries
from flask import Blueprint, request, render_template, flash,\
    session, redirect, url_for
from app.mod_autojira.forms import ticketTemplate, TicketCreator,\
    depCreator, teamEditor
from app.mod_autojira.models import assignedTeam, issue, dependent
from app.mod_autojira.jira import JIRA, JIRA_Create
from app import app, db
from datetime import timedelta, date
# Local libraries
from config import PRIORITY, CATEGORY_CHOICES

mod_autojira = Blueprint('autojira', __name__, url_prefix='/autojira')

# Autojira Home
@mod_autojira.route('/', methods=['GET'])
@mod_autojira.route('/index', methods=['GET'])
def autojira():
    # Set the title of the page
    title = 'Automated Infra-Desk Assitant'
    # gather the request arguments from the url string
    category = request.args.get('category')
    summary = request.args.get('summary')
    # app.logger.debug(session['username'] + ": " + 'summary is ' + str(summary))
    dep = request.args.get('dependent')
    # app.logger.debug(session['username'] + ": " + "dep is " + str(dep))
    disabled = True
    if request.args.get('priority') is not None:
        priority = request.args.get('priority')
    else:
        priority = 3
    summaries = [('', '')]
    dependents = [('', '')]
    try:
        security = [(g.id, g.summary) for g in issue.query.filter_by(category='Security').order_by('summary')]
    except:
        security = ''
        flash('Error loading security tickets.')
        app.logger.error(session['username'] + ": " + 'failed to lookup security summaries.')
    # Start the chain for picking an issue to create
    # Categories will always be populated automatically.
    # Summaries will be populated once a category is chosen
    if category is not None:
        try:
            summaries = [(g.id, g.summary) for g in issue.query.filter_by(category=category).order_by('summary')]
        except:
            app.logger.error(session['username'] + ": " + 'Failed to lookup summaries by category')
    if summary is not None:
        disabled = False
        try:
            dpcat = issue.query.filter_by(id=summary).first()
        except:
            app.logger.error(session['username'] + ": " + 'Failed to lookup the dependent category')
        try:
            dependents = [(g.id, g.name) for g in dependent.query.filter_by(category=dpcat.dependCategory).order_by('category')]
        except:
            app.logger.error(session['username'] + ": " + 'failed to lookup dependents')
    return(render_template('autojira/autojira.html',
                           title=title,
                           categories=CATEGORY_CHOICES,
                           category=category,
                           summaries=summaries,
                           summary=summary,
                           dep=dep,
                           dependents=dependents,
                           priorities=PRIORITY,
                           priority=priority,
                           security=security,
                           disabled=disabled))

# Creating a Ticket
@mod_autojira.route('/autojira/ticket/create', methods=['GET', 'POST'])
def createTicket():
    title = 'Ticket Maker'
    form = TicketCreator()
    jira = ''
    # grabing url variables
    try:
        form.team.choices = [(g.jid, g.team) for g in assignedTeam.query.order_by('team')]#.filter_by(visible=True)]
        app.logger.debug(session['username'] + ": " + 'assigned Team choices from database')
    except:
        app.logger.error(session['username'] + ": " + 'team.choices database failed.')
    try:
        # form.assignee.choices = [(g.jid, g.assigneeName) for g in assignedTeam.query.order_by('assigneeName')]
        form.assignee.choices = [(g.assigneeName, g.assigneeName) for g in assignedTeam.query.order_by('assigneeName').filter(assignedTeam.assigneeName != None).all()]

        app.logger.debug(session['username'] + ": " + 'successfully set choices for assignee')
    except:
        app.logger.error(session['username'] + ": " + 'failed to set choices for assignee')

    if request.method == 'GET':
        if request.args.get('summary') is not None:
            ticketid = request.args.get('summary')
        else:
            ticketid = 16
            app.logger.error(session['username'] + ": " + "ticket was defaulted")
        # get ticket object from database useing ticketid
        ticket = issue.query.filter_by(id=ticketid).first()
        app.logger.debug(session['username'] + ": " + ticket.dteam)
        # set description
        try:
            form.description.data = ticket.description
        except:
            app.logger.error(session['username'] + ": " + 'Loading Description from ticket object.')
            flash('Loading Description from ticket object.', 'error')

        # set AltTicket
        form.altTicket.data = ticket.altTicket
        # set Alt Team
        form.altTeam.data = ticket.altTeam
        # set dteam
        form.team.data = int(ticket.dteam)
        app.logger.debug(session['username'] + ": " + 'value for team is ' + str(ticket.dteam))
        # set assignee based on team
        form.assignee.data = "obuitinfrastructureops"
        # form.team.data = ticket.dteam
        app.logger.debug(session['username'] + ": " + 'value for form.team.data='+str(form.team.data))
        # set summary
        form.summary.data = ticket.summary
        # set priority
        if request.args.get('priority') is not None:
            form.priority.data = int(request.args.get('priority'))
            app.logger.debug(session['username'] + ": " + 'priority set by request args')
        else:
            form.priority.data = int(ticket.dpriority)
            app.logger.info(session['username'] + ": " + 'Priority set by ticket template')
        # Edits based on dependent chosen
        # grab dependent database object
        if request.args.get('dependent') is not None:
            app.logger.debug(session['username'] + ": " + 'requst.args.get(dependent) is not None value='+str(request.args.get('dependent')))
            cdependent = request.args.get('dependent')
            try:
                dep = dependent.query.filter_by(id=cdependent).first()
            except:
                app.logger.error(session['username'] + ": " + 'Dependent database query failed')
            try:
                if dep.DBNAME != "NULL":
                    if "DBNAME" in form.summary.data:
                        form.summary.data = form.summary.data.replace("DBNAME", dep.DBNAME)
                    if "DBNAME" in form.summary.data:
                        form.description.data = form.description.data.replace("DBNAME", dep.DBNAME)
                if dep.SERVERNAME != "NULL":
                    if "SERVERNAME" in form.summary.data:
                        form.summary.data = form.summary.data.replace("SERVERNAME", dep.SERVERNAME)
                    if "SERVERNAME" in form.description.data:
                        form.description.data = form.description.data.replace("SERVERNAME", dep.SERVERNAME)
                if dep.SITENAME != "NULL":
                    if "SITENAME" in form.summary.data:
                        form.summary.data = form.summary.data.replace("SITENAME", dep.SITENAME)
                    if "SITENAME" in form.description.data:
                        form.description.data = form.description.data.replace("SITENAME", dep.SITENAME)
                if dep.PROCESSNAME is not None:
                    if "PROCESSNAME" in form.summary.data:
                        form.summary.data = form.summary.data.replace("PROCESSNAME", dep.PROCESSNAME)
                    if "PROCESSNAME" in form.description.data:
                        form.description.data = form.description.data.replace("PROCESSNAME", dep.PROCESSNAME)
            except:
                app.logger.error(session['username'] + ": " + 'Replacing data for dependent failed.')

    if form.validate_on_submit():
        app.logger.debug(session['username'] + ": " + 'The form has been vailidated')
        app.logger.debug(session['username'] + ": " + 'alteam is ' + form.altTeam.data)
        # Creating Jira cookie file
        try:
            blah = JIRA(session['username'], session['password'], 'ESOC-10000')
            blah = ''
            app.logger.info(session['username'] + ": " + 'Created Jira Cookie')
        except:
            app.logger.error(session['username'] + ": " + 'Error creating jira Cookie')
            return(redirect(url_for('autojira.autojira')))
        # Creating Jira create ticket object
        try:
            jira = JIRA_Create(session['username'], session['password'])
            app.logger.info(session['username'] + ": " + 'Created JIRA_Create object')
        except:
            app.logger.error(session['username'] + ": " + 'Error Creating JIRA_Create Object.')
            flash('Failed to create jira session', 'error')
            return(redirect(url_for('autojira.ticket')))

        # set Summary
        try:
            # statement found https://stackoverflow.com/questions/20078816/replace-non-ascii-characters-with-a-single-space
            # replaces all non-asccii characters with a space, needed because of some of the wierd characters that are in SW ticket.
            jira.set_summary(str(''.join([i if ord(i) < 128 else ' ' for i in form.summary.data])))
        except:
            app.logger.error(session['username'] + ": " + 'failed on summary')
            return(redirect(url_for('autojira.autojira')))

        # set Description
        try:
            jira.set_description(str(''.join([i if ord(i) < 128 else ' ' for i in form.description.data])))
        except:
            app.logger.error(session['username'] + ": " + 'failled on decodeing description')
            return(redirect(url_for('autojira.autojira')))

        # set team.
        try:
            jira.set_team(str(form.team.data))
        except:
            app.logger.error('failed to set team defaulting to infra')
            flash('failed to set team defaulting to infra', 'error')

        # set priority
        try:
            jira.set_priority('P' + str(form.priority.data))
        except:
            app.logger.error(session['username'] + ": " + "failed to set priority")
            flash('failed to set priority defaulting priority P3')

        # set requester
        try:
            jira.set_requester(str(session['username']))
        except:
            app.logger.error(session['username'] + ": " + "failed to set requester")
            flash('failed to set priority defaulting requester')

        # set due date
        try:
            jira.set_due_date(str(date.today() + timedelta(days=3)))
        except:
            flash('failed to set due date to three days from now.', 'error')
            app.logger.error(session['username'] + ": " + 'Error setting due date')

        app.logger.debug('Set JIRA values')

        # set Assignee
        try:
            # app.logger.debug('team is' + str(form.team.data))
            # temp = assignedTeam.query.filter_by(jid=int(form.team.data)).first()
            # app.logger.debug(session['username'] + ": " + 'pulled team name from dteam data.')
            jira.set_assignee(str(form.assignee.data))
        except:
            app.logger.error('Error assigning assignee to ticket')
            flash('Error assigning assignee to ticket, defaulting to infra', 'error')

        # prep for the flash button.
        flashresp = "Ticket Created url is: " + url + "", 'success')
                app.logger.info(session['username'] + 'created ticket: ' + response2['key'])
            except:
                app.logger.error(session['username'] + ": " + 'Failure to create ' + str(form.altTeam.data) + ' Ticket')
                app.logger.error(session['username'] + ": " + str(response2))
                flash('Error Creating ' + str(form.altTeam.data) + 'Ticket', 'error')

        # create the ESOC ticket if you want one.
        if form.altTicket.data != 'only':
            try:
                response1 = json.loads(jira.create_issue())
            except:
                app.logger.error(session['username'] + ": " + 'Error Creating ESOC Ticket.')
                app.logger.error(session['username'] + ": " + str(response1))
                flash('Error Creating ESOC Ticket', 'error')

            try:
                url = "https://obujira.searshc.com/jira/browse/" + response1['key']
                flash(flashresp + url + "'>" + url + "", 'success')
                app.logger.info(session['username'] + "Created " + response1['key'])
            except:
                app.logger.error(session['username'] + ": failed to create flashes or push to email page.")
            try:
                flash("Create Email: " + url_for('ticket_mailer', str(response1['key'])))
            except:
                app.logger.error(session['username'] + ": Failed to build flash for ticket mailer")

            try:
                flash("Create Email: " + " Email!""success")
            except:
                app.logger.error(session['username'] + ": Cannot create email link at all.")

        if form.altTicket.data == 'yes':
            try:
                jira = JIRA(session['username'], session['password'])
                jira.link_tickets(response2['key'], response1['key'])
            except:
                flash('Error Linking Tickets', 'error')
                app.logger.error(session['username'] + ": " + 'Error linking Tickets= ' + response1['key'] + " & " + response2['key'])
        # redirecting after a successful or failed ticket creation.
        jira = ''  # needed to destroy the jira object after it has been used otherwise it f**ks with things.
        return(redirect(url_for('autojira.autojira')))

    # original template render return for GET requests
    return(render_template('autojira/createTicket.html',
                           title=title,
                           form=form))

# Template Functions
@mod_autojira.route('/autojira/ticketTemplate/create', methods=['GET', 'POST'])
def createTemplate():
    app.logger.debug('loading creation page')
    title = 'Custom Template Creator'
    form = ticketTemplate()
    form.dteam.choices = [(g.jid, g.team) for g in assignedTeam.query.order_by('team').all()]
    category = ''
    summary = ''
    summaries = ''
    if request.method == 'GET':
        app.logger.debug(session['username'] + ": " + "get request to creation page")
        if request.args.get('category'):
            try:
                category = request.args.get('category')
                summaries = [(g.id, g.summary) for g in issue.query.filter_by(category=category).order_by('summary')]
            except:
                app.logger.error(session['username'] + ": " + 'not category')
        if request.args.get('category1'):
            try:
                category = request.args.get('category1')
                summaries = [(g.id, g.summary) for g in issue.query.filter_by(category=category).order_by('summary')]
            except:
                app.logger.error(session['username'] + ": " + 'not category1')
        try:
            if request.args.get('summary1'):
                app.logger.debug(session['username'] + ": " + 'found summary1')
                ticket = request.args.get('summary1')
                app.logger.debug(session['username'] + ": " + 'i should redirect')
                return(redirect(url_for('autojira.editTemplate', ticket=ticket)))
        except:
            app.logger.error(session['username'] + ": " + 'failed summary1')

    if form.validate_on_submit():
        ticket = issue(summary=form.summary.data,     # id gets dynamically created.
                       dpriority=form.dpriority.data,
                       hdepend=form.hdepend.data,
                       description=form.description.data,
                       dteam=form.dteam.data,
                       altTicket=form.altTicket.data,
                       altTeam=form.altTeam.data,
                       category=form.category.data,
                       custom=form.custom.data,
                       owner='everyone',
                       creationCount=0,
                       dependCategory=form.dependCategory.data,
                       dependType=form.dependType.data)
        # app.logger.error(session['username'] + ": " + str(ticket.dteam))
        db.session.add(ticket)
        db.session.commit()
        flash('Ticket Template Created', 'success')
        return redirect(url_for('autojira.createTemplate'))
    return(render_template('autojira/createTemplate.html',
                           form=form,
                           title=title,
                           category=category,
                           categories=CATEGORY_CHOICES,
                           summary=summary,
                           summaries=summaries))

@mod_autojira.route('/autojira/ticketTemplate/edit/<int:ticket>', methods=['GET', 'POST'])
def editTemplate(ticket):
    title = 'Template Editor'
    form = ticketTemplate()
    form.dteam.choices = [(g.jid, g.team) for g in assignedTeam.query.order_by('team')]
    if request.method == 'GET':
        try:
            template = issue.query.filter_by(id=ticket).first()
            app.logger.debug(session['username'] + ": " + 'Edit: succeeded in looking up ticket: ' +ticket)
        except:
            app.logger.error(session['username'] + ": " + 'Edit: Failed to retrieve ticket to edit')
        try:
            form.summary.data = template.summary
            form.dpriority.data = template.dpriority
            form.hdepend.data = template.hdepend
            form.description.data = template.description
            form.dteam.data = template.dteam
            form.altTicket.data = template.altTicket
            form.altTeam.data = template.altTeam
            form.category.data = template.category
            form.dependCategory.data = template.dependCategory
            form.dependType.data = template.dependType
        except:
            app.logger.error('Edit: Failed to set values for Edit Ticket Form')

    if form.validate_on_submit():
        app.logger.debug("Edit: Edit form validatied.")
        # Retrieve Ticket Template from the database
        try:
            template = issue.query.filter_by(id=ticket).first()
        except:
            app.logger.error(session['username'] + ": " + 'Edit: failed to look up ticket')

        template.summary = form.summary.data    # id gets dynamically created.
        app.logger.debug(session['username'] + ": " + 'Edit: ticket id value is ' + str(template.summary))
        template.dpriority = form.dpriority.data
        template.hdepend = form.hdepend.data
        template.description = form.description.data
        template.dteam = form.dteam.data
        template.altTicket = form.altTicket.data
        template.altTeam = form.altTeam.data
        template.category = form.category.data
        template.custom = form.custom.data
        template.dependCategory = form.dependCategory.data
        template.dependType = form.dependType.data
        try:
            db.session.commit()
            flash('Successfully edited ticket', 'success')
            app.logger.debug(session['username'] + ": " + 'Edit: Succesfully commited edits to database')
        except:
            db.session.rollback()
            app.logger.error(session['username'] + ": " + 'Edit: Error Merging Ticket Edit Data with Database')
        return(redirect(url_for('autojira.createTemplate')))
    # utlimate return
    return(render_template('autojira/editTemplate.html',
                           form=form,
                           title=title,
                           categories=CATEGORY_CHOICES,
                           ticket=ticket))

@mod_autojira.route("/autojira/ticketTemplate/delete/<int:id>", methods=["GET"])
def deleteTemplate(id):
    template = issue.query.filter_by(id=id).first()
    tmp = template.summary
    try:
        db.session.delete(link)
        db.session.commit()
        app.logger.info(session["username"] + ": Deleted Template named: " + str(tmp))
        flash("Successfully Deleted Template : " + str(tmp), "success")
    except:
        app.logger.error(session["username"] + ": Failed to delete " + str(tmp))
        flash("Failed to delete Template: " + str(tmp), "error")

    return(redirect(url_for('autojira.autojira')))

@mod_autojira.route('/autojira/dependent/create', methods=['GET', 'POST'])
def createDependent():
    form = depCreator()
    title = 'Dependent Creator'
    form.aTeam.choices = [(g.jid, g.team) for g in assignedTeam.query.order_by('team')]

    if form.validate_on_submit():
        create = dependent(category=form.category.data,
                           name=form.name.data,
                           DBNAME=form.dbname.data,
                           SERVERNAME=form.servername.data,
                           SITENAME=form.sitename.data,
                           PROCESSNAME=form.processname.data,
                           aTeam=form.aTeam.data)
        try:
            db.session.add(create)
            db.session.commit()
            flash('depdent Created Succesfully', 'success')
            # app.logger.info(session['username']+ ' created depedent. category= '+ create.category + ' name= ', create.name + 'DBNAME = '+ create.DBNAME + ' SERVERNAME = ' + create.SERVERNAME + ' SITENAME = ' + create.SITENAME+ ' PROCESSNAME = ' + create.PROCESSNAME + ' Team = ' + create.ateam )
        except:
            app.logger.error(session['username'] + ": " + 'adding dependent to the database failed.')
            flash('dependent Creating failed', 'error')
        return(redirect(url_for('autojira.createDependent')))
    # return page on GET request.
    return(render_template('autojira/createDependent.html', form=form, title=title))

@mod_autojira.route('/dependent/edit/<int:depend>')
def editDependent(depend):
    form = depCreator()
    title = 'Dependent Editor'
    try:
        form.aTeam.choices = [(g.jid, g.team) for g in assignedTeam.query.order_by('team')]
    except:
        flash("failed in loading assigned team choices", 'error')
        app.logger.error(session['username'] + ": " + 'Failed in loading assigned team choices.')
    try:
        object = dependent.query.filter_by(id=depend).first()
    except:
        flash("failed in looking up depedent", 'error')
        app.logger.error(session['username'] + ": " + 'Failed to lookup dependent')

    form.category.data = object.category
    form.name.data = object.name
    form.dbname.data = object.DBNAME
    form.servername.data = object.SERVERNAME
    form.sitename.data = object.SITENAME
    form.processname.data = object.PROCESSNAME
    form.aTeam.data = object.aTeam

    if form.validate_on_submit():
        object = dependent.query.filter_by(id=depend).first()
        object.category = form.category.data
        object.name = form.name.data
        object.DBNAME = form.dbname.data
        object.SERVERNAME = form.servername.data
        object.SITENAME = form.sitename.data
        object.PROCESSNAME = form.processname.data
        object.aTeam = form.aTeam.data

        try:
            db.session.commit()
            flash('Depdent Edited Succesfully', 'success')
        except:
            app.logger.error(session['username'] + ": " + 'adding dependent to the database failed.')
            flash('dependent Creating failed', 'error')
        return(redirect(url_for('autojira.dependentCreate')))
    # return page on GET request.
    return(render_template('autojira/createDependent.html', form=form, title=title))

@mod_autojira.route('/team/edit/')
def editTeamLanding():
    title = 'Chose Team to Edit'
    list = [(g.jid, g.team) for g in assignedTeam.query.order_by('team')]
    steam = ''
    jid =''

    return(render_template('autojira/editTeam.html',
                           teams=list,
                           title=title,
                           steam=steam))

@mod_autojira.route('/team/edit/<int:team>', methods=['GET', 'POST'])
def editTeam(team):
    title = 'Team Editor'
    app.logger.debug('Starting Edit Team.')
    form = teamEditor()
    try:
        obj = assignedTeam.query.filter_by(jid=team).first()
        steam = obj.team
        jid = obj.jid
    except:
        app.logger.error('Failed to load team object for editing')

    if request.method == 'GET':
        form.assigneeName.data = obj.assigneeName
        form.email.data = obj.email
        form.visible.data = obj.visible

    if form.validate_on_submit():
        app.logger.debug('sumbitted')
        obj.assigneeName = form.assigneeName.data
        if form.email.data is not None:
            obj.email = form.email.data
        app.logger.debug('got passed assigning changes to object.')
        obj.visible = form.visible.data
        try:
            db.session.commit()
            app.logger.info("Changes made to team: " + steam)
            flash('edits commited', 'success')
        except:
            flash('Failed', 'error')
            app.logger.error("Couldn't Commit team change to db")
        try:
            return(redirect(url_for('autojira.editTeamLanding')))
        except:
            app.logger.error('redirection failed. ')

    return(render_template('autojira/editTeam.html',
                           form=form,
                           title=title,
                           steam=steam,
                           jid=jid))

# @mod_autojira.route('/autojira/ticket/super/create', methods=['GET', 'POST'])
# def super():
#     title = 'Ticket Maker'
#     form = TicketCreator()

#     # grabing url variables
#     title = 'Super-Console'
#     form = TicketCreator()
#     csummary = request.args.get['summary']
#     cpriority = request.args.get['priority']
#     cdescription = request.args.get['description']

#     #Generate Team Choices
#     form.team.choices = [(g.jid, g.team) for g in assignedTeam.query.order_by('team')]
#     #set summary
#     form.summary.data = ticket.summary
#     #set priority
#     if cpriority is not None:
#         try:
#             form.priority.data = int(cpriority)
#         except:
#             form.priority.data = 3
#     else:
#         form.priority.data = 3
#     #set description
#     if cdescription is not None:
#         try:
#             form.description.data = cdescription
#         except:
#             form.description.data = 'Description '
#     #set AltTicket
#     form.altTicket.data = ticket.altTicket
#     #set Alt Team
#     form.altTeam.data = ticket.altTeam
#     #set dteam
#     form.team.data = ticket.dteam

#     if form.validate_on_submit():
#         form=TicketCreator()

#         #Creating Jira cookie file
#         blah = JIRA(session['username'], session['password'],'ESOC-10000')

#         #Creating Jira create ticket object
#         jira = JIRA_Create(session['username'], session['password'])
#         jira.set_project_type(str('ESOC')) #needs to be edited for making multiple types of tickets.
#         jira.set_summary(str(form.summary.data))
#         jira.set_priority('P' + str(form.priority.data))
#         jira.set_requester(str(session['username']))
#         jira.set_due_date(str(date.today() + timedelta(days=3)))
#         jira.set_description(str(form.description.data))

#         try:
#             ateam = assignedTeam.query.filter_by(jid=form.dteam.data).first()
#         except:
#             app.logger.error(session['username'] + ": " + 'failed to lookup assignedTeam jid =' + form.team.data)
#             ateam = 'NULL'

#         if ateam != "NULL":
#             jira.set_assignee(str(ateam))
#         else:
#             jira.set_assignee('obuitinfrastructureops')
#         try:
#             output = jira.create_issue()
#             response = json.loads(output)
#             flashresp = 'Ticket Created url is: https://obujira.searshc.com/jira/browse/' + response['key']
#             flash( flashresp, 'success')
#             jira = '' #nesscary to close out and restart jira object.
#         except:
#             app.logger.error(session['username'] + ": " + 'Error Creating Ticket.')
#         return(redirect(url_for('autojira.super')))

#     return(render_template('autojira/superTicket.html', title='Ticket Maker', form=form))


import io
import os

from googleapiclient.errors import HttpError
from googleapiclient.http import MediaIoBaseDownload, MediaFileUpload
from httplib2 import Http
from oauth2client import file
from apiclient.discovery import build

from DatShiroShop.models import Song
from api.auth import Auth

SCOPES = 'https://www.googleapis.com/auth/drive'
store = file.Storage('credentials.json')
auth = Auth(SCOPES, store)
creds = auth.getCredentials()
shiro_store_folder_id = '1E1_y5_-vW6Qwvh0aXkQ3DK5cYq2ZaVY2'
shiro_store_user_folder_id = '11PJLtUpw2U1u7Sm-acxYYaoi_QbIWhg5'
service = build('drive', 'v3', http=creds.authorize(Http()))

downloads_path = os.path.expanduser(os.sep.join(["~", "Downloads"]))

def list_files(size=10, folder_id=shiro_store_folder_id):
    results = service.files().list(
        pageSize=10, fields="nextPageToken, files(id, name)", q="'{0}' in parents".format(folder_id)).execute()
    items = results.get('files', [])
    if not items:
        print('No files found.')
    # else:
        # print('Files:')
        # for item in items:
        #     print('{0} ({1})'.format(item['name'], item['id']))
    return items

def get_file(fileID):
    results = service.files().get(fileId=fileID).execute()
    return results

def load_files_to_sqlite():
    Song.objects.all().delete()
    results = service.files().list(
        pageSize=10, fields="nextPageToken, files(id, name)", q="'{0}' in parents".format(shiro_store_folder_id)).execute()
    items = results.get('files', [])
    if not items:
        print('No files found.')
    else:
        print('Files:')
        for item in items:
            print('{0} ({1})'.format(item['name'], item['id']))
            id = item['id']
            name = item['name'].rsplit(' - ')[0]
            author, extension = item['name'].rsplit(' - ')[1].rsplit('.', 1)
            song = Song(name=name, id=id, author=author, extension=extension)
            song.save()
            print('Saved to database')

def uploadFile(filename, filepath, mimetype, folder_id=shiro_store_folder_id):
    file_metadata = {'name': filename, 'parents': ['%s' % folder_id]}
    media = MediaFileUpload(filepath,
                            mimetype=mimetype)
    file = service.files().create(body=file_metadata,
                                        media_body=media,
                                        fields='id').execute()
    print("Uploaded file ", file.get('id'))
    return file.get('id')

def downloadFile(file_id, file_name, file_path=downloads_path):
    request = service.files().get_media(fileId=file_id)
    fh = io.BytesIO()
    downloader = MediaIoBaseDownload(fh, request)
    done = False
    full_path = file_path + os.sep + file_name if file_name else file_id
    while done is False:
        status, done = downloader.next_chunk()
        print("Download %d%%." % int(status.progress() * 100))
    with io.open(full_path,'wb') as f:
        fh.seek(0)
        f.write(fh.read())
    print("Download success: " + full_path)
    return full_path

def createFolder(name):
    file_metadata = {
        'name': name,
        'mimeType': 'application/vnd.google-apps.folder',
        'parents': [shiro_store_user_folder_id],
    }
    user_permission = {
        'role': 'reader',
        'type': 'anyone'
    }
    file = service.files().create(body=file_metadata, fields='id').execute()

    def callback(request_id, response, exception):
        if exception:
            # Handle error
            print
            exception
        else:
            print
            "Permission Id: %s" % response.get('id')

    batch = service.new_batch_http_request(callback=callback)
    batch.add(service.permissions().create(
        fileId=file.get('id'),
        body=user_permission,
        fields='id',
    ))
    batch.execute()
    # permission = service.permissions().create(fileId=file.get('id'),body=file_metadata,fields='id').execute()
    print('Folder ID: %s' % file.get('id'))
    return file.get('id')

def searchFile(size,query):
    results = service.files().list(
    pageSize=size, fields="nextPageToken, files(id, name, kind, mimeType)", q=query).execute()
    items = results.get('files', [])
    if not items:
        print('No files found.')
    else:
        print('Files:')
        for item in items:
            print(item)
            print('{0} ({1})'.format(item['name'], item['id']))

def deleteFile(file_id):
    try:
        results = service.files().delete(fileId=file_id).execute()
    except HttpError as e:
        print(e.content)
    print("Removed file ", file_id)