import pkg.no_site_packages

# Prefixes should be ordered alphabetically with most specific first.
DRIVER_ALIAS_PREFIXES = (
    "firewire",
    "pccard",
    "pciexclass",
    "pciclass",
    "pciex",
    "pcie",
    "pci",
    "pnpPNP",
    "usbia",
    "usbif",
    "usbi",
    "usb",
)

# Format a manifest according to the following rules:
#
# 1) File leading comments are left alone
# 2) All other comments stay w/ the first non-comment line that follows
#    them
# 3) Actions appear grouped by type, ignoring macros
# 4) Actions are limited to 80 chars; continuation lines are accepted
#    and emitted
# 5) variant & facet tags appear at the end of actions
# 6) multi-valued tags appear at the end aside from the above
# 7) key attribute tags come first

try:
    import copy
    import errno
    import getopt
    import gettext
    import locale
    import operator
    import os
    import re
    import six
    import sys
    import tempfile
    import traceback
    import warnings
    from difflib import unified_diff
    from functools import cmp_to_key
    from six.moves import cStringIO

    import pkg
    import pkg.actions
    import pkg.misc as misc
    import pkg.portable
    from pkg.misc import emsg, PipeError
    from pkg.actions.generic import quote_attr_value
    from pkg.actions.depend import known_types as dep_types
    from pkg.client.pkgdefs import (EXIT_OK, EXIT_OOPS, EXIT_BADOPT,
        EXIT_PARTIAL)
except KeyboardInterrupt:
    import sys
    sys.exit(EXIT_OOPS)

FMT_V1 = "v1"
FMT_V2 = "v2"

opt_unwrap = False
opt_check = False
opt_diffs = False
opt_format = FMT_V2
orig_opt_format = None

def usage(errmsg="", exitcode=EXIT_BADOPT):
    """Emit a usage message and optionally prefix it with a more specific
    error message.  Causes program to exit."""

    if errmsg:
        error(errmsg)

    # -f is intentionally undocumented.
    print(_("""\
Usage:
        pkgfmt [-cdu] [file1] ... """), file=sys.stderr)

    sys.exit(exitcode)

def error(text, exitcode=EXIT_OOPS):
    """Emit an error message prefixed by the command name """

    # If we get passed something like an Exception, we can convert
    # it down to a string.
    text = str(text)

    # If the message starts with whitespace, assume that it should come
    # *before* the command-name prefix.
    text_nows = text.lstrip()
    ws = text[:len(text) - len(text_nows)]

    # This has to be a constant value as we can't reliably get our actual
    # program name on all platforms.
    emsg(ws + "pkgfmt: error: " + text_nows)

    if exitcode is not None:
        sys.exit(exitcode)

def read_line(f):
    """Generates the lines in the file as tuples containing
    (action, prepended macro, list of prepended comment lines);
    handles continuation lines, transforms, etc."""

    accumulate = ""
    wrap_accumulate = ""
    noncomment_line_seen = False
    comments = []

    for l in f:
        line = l.strip()
        wrap_line = l
        # Preserve line continuations for transforms for V2,
        # but force standard leading space formatting.
        if line.endswith("\\"):
            accumulate += line[:-1]
            wrap_accumulate += re.sub(r"^\s+", "    ",
                wrap_line.rstrip(" \t"))
            continue
        elif accumulate:
            line = accumulate + line
            wrap_line = wrap_accumulate + re.sub(r"^\s+", "    ",
                wrap_line)
            accumulate = ""
            wrap_accumulate = ""

        if not line or line[0] == "#":
            comments.append(line)
            continue

        if not noncomment_line_seen:
            noncomment_line_seen = True
            yield None, "", comments
            comments = []

        if line.startswith("$("):
            cp = line.index(")")
            macro = line[:cp + 1]
            actstr = line[cp + 1:]
        else:
            macro = ""
            actstr = line

        if actstr[0] == "<" and actstr[-1] == ">":
            if opt_format == FMT_V2:
                yield None, wrap_line.rstrip(), comments
            else:
                yield None, macro + actstr, comments

            comments = []
            macro = ""
            continue

        try:
            act = pkg.actions.fromstr(actstr)

            # For formatting purposes, treat dependency actions that
            # do not yet have a valid type as invalid.
            if (act.name == "depend" and
                act.attrs.get("type") not in dep_types):
                raise pkg.actions.InvalidActionError(act,
                    _("Unknown type '{0}' in depend "
                      "action").format(act.attrs.get("type")))
        except (pkg.actions.MalformedActionError,
            pkg.actions.UnknownActionError,
            pkg.actions.InvalidActionError):
            # cannot convert; treat as special macro
            yield None, macro + actstr, comments
        else:
            yield act, macro, comments

        comments = []

    if comments:
        yield None, "", comments

def cmplines(a, b):
    """Compare two line tuples for sorting"""
    # we know that all lines that reach here have actions
    # make set actions first
    # depend actions last
    # rest in alpha order

    def typeord(a):
        if a.name == "set":
            return 1
        if opt_format == FMT_V2:
            if a.name in ("driver", "group", "user"):
                return 3
            if a.name in ("legacy", "license"):
                return 4
        if a.name == "depend":
            return 5
        return 2

    c = misc.cmp(typeord(a[0]), typeord(b[0]))
    if c:
        return c

    if opt_format != FMT_V2:
        c = misc.cmp(a[0].name, b[0].name)
        if c:
            return c

    # Place set pkg.fmri actions first among set actions.
    if a[0].name == "set" and a[0].attrs["name"] == "pkg.fmri":
        return -1
    if b[0].name == "set" and b[0].attrs["name"] == "pkg.fmri":
        return 1

    # Place set actions with names that start with pkg. before any
    # remaining set actions.
    if a[0].name == "set" and a[0].attrs["name"].startswith("pkg.") and \
        not (b[0].name != "set" or b[0].attrs["name"].startswith("pkg.")):
        return -1
    if b[0].name == "set" and b[0].attrs["name"].startswith("pkg.") and \
        not (a[0].name != "set" or a[0].attrs["name"].startswith("pkg.")):
        return 1

    if opt_format == FMT_V2:
        # Place set pkg.summary actions second and pkg.description
        # options third.
        for attr in ("pkg.summary", "pkg.description"):
            if (a[0].name == "set" and
                a[0].attrs["name"] == attr and
                not b[0].attrs["name"] == attr):
                return -1
            if (b[0].name == "set" and
                b[0].attrs["name"] == attr and
                not a[0].attrs["name"] == attr):
                return 1

    # Sort actions based on key attribute (if applicable).
    key_attr = a[0].key_attr
    if key_attr and key_attr == b[0].key_attr:
        a_sk = b_sk = None
        if opt_format == FMT_V2:
            if "path" in a[0].attrs and "path" in b[0].attrs:
                # This ensures filesystem actions are sorted by
                # path and link and hardlink actions are sorted
                # by path and then target (when compared against
                # each other).
                if "target" in a[0].attrs and \
                    "target" in b[0].attrs:
                    a_sk = operator.itemgetter("path",
                        "target")(a[0].attrs)
                    b_sk = operator.itemgetter("path",
                        "target")(b[0].attrs)
                else:
                    a_sk = a[0].attrs["path"]
                    b_sk = b[0].attrs["path"]
            elif a[0].name == "depend" and b[0].name == "depend":
                a_sk = operator.itemgetter("type", "fmri")(
                    a[0].attrs)
                b_sk = operator.itemgetter("type", "fmri")(
                    b[0].attrs)

        # If not using alternate format, or if no sort key has been
        # determined, fallback to sorting on key attribute.
        if not a_sk:
            a_sk = a[0].attrs[key_attr]
        if not b_sk:
            b_sk = b[0].attrs[key_attr]

        c = misc.cmp(a_sk, b_sk)
        # misc.cmp returns NotImplemented for uncomparable types in
        # Python 3. Sort them based on stringified key attribute.
        if c is NotImplemented:
            c = misc.cmp(str(a_sk), str(b_sk))
            if c:
                return c
        elif c:
            return c

    # No key attribute or key attribute sorting provides equal placement, so
    # sort based on stringified action.
    return misc.cmp(str(a[0]), str(b[0]))

def write_line(line, fileobj):
    """Write out a manifest line"""
    # write out any comments w/o changes
    global opt_unwrap

    comments = "\n".join(line[2])
    act = line[0]
    out = line[1] + act.name

    sattrs = act.attrs
    ahash = None
    try:
        ahash = act.hash
        if ahash and ahash != "NOHASH":
            if "=" not in ahash and " " not in ahash and \
                '"' not in ahash:
                out += " " + ahash
            else:
                sattrs = copy.copy(act.attrs)
                sattrs["hash"] = ahash
                ahash = None
    except AttributeError:
        # No hash to stash.
        pass

    # high order bits in sorting
    def kvord(a):
        # Variants should always be last attribute.
        if a[0].startswith("variant."):
            return 7
        # Facets should always be before variants.
        if a[0].startswith("facet."):
            return 6
        # List attributes should be before facets and variants.
        if isinstance(a[1], list):
            return 5

        # note closure hack...
        if opt_format == FMT_V2:
            if act.name == "depend":
                # For depend actions, type should always come
                # first even though it's not the key attribute,
                # and fmri should always come after type.
                if a[0] == "fmri":
                    return 1
                elif a[0] == "type":
                    return 0
            elif act.name == "driver":
                # For driver actions, attributes should be in
                # this order: name, perms, clone_perms, privs,
                # policy, devlink, alias.
                if a[0] == "alias":
                    return 6
                elif a[0] == "devlink":
                    return 5
                elif a[0] == "policy":
                    return 4
                elif a[0] == "privs":
                    return 3
                elif a[0] == "clone_perms":
                    return 2
                elif a[0] == "perms":
                    return 1
            elif act.name != "user":
                # Place target after path, owner before group,
                # and all immediately after the action's key
                # attribute.
                if a[0] == "mode":
                    return 3
                elif a[0] == "group":
                    return 2
                elif a[0] == "owner" or a[0] == "target":
                    return 1

        # Any other attributes should come just before list, facet,
        # and variant attributes.
        if a[0] != act.key_attr:
            return 4

        # No special order for all other cases.
        return 0

    # actual key function
    def key_func(a):
        return (kvord(a), a[0])

    JOIN_TOK = " \\\n    "
    def grow(a, b, rem_values, force_nl=False):
        if opt_unwrap or not force_nl:
            lastnl = a.rfind("\n")
            if lastnl == -1:
                lastnl = 0

            if opt_format == FMT_V2 and rem_values == 1:
                # If outputting the last attribute value, then
                # use full line length.
                max_len = 80
            else:
                # If V1 format, or there are more attributes to
                # output, then account for line-continuation
                # marker.
                max_len = 78

            # Note this length comparison doesn't include the space
            # used to append the second part of the string.
            if opt_unwrap or (len(a) - lastnl + len(b) < max_len):
                return a + " " + b
        return a + JOIN_TOK + b

    def get_alias_key(v):
        """This function parses an alias attribute value into a list
        of numeric values (e.g. hex -> int) and strings that can be
        sensibly compared for sorting."""

        alias = None
        prefix = None
        for pfx in DRIVER_ALIAS_PREFIXES:
            if v.startswith(pfx):
                # Strip known prefixes before attempting
                # to create list of sort values.
                alias = v.replace(pfx, "")
                prefix = pfx
                break

        if alias is None:
            # alias didn't start with known prefix; use
            # raw value for sorting.
            return [v]

        entry = [prefix]
        for part in alias.split(","):
            for comp in part.split("."):
                try:
                    cval = int(comp, 16)
                except ValueError:
                    cval = comp
                entry.append(cval)
        return entry

    def cmp_aliases(a, b):
        if opt_format == FMT_V1:
            # Simple comparison for V1 format.
            return misc.cmp(a, b)
        # For V2 format, order aliases by interpreted value.
        c = misc.cmp(get_alias_key(a), get_alias_key(b))
        # misc.cmp returns NotImplemented for uncomparable types in
        # Python 3. Instead fallback to using the string of the key
        # generated from the alias and sort alphabetically. This
        # maintains the python 2 sorting behaviour.
        if c is NotImplemented:
            c = -misc.cmp(str(get_alias_key(a)), str(get_alias_key(b)))
        return c

    def astr(aout):
        # Number of attribute values for first line and remaining.
        first_line = True
        first_attr_count = 0
        rem_attr_count = 0

        # Total number of remaining attribute values to output.
        total_count = sum(len(act.attrlist(k)) for k in sattrs)
        rem_count = total_count

        # Now build the action output string an attribute at a time.
        for k, v in sorted(six.iteritems(sattrs), key=key_func):
            # Newline breaks are only forced when there is more than
            # one value for an attribute.
            if not (isinstance(v, list) or isinstance(v, set)):
                nv = [v]
                use_force_nl = False
            else:
                nv = v
                use_force_nl = True

            cmp_attrs = None
            if k == "alias":
                cmp_attrs = cmp_to_key(cmp_aliases)
            for lmt in sorted(nv, key=cmp_attrs):
                force_nl = use_force_nl and \
                    (k == "alias" or (opt_format == FMT_V2 and
                    k.startswith("pkg.debug")))

                aout = grow(aout, "=".join((k,
                    quote_attr_value(lmt))), rem_count,
                    force_nl=force_nl)

                # Must be done for each value.
                if first_line and JOIN_TOK in aout:
                    first_line = False
                    first_attr_count = \
                        (total_count - rem_count)
                    if ahash and ahash != "NOHASH":
                        first_attr_count += 1
                    rem_attr_count = rem_count

                rem_count -= 1

        return first_attr_count, rem_attr_count, aout

    first_attr_count, rem_attr_count, output = astr(out)
    if opt_format == FMT_V2 and not opt_unwrap:
        outlines = output.split(JOIN_TOK)

        # If wrapping only resulted in two lines, and the second line
        # only has one attribute and the first line had zero attributes,
        # unwrap the action.
        if first_attr_count < 2 and rem_attr_count == 1 and \
            len(outlines) == 2 and first_attr_count == 0:
            opt_unwrap = True
            output = astr(out)[-1]
            opt_unwrap = False

    if comments:
        print(comments, file=fileobj)

    if opt_format == FMT_V2:
        # Force 'dir' actions to use four spaces at beginning of lines
        # so they line up with other filesystem actions such as file,
        # link, etc.
        output = re.sub("^dir ", "dir  ", output)
    print(output, file=fileobj)

def main_func():
    global opt_unwrap
    global opt_check
    global opt_diffs
    global opt_format
    global orig_opt_format

    # Purposefully undocumented; just like -f.
    env_format = os.environ.get("PKGFMT_OUTPUT")
    if env_format:
        opt_format = orig_opt_format = env_format

    ret = 0
    opt_set = set()

    try:
        opts, pargs = getopt.getopt(sys.argv[1:], "cdf:u?", ["help"])
        for opt, arg in opts:
            opt_set.add(opt)
            if opt == "-c":
                opt_check = True
            elif opt == "-d":
                opt_diffs = True
            elif opt == "-f":
                opt_format = orig_opt_format = arg
            elif opt == "-u":
                opt_unwrap = True
            elif opt in ("--help", "-?"):
                usage(exitcode=EXIT_OK)
    except getopt.GetoptError as e:
        usage(_("illegal global option -- {0}").format(e.opt))
    if len(opt_set - set(["-f"])) > 1:
        usage(_("only one of [cdu] may be specified"))
    if opt_format not in (FMT_V1, FMT_V2):
        usage(_("unsupported format '{0}'").format(opt_format))

    def difference(in_file):
        whole_f1 = in_file.readlines()
        f2 = cStringIO()
        fmt_file(cStringIO("".join(whole_f1)), f2)
        f2.seek(0)
        whole_f2 = f2.readlines()

        if whole_f1 == whole_f2:
            if opt_diffs:
                return 0, ""
            return 0, "".join(whole_f2)
        elif opt_diffs:
            return 1, "".join(unified_diff(whole_f2,
                whole_f1))
        return 1, "".join(whole_f2)

    flist = pargs
    if not flist:
        try:
            in_file = cStringIO()
            in_file.write(sys.stdin.read())
            in_file.seek(0)

            ret, formatted = difference(in_file)
            if ret == 1 and opt_check:
                # Manifest was different; if user didn't specify
                # a format explicitly, try V1 format.
                if not orig_opt_format:
                    opt_format = FMT_V1
                    in_file.seek(0)
                    rcode, formatted = difference(in_file)
                    opt_format = FMT_V2
                    if rcode == 0:
                        # Manifest is in V1 format.
                        return 0

                error(_("manifest is not in pkgfmt form"))
            elif ret == 1 and not opt_diffs:
                # Treat as successful exit if not checking
                # formatting or displaying diffs.
                ret = 0

            # Display formatted version (explicit 'end' needed to
            # prevent output of extra newline) even if manifest
            # didn't need formatting for the stdin case.  (The
            # assumption is that it might be used in a pipeline.)
            if formatted:
                print(formatted, end="")
        except EnvironmentError as e:
            if e.errno == errno.EPIPE:
                # User closed input or output (i.e. killed piped
                # program before all input was read or output
                # was written).
                return 1
        return ret

    ret = 0
    tname = None
    for fname in flist:
        try:
            # force path to be absolute; gives better diagnostics if
            # something goes wrong.
            path = os.path.abspath(fname)

            with open(fname, "r") as f:
                rcode, formatted = difference(f)
            if rcode == 0:
                continue

            if opt_check:
                # Manifest was different; if user didn't specify
                # a format explicitly, try V1 format.
                if not orig_opt_format:
                    opt_format = FMT_V1
                    with open(fname, "r") as f:
                        rcode, formatted = difference(f)
                    opt_format = FMT_V2
                    if rcode == 0:
                        # Manifest is in V1 format.
                        continue

                ret = 1
                error(_("{0} is not in pkgfmt form; run pkgfmt "
                    "on file without -c or -d to reformat "
                    "manifest in place").format(fname), exitcode=None)
                continue
            elif opt_diffs:
                # Display differences (explicit 'end' needed to
                # prevent output of extra newline).
                ret = 1
                print(formatted, end=" ")
                continue
            elif ret != 1:
                # Treat as successful exit if not checking
                # formatting or displaying diffs.
                ret = 0

            # Replace manifest with formatted version.
            pathdir = os.path.dirname(path)
            tfd, tname = tempfile.mkstemp(dir=pathdir)
            with os.fdopen(tfd, "w") as t:
                t.write(formatted)

            try:
                # Ensure existing mode is preserved.
                mode = os.stat(fname).st_mode
                os.chmod(tname, mode)
                os.rename(tname, fname)
            except EnvironmentError as e:
                error(str(e), exitcode=EXIT_OOPS)
        except (EnvironmentError, IOError) as e:
            error(str(e), exitcode=EXIT_OOPS)
        finally:
            if tname:
                try:
                    pkg.portable.remove(tname)
                except EnvironmentError as e:
                    if e.errno != errno.ENOENT:
                        raise

    return ret

def fmt_file(in_file, out_file):
    lines = []
    saw_action = False
    trailing_comments = []

    for tp in read_line(in_file):
        if tp[0] is None:
            if saw_action and not tp[1]:
                # Comments without a macro or transform
                # nearby will be placed at the end if
                # found after actions.
                trailing_comments.extend(tp[2])
                continue

            # Any other comments, transforms, or unparseables
            # will simply be printed back out wherever they
            # were found before or after actions.
            for l in tp[2]:
                print(l, file=out_file)
            if tp[1]:
                print(tp[1], file=out_file)
        else:
            lines.append(tp)
            saw_action = True

    lines.sort(key=cmp_to_key(cmplines))
    for l in lines:
        write_line(l, out_file)
    out_file.writelines("\n".join(trailing_comments))
    if trailing_comments:
        # Ensure file ends with newline.
        out_file.write("\n")

if __name__ == "__main__":
    misc.setlocale(locale.LC_ALL, "", error)
    gettext.install("pkg", "/usr/share/locale")
    misc.set_fd_limits(printer=error)

    if six.PY3:
        # disable ResourceWarning: unclosed file
        warnings.filterwarnings("ignore", category=ResourceWarning)
    try:
        __ret = main_func()
    except (PipeError, KeyboardInterrupt):
        # We don't want to display any messages here to prevent
        # possible further broken pipe (EPIPE) errors.
        __ret = 1
    except SystemExit as _e:
        raise _e
    except:
        traceback.print_exc()
        error(misc.get_traceback_message(), exitcode=None)
        __ret = 99

    sys.exit(__ret)


from Mydoit import read, write
import os
import shutil
from datetime import datetime

MY_TMP_DIR = 'tmp'

def test_write_file():
    path, test_string = single_test_file_setup()
    assert write(path, test_string) == None
    assert read_file_content(path) == test_string
    single_test_file_teardown()

def test_read_file():
    path, test_string = single_test_file_setup()
    write_file_content(path, test_string)
    assert isinstance(read(path).text(), str)
    single_test_file_teardown()

def test_read_http():
    url = 'https://httpbin.org/get'
    text = read(url).text()
    assert isinstance(text, str)
    assert 'args' in text

def test_read_http_show():
    url = 'https://httpbin.org/get'
    text = read(url).show()

def test_write_http():
    url = 'https://httpbin.org/post'
    data = {"foo":"bar"}
    message = write(url, data)
    text = message.text()
    assert isinstance(text, str)
    assert 'args' in text
    assert message.body.request.method == 'POST'

def test_write_http_put():
    url = 'https://httpbin.org/put'
    data = {"foo":"bar"}
    message = write(url, data, options={"httpMethod":"PUT"})
    text = message.text()
    assert isinstance(text, str)
    assert 'args' in text
    assert message.body.request.method == 'PUT'

def write_file_content(path, content):
    f = open(path, "w+")
    f.write(content)
    f.close()

def read_file_content(path):
    f = open(path, 'r')
    content = f.read()
    f.close()
    return content

def single_test_file_setup():
    os.makedirs(MY_TMP_DIR, exist_ok=True)
    path = os.path.join(MY_TMP_DIR, 'single_file_test_data.txt')
    test_string = str(datetime.now())
    return path, test_string

def single_test_file_teardown():
    shutil.rmtree(MY_TMP_DIR)


from django import forms
from django.utils.translation import gettext_lazy as _

# the min and max quantity user could buy
PRODUCT_QUANTITY_CHOICES = [(i, str(i)) for i in range(1, 21)]

class CartAddProductForm(forms.Form):
    quantity = forms.TypedChoiceField(choices=PRODUCT_QUANTITY_CHOICES,
                                      coerce=int,  # convert input to integer
                                      label=_('Quantity'))

    # override indicates whether the quantity should update or not
    override = forms.BooleanField(required=False,
                                  initial=False,
                                  widget=forms.HiddenInput)  # we do not like to show it to the user


from django.contrib import admin
from .models import ContactUs, NewsLetter

# Register your models here.
class ContactAdmin(admin.ModelAdmin):

    list_display = (
        'submitted_on',
        'name',
        'email',
        'message',
    )
    list_filter = (
        'name',
        'email',
    )
    search_fields = (
        'submitted_on',
        'name',
        'email',
    )

    ordering = ('-submitted_on',)

class NewsLetterAdmin(admin.ModelAdmin):
    list_display = (
        'email',
        'signed_up_on',
    )
    list_filter = (
        'email',
        'signed_up_on',
    )
    search_fields = (
        'email',
        'signed_up_on',
    )

admin.site.register(ContactUs, ContactAdmin)
admin.site.register(NewsLetter, NewsLetterAdmin)


__author__ = 'kirry'
import datetime,time
from interfaceTest import app
from interfaceTest.Methods.BeopTools import BeopTools
import unittest

class Calc042(unittest.TestCase):
    testCaseID = 'Calc042'
    projectName = ""
    buzName = '测试每个项目的原始数据的历史数据是否掉线'
    now = 'None'
    errors = []
    url = "http://%s/get_history_data_padded" % app.config['SERVERIP']
    params = [
        #{'projectId':396,"point":["Accum_watermeter_lifeuse","instant_watermeter_lifeuse"]},
        {'projectId':421,"point":["CE_Ch002_ChLeaveCondTemp","CE_CTFan009_CTFanSpeed"]},
        {'projectId':395,"point":["B1F_HeatPump01_CHW_ReturnT","B1F_HeatPump01_Heating_TSet"]},
        {'projectId':190,"point":["!DDC-BUB-L00-02:Address","!DDC-HA-L01M-01A:BATT"]},
        {'projectId':316,"point":["10F_AHU001_RADamperPositionSet","10F_VAV001_VAVBoxAirFlow"]},
        {'projectId':374,"point":["Gas_900_02_accumulatedflow","Gas_901_02_instantaneousflow"]},
        {'projectId':128,"point":["AHU0C101_RAH","AHU0C104_RoomRH_02"]},
        {'projectId':218,"point":["AirCooler001_RoomT","ScrewRack001_RefDeviationValueSet"]},
        {'projectId':18,"point":["11F_AHU1.VOLUME_F","11F_AHU2_CO2"]},
        {'projectId':373,"point":["AverageLoad1","AverageLoadInt1"]},
        {'projectId':15,"point":["6F_LSJZ_2_VlvOn_CV","6F_LSJZ_4_VlvOnFK_CV"]},
        {'projectId':316,"point":["10F_AHU001_CCReturnT","10F_AHU001_SATSet"]},
        {'projectId':376,"point":["Aqu_SecCHW_ReturnT29","Aqu_SecHWP01_ElecUse"]},
        {'projectId':318,"point":["1089","1088"]},
        {'projectId':126,"point":["1F_AHU20101_CCValvePosition","1F_AHU20101_SAFanVSDFreq"]},
        {'projectId':284,"point":["DDC_11F_nvoIO1_ui3","DDC_16_nvoIO1_ui3"]},
        {'projectId':19,"point":["2#RoomRH01","4#RoomRH01"]},
        {'projectId':194,"point":["ChAmpLmtSetPointFeedback01","ChChWTempSupplyActiveSetPoint06R"]},
        {'projectId':364,"point":["10FL_EAFan001_CO","10FL_EAFan002_CO"]},
        {'projectId':179,"point":["10FL_EAFan002_CO","11FL_EAFan002_CO"]},
        {'projectId':90,"point":["AHU00101_CCValvePosition","AHU00101_RARH"]},
        {'projectId':120,"point":["1000025","1000051"]},
        {'projectId':72,"point":["A11AHU_A_11_VlvColdReg","A11AHU_A_21_VlvColdReg"]},
    ]

    def setUp(self):
        self.start = datetime.datetime.now()
        self.startime = self.start-datetime.timedelta(minutes = 20)
    def Test(self):
        endtime = datetime.datetime.strftime(self.start,"%Y-%m-%d %H:%M")
        if int((endtime[-1:]))>=5:
            endtime =endtime[:-1]+"5:00"
        else:
            endtime =endtime[:-1]+"0:00"
        start = datetime.datetime.strftime(self.startime,"%Y-%m-%d %H:%M")
        if int((start[-1:]))>=5:
            start =start[:-1]+"5:00"
        else:
            start =start[:-1]+"0:00"
        for param in self.params:
            projectId = param["projectId"]
            point = param["point"]
            data = {"projectId":projectId,"pointList":point,
                    "timeStart":start,"timeEnd":endtime,
                    "timeFormat":"m5","prop":{}}
            self.checkpoint(self.url,data,time=15,projectId=projectId,point=point)
    def checkpoint(self,url,data,time,projectId,point):
        rv = False
        try:
            rv = BeopTools.postJsonToken(url,data,t=time)
        except Exception as e:
            print(e.__str__())
            self.errors.append("请求接口%s超时，超时时间为15s"%url)
        if isinstance(rv,list) and rv:
            for index,r in enumerate(rv):
                r = r.get("history",False)
                if r:
                    if r.__len__() >0:
                        print("原始数据的历史数据更新中！")
                    else:
                        self.errors.append("项目%s原始点%s的历史数据掉线！"%(projectId,point[index]))
        BeopTools.raiseError(self.errors,self.testCaseID)
    def tearDown(self):
        self.offline = False
        use1 = str((datetime.datetime.now() - self.start).seconds)
        use = use1 + "s"
        print("本次用例执行时间为%s" % use)
        self.now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

if __name__ == '__main__':
    suite = unittest.TestSuite()
    suite.addTest(Calc042('Test'))
    runner = unittest.TextTestRunner()
    result = runner.run(suite)


import requests

def getID(problem):
    if(problem.get("contestId") == None):
        return None
    return f"{problem['contestId']}{problem['index']}"

def count_ac(problemset, users):
    userlist = open(users, "r")
    count = dict()

    accepted_problems = []
    for user in userlist.readlines():
        handle = user.strip()
        # print(handle)
        response = requests.get(f"https://codeforces.com/api/user.status?handle={handle}")
        submitions = response.json()["result"]
        ac_problems = []
        for s in submitions:
            if(s["verdict"] == "OK"):
                ac_problems.append(s["problem"])
        accepted_problems.append(ac_problems)

    for problem in problemset:
        flag = 0
        for oth in problemset:
            if(problem["name"] == oth["name"]):
                flag += 1
        cnt = 0
        id = getID(problem)
        for ac_problems in accepted_problems:
            for ac_submition in ac_problems:
                if(ac_submition["name"] == problem["name"] and (flag == 1 or getID(ac_submition) == id)):
                    cnt += 1
                    break
        count[id] = cnt
    return count

response = requests.get("https://codeforces.com/api/problemset.problems")
problemset = response.json()["result"]["problems"]
response = requests.get("https://codeforces.com/api/contest.list")
constests = response.json()["result"]

students = count_ac(problemset, "hoi36.txt")
legends = count_ac(problemset, "legends.txt")

isDiv2 = dict()
for contest in constests:
    if(("Div. 2" in contest["name"]) and ("Div. 1" not in contest["name"])):
        isDiv2[contest["id"]] = True
    else:
        isDiv2[contest["id"]] = False

tags = [""]
rate = [2500 , 2800]
for problem in problemset:
    if("tags" not in problem or "rating" not in problem):
        continue
    # if(problem["rating"] < rate[0] or rate[1] < problem["rating"]):
    #     continue
    # validTags = False
    # for tag in problem["tags"]:
    #     if(tag in tags):
    #         validTags = True
    # if(validTags == False):
    #     continue
    # if(not isDiv2[problem["contestId"]]):
    #     continue
    id = getID(problem)
    # url = "https://codeforces.com/problemset/problem/{0}/{1}".format(problem["contestId"], problem["index"])
    # print('{0}\t=HYPERLINK("{1}", "{2}")\t{3}\t{4}\t{5}'.format(
        # id, url, problem["name"], problem["rating"], legends[id], students[id]))
    print("{0}\t{1}\t{2}".format(id, legends[id], students[id]))


import cv2
import numpy as np

img_1 = cv2.imread('wikipedia-without-text.png')
img_2 = cv2.imread('wikipedia-without-text-2.png')

rows_1, cols, _ = img_1.shape
rows_2, _, _ = img_2.shape

if rows_1 >= rows_2:
    result = img_1.copy()
    rows = rows_2
else:
    result = img_2.copy()
    rows = rows_1

for i in range(rows):
    for j in range(cols):
        pixel_1 = img_1[i][j]
        pixel_2 = img_2[i][j]

        if not np.array_equal(pixel_1, pixel_2):
            result[i][j] = [203, 192, 255]

cv2.imshow('comparison', result)
cv2.waitKey(0)


import sys
from pathlib import Path

from common.excel_file import ExcelFile
from common.url_parse import UrlParse
from common.utils import get_basic_dirpath

class MyUrlParse(UrlParse):
    def __init__(self, url, basic_dirpath, find_attrs):
        super().__init__(url, basic_dirpath, find_attrs)

    def get_images_list(self):
        img_list = list()
        # -------------------------------------------------
        for item_image in self.div_item.find_all(
                name=None, attrs={"class": ["gallery-slider-image-big", "gallery-slider-image-one"]}):
            if item_image.name == "img":
                img = item_image
            else:
                img = item_image.find("img")
            if img:
                img_src = img.get("data-src", None)
                if img_src:
                    img_list.append(img_src)
                img_src = img.get("src", None)
                if img_src:
                    img_list.append(img_src)
        # -------------------------------------------------
        checked_img_list = list()
        for img_src in img_list:
            img_src = self._get_full_img_url(img_src)
            checked_img_list.append(img_src)

        return checked_img_list

def main():
    if len(sys.argv) < 1 or not Path(sys.argv[1]).resolve().exists():
        raise ValueError(
            """
            Usage: python zakaz_mebel.py <url list file>
            Example: python zakaz_mebel.py /tmp/list.txt
            """
        )

    url_list_file = open(sys.argv[1], 'r')
    url_list = url_list_file.readlines()
    url_list_file.close()

    basic_dirpath = get_basic_dirpath()
    excel_file = ExcelFile(filename="excel_file", path=basic_dirpath)
    is_header = False

    for url in url_list:
        url = url.strip()
        print(url)
        url_parse = MyUrlParse(url=url, basic_dirpath=basic_dirpath, find_attrs={"class": "gallery-block-top"})
        url_parse.download_text()
        url_parse.download_images()
        row = url_parse.get_row(body_patterns=None)
        if not is_header:
            excel_file.add_row(list(row.keys()))
            is_header = True
        excel_file.add_row(list(row.values()))
        # print(row)
    excel_file.save()

if __name__ == '__main__':
    main()


# -*- coding: utf-8 -*-

import wx
import requests
import json
import threading

def CommunityExtractIds(id):
    params = {'group_id': id, 'sort': 'id_asc', 'offset': '0', 'count': '1000'}
    r = requests.get("http://api.vk.com/method/groups.getMembers", params=params)
    jsonData = r.text
    jsonData = json.loads(jsonData)
    count = jsonData['response']['count']
    outList = []  # создаём пустой список
    outList.extend(jsonData['response']['users'])
    if count > 1000:
        offset = 1000
        while offset < count:
            params.update({'offset': offset})
            r = requests.get("http://api.vk.com/method/groups.getMembers", params=params)
            jsonData = r.text
            jsonData = json.loads(jsonData)
            outList.extend(jsonData['response']['users'])
            offset = len(outList)

    # запишем строку в файл
    uIdOut = ''
    for uId in outList:
        uIdOut = uIdOut + str(uId) + '\n'
    f = open('out/' + id + '.txt', 'w')
    f.write(str(uIdOut))
    f.close()
    print(str(count) + ' ID экспортированны из ' + str(id))

app = wx.App()
wnd = wx.Frame(None, wx.ID_ANY, "I'm the title")
b = wx.Button(wnd, -1, "Create and Show a TextEntryDialog", (50, 50))
wnd.Show(True)
while 1:
    dlg = wx.TextEntryDialog(wnd, 'What is your favorite programming language?', 'Eh??', 'Python')
    dlg.SetValue("6885780")
    if dlg.ShowModal() == wx.ID_OK:
        id = dlg.GetValue()
        p1 = threading.Thread(target=CommunityExtractIds, name=id, args=[id])
        p1.start()
    else:
        if dlg.ShowModal() == wx.ID_CANCEL:
            app.Destroy()

dlg.Destroy()
app.MainLoop()

raw_input(input)


import os
from tqdm import tqdm
from natsort import natsorted

import matplotlib.pyplot as plt

import numpy as np
import torch
from torch import optim, nn, utils
import pytorch_lightning as pl
import torchvision as tv
from collections import OrderedDict

from model import SiameseNet, TripletLossModel, Classifier, ClassifierArcface
from dataset_utils.dataset_test import PatchMatchTest
from sklearn.metrics import pairwise_distances
from sklearn.preprocessing import normalize

def main(drone_img_name, map_img_name, model_name):
    print(drone_img_name, 'vs', map_img_name, 'with', model_name)
    image_names_drone = os.listdir('patches_matching_data/test/patches/')
    image_names_map = os.listdir('patches_matching_data/train/patches/')

    UAV_images = [x for x in image_names_drone if drone_img_name in x]
    Map_images = [x for x in image_names_map if map_img_name in x]

    UAV_images = natsorted(UAV_images)
    Map_images = natsorted(Map_images)

    drone_dataset = PatchMatchTest(UAV_images, 'patches_matching_data/test/patches/')
    drone_loader = utils.data.DataLoader(
        drone_dataset, batch_size=64,
        shuffle=False, pin_memory=True, num_workers=8
    )
    map_dataset = PatchMatchTest(Map_images, 'patches_matching_data/train/patches/')
    map_loader = utils.data.DataLoader(
        map_dataset, batch_size=64,
        shuffle=False, pin_memory=True, num_workers=8
    )

    UAV_embeddings = np.zeros((len(UAV_images), 1000))
    Map_embeddings = np.zeros((len(Map_images), 1000))

    if model_name=='Classifier':
        model = Classifier()
        batch_size = 64
        state_dict_model = torch.load('model_saves/classifier_version_0/epoch=22-step=13202.ckpt')['state_dict']
        new_state_dict = OrderedDict()
        for k, v in state_dict_model.items():
            name = k.replace("model.", "")
            new_state_dict[name] = v
        model.load_state_dict(new_state_dict)
        model = model.backbone
        model = model.cuda().half()
    elif model_name=='ClassifierArcface':
        model = ClassifierArcface()
        batch_size = 64
        state_dict_model = torch.load('model_saves/classifier_arcface_version_0/epoch=23-step=13776.ckpt')['state_dict']
        new_state_dict = OrderedDict()
        for k, v in state_dict_model.items():
            name = k.replace("model.", "")
            new_state_dict[name] = v
        model.load_state_dict(new_state_dict)
        model = model.backbone
        model = model.cuda().half()
    elif model_name=='TripletLossModel':
        model = TripletLossModel()
        batch_size = 64
        state_dict_model = torch.load('model_saves/triplet_version_0/epoch=24-step=14350.ckpt')['state_dict']
        new_state_dict = OrderedDict()
        for k, v in state_dict_model.items():
            name = k.replace("model.", "")
            new_state_dict[name] = v
        model.load_state_dict(new_state_dict)
        model = model.backbone
        model = model.cuda().half()
    elif model_name=='SiameseNet':
        model = SiameseNet()
        batch_size = 64
        state_dict_model = torch.load('model_saves/siamese_version_0/epoch=7-step=4592.ckpt')['state_dict']
        new_state_dict = OrderedDict()
        for k, v in state_dict_model.items():
            name = k.replace("model.", "")
            new_state_dict[name] = v
        model.load_state_dict(new_state_dict)
        model = model.backbone
        model = model.cuda().half()

    with torch.no_grad():
        for i, images in tqdm(enumerate(drone_loader),
                            total=len(drone_loader)):
            images = images.cuda().half()
            outputs = model(images)
            outputs = outputs.data.cpu().numpy()
            UAV_embeddings[
                i*batch_size:(i*batch_size + batch_size), :
            ] = outputs
        for i, images in tqdm(enumerate(map_loader),
                            total=len(map_loader)):
            images = images.cuda().half()
            outputs = model(images)
            outputs = outputs.data.cpu().numpy()
            Map_embeddings[
                i*batch_size:(i*batch_size + batch_size), :
            ] = outputs

    distances = pairwise_distances(UAV_embeddings, Map_embeddings)
    distances = distances.reshape(24480, 120, 204)

    if not os.path.isdir('results/'+drone_img_name+'_vs_'+map_img_name+'_with_'+model_name+'/'):
        os.makedirs('results/'+drone_img_name+'_vs_'+map_img_name+'_with_'+model_name+'/')
    for i in range(len(distances)):
        plt.imsave('results/'+drone_img_name+'_vs_'+map_img_name+'_with_'+model_name+'/'+str(i)+'_heatmap.png', 1.-normalize(distances[i]), cmap='hot', format='png')

    pos=0
    for x in range(24480):
        search_index = x
        retrieved_h, retrieved_w = np.unravel_index(distances[search_index].argmin(), distances[search_index].shape)
        search_h, search_w = (search_index)//204, (search_index)%204
        if (abs(search_h-retrieved_h)+abs(search_w-retrieved_w)) < 20:
            pos+=1
    print(pos/24480)

if __name__ == "__main__":
    drone_image_name = ['UAV_am', 'UAV_noon', 'UAV_pm']
    map_image_name = ['Bing', 'ESRI', 'Yandex']
    models = ['SiameseNet', 'TripletLossModel', 'Classifier', 'ClassifierArcface']
    for x in drone_image_name:
        for y in map_image_name:
            for z in models:
                main(x, y, z)


"""
Descrition
"""
__author__ = 'maxdob'
__date__ = '26.09.21'
__time__ = '3:29'
__version__ = '0.1'

import pika
import settings

def on_message(channel, method_frame, prop, body):
    body_str = body.decode("utf-8")
    rkey = method_frame.routing_key
    print(body_str)
    channel.basic_ack(delivery_tag=method_frame.delivery_tag)

rmq_parameters = pika.URLParameters(settings.rmq_url_connection_str)
rmq_connection = pika.BlockingConnection(rmq_parameters)
rmq_channel = rmq_connection.channel()
rmq_channel.queue_declare(queue='inserer.two', durable=True)
rmq_channel.basic_consume(on_message_callback=on_message, queue='inserer.two', auto_ack=True)


from flask import Flask, request, render_template, flash, redirect
import os
import uuid

from src.detector import runInference

# set the project root directory as the static folder, you can set others.
app = Flask(__name__, static_url_path='')

@app.route('/')
def root():
    #return app.send_static_file('index.html')
    return render_template('index.html')

@app.route('/home')
def application():
    #return app.send_static_file('index.html')
    return render_template('home.html')

@app.route("/upload-image", methods=["GET", "POST"])
def upload_image():
    if request.method == "POST":
        if request.files:
            image = request.files["image"]
            imageDirectory = os.path.join(os.getcwd(),"uploads")
            uniqueFilename = str(uuid.uuid4())+"."+image.filename.split('.')[-1]
            imageDirectory = os.path.join(imageDirectory, uniqueFilename)
            image.save(imageDirectory)
            print("Image saved")
            #return redirect(request.url)
    response = runInference(uniqueFilename)
    return render_template("success.html", pyArgs = response)

if __name__ == "__main__":
    app.run()


import re
from typing import Union

import permissions
from utils.choicetree import ChoiceTree

# More import statements at the end of the file, due to circular dependencies.
from pipes.logger import ErrorLog
from pipes.spout_state import SpoutState

class PipelineError(ValueError):
    '''Special error for some invalid element when processing a pipeline.'''

class ParsedPipe:
    '''In a parsed Pipeline represents a single, specific pipeoid along with its specific assigned arguments.'''
    # Different types of ParsedPipe, determined at moment of parsing
    SPECIAL         = object()
    NATIVE_PIPE     = object()
    SPOUT           = object()
    NATIVE_SOURCE   = object()
    MACRO_PIPE      = object()
    MACRO_SOURCE    = object()
    UNKNOWN         = object()

    def __init__(self, pipestr:str):
        ''' Parse a string of the form `[name] [argstr]` '''
        name, *args = pipestr.strip().split(' ', 1)
        self.name = name.lower()
        self.argstr = args[0] if args else ''

        self.errors = ErrorLog()
        self.arguments: Arguments | None = None

        ## (Attempt to) determine what kind of pipe it is ahead of time
        if self.name in ['', 'nop', 'print']:
            self.type = ParsedPipe.SPECIAL
            # Special pipes don't have arguments
        elif self.name in pipes:
            self.type = ParsedPipe.NATIVE_PIPE
            self.pipe = pipes[self.name]
            self.arguments, _, errors = Arguments.from_string(self.argstr, self.pipe.signature)
            self.errors.extend(errors, self.name)
        elif self.name in spouts:
            self.type = ParsedPipe.SPOUT
            self.pipe = spouts[self.name]
            self.arguments, _, errors = Arguments.from_string(self.argstr, self.pipe.signature)
            self.errors.extend(errors, self.name)
        elif self.name in sources:
            self.type = ParsedPipe.NATIVE_SOURCE
            self.pipe = sources[self.name]
            self.arguments, _, errors = Arguments.from_string(self.argstr, self.pipe.signature)
            self.errors.extend(errors, self.name)
        elif self.name in pipe_macros:
            self.type = ParsedPipe.MACRO_PIPE
            self.arguments, _, errors = Arguments.from_string(self.argstr)
            self.errors.extend(errors, self.name)
        elif self.name in source_macros:
            self.type = ParsedPipe.MACRO_SOURCE
            self.arguments, _, errors = Arguments.from_string(self.argstr)
            self.errors.extend(errors, self.name)
        else:
            self.type = ParsedPipe.UNKNOWN
            self.arguments, _, errors = Arguments.from_string(self.argstr)
            self.errors.extend(errors, self.name)
            # This one will keep being posted repeatedly even if the name eventually is defined, so don't uncomment it
            # self.errors.warn(f'`{self.name}` is no known pipe, source, spout or macro at the time of parsing.')
        return

class Pipeline:
    '''
    The Pipeline class parses a pipeline script into a reusable, applicable Pipeline object.
    A Pipeline is made for each script execution, for nested (parenthesised) Pipelines, and for Macros.
    Its state should be immutable past parsing and comprises only two things:
        * An internal representation of the script using ParsedPipes, GroupModes, Pipelines, Arguments, etc.
        * An ErrorLog containing warnings and errors encountered during parsing.
    '''
    def __init__(self, string: str, iterations: str=None):
        self.parser_errors = ErrorLog()

        self.iterations = int(iterations or 1)
        if self.iterations < 0:
            self.parser_errors.log('Negative iteration counts are not allowed.', True)

        ### Split the pipeline into segments (segment > segment > segment)
        segments = self.split_into_segments(string)

        ### For each segment, parse the group mode, expand the parallel pipes and parse each parallel pipe.
        self.parsed_segments: list[tuple[ groupmodes.GroupMode, list[ParsedPipe | Pipeline] ]] = []
        for segment in segments:
            try:
                segment, groupMode = groupmodes.parse(segment)
            except groupmodes.GroupModeError as e:
                self.parser_errors.log(e, True)
                # Don't attempt to parse the rest of this segment, since we aren't sure where the groupmode ends
                continue
            parallel = self.parse_segment(segment)
            self.parsed_segments.append((groupMode, parallel))

    # =========================================== Parsing ==========================================

    @classmethod
    def split_into_segments(cls, string: str):
        '''
        Split the sequence of pipes (one big string) into a list of pipes (list of strings).
        Doesn't split on >'s inside quote blocks or within parentheses, and inserts "print"s on ->'s.
        '''
        # This is an extremely hand-written extremely low-level parser for the basic structure of a pipeline.
        # There are NO ESCAPE SEQUENCES. Every quotation mark is taken as one. Every parenthesis outside of quotation marks is 100% real.
        # TODO: NOTE: This causes terrible parsing inconsistencies. e.g.    foo > bar x=( > baz     only splits on the first >

        segments: list[str] = []
        quotes = False
        parens = 0
        start = 0

        for i in range(len(string)):
            c = string[i]

            ## If quotes are open, only check for closing quotes.
            if quotes:
                ## Close quotes
                if c == '"': quotes = False

            ## Open quotes
            elif c == '"':
                quotes = True

            ## Open parentheses
            elif c == '(':
                parens += 1

            ## Close parentheses
            elif c == ')':
                if parens > 0: parens -= 1

            ## New segment
            elif parens == 0 and c == '>':
                if i > 0 and string[i-1] == '-': # The > is actually the head of a ->
                    segments.append(string[start:i-1].strip())
                    segments.append('print')
                else:
                    segments.append(string[start:i].strip())
                start = i+1 # Clip off the >

        ## Add the final segment, disregarding quotes or parentheses left open
        segments.append(string[start:].strip())
        return segments

    # Matches the first (, until either the last ) or if there are no ), the end of the string
    # Use of this regex relies on the knowledge/assumption that the nested parentheses in the string are matched
    wrapping_parens_regex = re.compile(r'\(((.*)\)(?:\^(-?\d+))?|(.*))', re.S)
    #                                        ^^         ^^^^^     ^^

    @classmethod
    def steal_parentheses(cls, segment):
        '''Steals all (intelligently-parsed) parentheses-wrapped parts from a string and puts them in a list so we can put them back later.'''
        ## Prepare the segment for Magic
        # Pretty sure the magic markers don't need to be different from the triple quote ones, but it can't hurt so why not haha
        segment = segment.replace('µ', '?µ?')

        # Parsing loop similar to the one in split_into_segments.
        # NOTE: So why not combine the two into one? Well, I tried, but BETWEEN splitting into segments and stealing parentheses
        # we have to consume the group mode from each segment! Which is hard to squeeze in here! Especially since one group mode also uses parentheses!!!
        stolen = []
        bereft = []

        quotes = False
        parens = 0
        start = 0

        for i in range(len(segment)):
            c = segment[i]

            ## If we're in quotes: ONLY look for closing quotes.
            if quotes:
                ## Open quotes
                if c == '"': quotes = False
            ## Close quotes
            elif c == '"': quotes = True

            ## Open parentheses
            elif c == '(':
                parens += 1
                ## This '(' opens a top level parenthesis: Start stealing it.
                if parens == 1:
                    ## Leave behind a Magic Marker in its place, and remember where it started
                    bereft += (segment[start:i], 'µ',  str(len(stolen)), 'µ')
                    start = i

            ## Close parentheses
            elif c == ')':
                if parens > 0:
                    parens -= 1
                    ## This ')' closes a top-level parenthesis: Complete stealing it.
                    if parens == 0:
                        ## Add the portion to our spoils, and continue from there.
                        stolen.append( segment[start:i+1] )
                        start = i+1

        ## Parentheses weren't closed before the segment (and thus also the script) ended: Pretend they were closed.
        if parens > 0: stolen.append(segment[start:])
        ## Parentheses were closed: Just add the last bit of text and we're done.
        else: bereft.append( segment[start:] )

        return ''.join(bereft), stolen

    rp_regex = re.compile(r'µ(\d+)µ')
    rq_regex = re.compile(r'§(\d+)§')

    @classmethod
    def restore_parentheses(cls, bereft, stolen):
        bereft = cls.rp_regex.sub(lambda m: stolen[int(m[1])], bereft)
        return bereft.replace('?µ?', 'µ')

    @classmethod
    def steal_triple_quotes(cls, segment):
        '''Steals all triple quoted parts from a string and puts them in a list so we can put them back later.'''
        stolen = []
        def steal(match):
            stolen.append(match[0])
            return '§' + str(len(stolen)-1) + '§'
        segment = segment.replace('§', '!§!')
        segment = re.sub(r'(?s)""".*?"""', steal, segment) # (?s) means "dot matches all"
        return segment, stolen

    @classmethod
    def restore_triple_quotes(cls, bereft, stolen):
        bereft = cls.rq_regex.sub(lambda m: stolen[int(m[1])], bereft)
        return bereft.replace('!§!', '§')

    def parse_segment(self, segment: str) -> list[Union[ParsedPipe, 'Pipeline']]:
        '''Turn a single string describing one or more parallel pipes into a list of ParsedPipes or Pipelines.'''
        #### True and utter hack: Steal triple-quoted strings and parentheses wrapped strings out of the segment string.
        # This way these types of substrings are not affected by ChoiceTree expansion, because we only put them back afterwards.
        # For triple quotes: This allows us to pass string arguments containing [|] without having to escape them, which is nice to have.
        # For parentheses: This allows us to use parallel segments inside of inline pipelines, giving them a lot more power and utility.
        segment, stolen_parens = self.steal_parentheses(segment)
        segment, stolen_quotes = self.steal_triple_quotes(segment)

        ### Parse the simultaneous pipes into a usable form: A list[Union[Pipeline, ParsedPipe]]
        parsedPipes: list[ParsedPipe | Pipeline] = []

        # ChoiceTree expands the segment into the different parallel pipes
        for pipe in ChoiceTree(segment, add_brackets=True):
            ## Put the stolen triple-quoted strings and parentheses back.
            pipe = self.restore_triple_quotes(pipe, stolen_quotes)
            pipe = self.restore_parentheses(pipe, stolen_parens)
            pipe = pipe.strip()

            ## Inline pipeline: (foo > bar > baz)
            if pipe and pipe[0] == '(':
                # TODO: This shouldn't happen via regex.
                m = re.match(Pipeline.wrapping_parens_regex, pipe)
                pipeline = m[2] or m[4]
                # Immediately attempt to parse the inline pipeline (recursion call!)
                parsed = Pipeline(pipeline, m[3])
                self.parser_errors.steal(parsed.parser_errors, context='parens')
                parsedPipes.append(parsed)

            ## Normal pipe: foo [bar=baz]*
            else:
                parsed = ParsedPipe(pipe)
                self.parser_errors.steal(parsed.errors)
                parsedPipes.append(parsed)

        return parsedPipes

    # ========================================= Application ========================================

    def check_items(self, values: list[str], context: 'Context'):
        '''Raises an error if the user is asking too much of the bot.'''
        # TODO: this could stand to be smarter/more oriented to the type of operation you're trying to do, or something, maybe...?
        # meditate on this...
        MAXCHARS = 10000
        chars = sum(len(i) for i in values)
        if chars > MAXCHARS and not permissions.has(context.origin.activator.id, permissions.owner):
            raise PipelineError(f'Attempted to process a flow of {chars} total characters at once, try staying under {MAXCHARS}.')

    async def apply(self, items: list[str], context: 'Context', parent_scope: 'ItemScope'=None) -> tuple[ list[str], ErrorLog, SpoutState ]:
        '''Apply the pipeline to a list of items the denoted amount of times.'''
        errors = ErrorLog()
        spout_state = SpoutState()

        NOTHING_BUT_ERRORS = (None, errors, None)
        errors.extend(self.parser_errors)
        if errors.terminal: return NOTHING_BUT_ERRORS

        for _ in range(self.iterations):
            iter_items, iter_errors, iter_spout_state = await self.apply_iteration(items, context, parent_scope)
            errors.extend(iter_errors)
            if errors.terminal: return NOTHING_BUT_ERRORS
            items = iter_items
            spout_state.extend(iter_spout_state, extend_print=True)

        return items, errors, spout_state

    async def apply_iteration(self, items: list[str], context: 'Context', parent_scope: 'ItemScope'=None) -> tuple[ list[str], ErrorLog, SpoutState ]:
        '''Apply the pipeline to a list of items a single time.'''
        ## This is the big method where everything happens.

        errors = ErrorLog()
        # When a terminal error is encountered, cut script execution short and only return the error log
        # This suggestively named tuple is for such cases.
        NOTHING_BUT_ERRORS = (None, errors, None)

        # Turns out this pipeline just isn't even executable due to parsing errors! abort!
        if errors.terminal:
            return NOTHING_BUT_ERRORS

        # Set up some objects we'll likely need
        item_scope = ItemScope(parent_scope)
        spout_state = SpoutState()
        loose_items = items

        self.check_items(loose_items, context)

        ### This loop iterates over the pipeline's segments as they are applied in sequence. (first > second > third)
        for group_mode, parsed_pipes in self.parsed_segments:
            next_items = []
            new_printed_items = []

            # Non-trivial groupmodes add a new context layer
            if group_mode.splits_trivially():
                group_scope = item_scope
            else:
                item_scope.set_items(loose_items)
                group_scope = ItemScope(item_scope)

            try:
                applied_group_mode = await group_mode.apply(loose_items, parsed_pipes, context, group_scope)
            except groupmodes.GroupModeError as e:
                errors.log('GroupModeError: ' + str(e), True)
                return NOTHING_BUT_ERRORS

            ### The group mode turns the list[item], list[pipe] into  list[Tuple[ list[item], Optional[Pipe] ]]
            # i.e. it splits the list of items into smaller lists, and assigns each one a pipe to be applied to (if any).
            # The implemenation of this arcane flowchart magicke is detailed in `./groupmodes.py`
            # In the absolute simplest (and most common) case, all values are simply sent to a single pipe, and this loop iterates exactly once.
            for items, parsed_pipe in applied_group_mode:
                group_scope.set_items(items)

                ## CASE: `None` is how the groupmode assigns values to remain unaffected
                if parsed_pipe is None:
                    next_items.extend(items)
                    continue

                ## CASE: The pipe is itself an inlined Pipeline (recursion!)
                if isinstance(parsed_pipe, Pipeline):
                    items, pl_errors, pl_spout_state = await parsed_pipe.apply(items, context, group_scope)
                    errors.extend(pl_errors, 'braces')
                    if errors.terminal: return NOTHING_BUT_ERRORS
                    next_items.extend(items)
                    # group_mode.is_singular is a special case where we can safely extend print values, otherwise they're discarded here
                    spout_state.extend(pl_spout_state, extend_print=group_mode.is_singular())

                    continue

                ## CASE: The pipe is a ParsedPipe: something of the form "name [argument_list]"
                name = parsed_pipe.name

                #### Determine the arguments (if needed)
                if parsed_pipe.arguments is not None:
                    args, arg_errors = await parsed_pipe.arguments.determine(context, group_scope)
                    errors.extend(arg_errors, context=name)

                # Check if something went wrong while determining arguments
                if errors.terminal: return NOTHING_BUT_ERRORS
                # Handle certain items being ignoring/filtering depending on their use in arguments
                ignored, items = group_scope.extract_ignored()
                next_items.extend(ignored)

                ###################################################
                #### Figure out what the pipe is, this is important

                ## NO OPERATION
                if name in ['', 'nop']:
                    next_items.extend(items)

                ## HARDCODED 'PRINT' SPOUT (TODO: GET RID OF THIS)
                elif name == 'print':
                    next_items.extend(items)
                    new_printed_items.extend(items)
                    spouts['print'].hook(spout_state, items)

                ## A NATIVE PIPE
                elif parsed_pipe.type == ParsedPipe.NATIVE_PIPE:
                    pipe: Pipe = parsed_pipe.pipe
                    if not pipe.may_use(context.origin.activator):
                        errors.log(f'User lacks permission to use Pipe `{name}`.', True)
                        return NOTHING_BUT_ERRORS
                    try:
                        if pipe.is_coroutine:
                            next_items.extend(await pipe.apply(items, **args))
                        else:
                            next_items.extend(pipe.apply(items, **args))
                    except Exception as e:
                        errors.log(f'Failed to process Pipe `{name}` with args {args}:\n\t{type(e).__name__}: {e}', True)
                        return NOTHING_BUT_ERRORS

                ## A SPOUT
                elif parsed_pipe.type == ParsedPipe.SPOUT:
                    spout: Spout = parsed_pipe.pipe
                    # Hook the spout into the SpoutState
                    spout.hook(spout_state, items, **args)
                    # As a rule, spouts do not affect the values
                    next_items.extend(items)

                ## A NATIVE SOURCE
                elif parsed_pipe.type == ParsedPipe.NATIVE_SOURCE:
                    source: Source = parsed_pipe.pipe
                    # Sources don't accept input values: Discard them but warn about it if nontrivial input is being discarded.
                    # This is just a style warning, if it turns out this is annoying then it should be removed.
                    # NOTE: This turned out to be annoying
                    # if items and not (len(items) == 1 and not items[0]):
                    #     errors.log(f'Source-as-pipe `{name}` received nonempty input; either use all items as arguments or explicitly `remove` unneeded items.')

                    try:
                       next_items.extend( await source.generate(context, args) )
                    except Exception as e:
                        errors.log(f'Failed to process Source-as-Pipe `{name}` with args {args}:\n\t{type(e).__name__}: {e}', True)
                        return NOTHING_BUT_ERRORS

                ## A PIPE MACRO
                elif name in pipe_macros:
                    macro = pipe_macros[name]
                    try:
                        # NEWFANGLED: Get the set of arguments and put them in Context
                        args = macro.apply_signature(args)
                        macro_ctx = context.into_macro(macro, args)
                        # DEPRECATED: Insert arguments into Macro string
                        code = macro.apply_args(args)
                    except ArgumentError as e:
                        errors.log(e, True, context=name)
                        return NOTHING_BUT_ERRORS

                    ## Load the cached pipeline if we already parsed this code once before
                    if code in pipe_macros.pipeline_cache:
                        macro_pl = pipe_macros.pipeline_cache[code]
                    else:
                        macro_pl = Pipeline(code)
                        pipe_macros.pipeline_cache[code] = macro_pl

                    newvals, macro_errors, macro_spout_state = await macro_pl.apply(items, macro_ctx)
                    errors.extend(macro_errors, name)
                    if errors.terminal: return NOTHING_BUT_ERRORS

                    next_items.extend(newvals)
                    # group_mode.is_singular is a special case where we can safely extend print values, otherwise they're discarded here
                    spout_state.extend(macro_spout_state, extend_print=group_mode.is_singular())

                ## A SOURCE MACRO
                elif name in source_macros:
                    macro = source_macros[name]

                    # Source Macro functioning is implemented in ParsedSource
                    temp_parsed_source = ParsedSource(name, None)
                    new_vals, src_errs = await temp_parsed_source.evaluate(context, group_scope, args)
                    errors.steal(src_errs, context='source-as-pipe')

                    if new_vals is None or errors.terminal:
                        errors.terminal = True
                        return NOTHING_BUT_ERRORS
                    next_items.extend(new_vals)

                ## UNKNOWN NAME
                else:
                    errors.log(f'Unknown pipe `{name}`.', True)
                    return NOTHING_BUT_ERRORS

            # Clean up after applying every group mode, prepare for the next pipeline segment
            if new_printed_items:
                spout_state.print_values.append(new_printed_items)
            loose_items = next_items
            self.check_items(loose_items, context)

        return loose_items, errors, spout_state

# These lynes be down here dve to dependencyes cyrcvlaire
from .implementations.pipes import pipes
from .implementations.sources import sources
from .implementations.spouts import spouts
from .macros import pipe_macros, source_macros
from .context import Context, ItemScope
from .signature import ArgumentError, Arguments
from .templatedstring import ParsedSource
from .pipe import Pipe, Source, Spout
import pipes.groupmodes as groupmodes


from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, HTML, Fieldset
from crispy_forms.bootstrap import Field
from core.utils.utils_commandes import Commandes
from core.widgets import SelectionActivitesWidget, DateRangePickerWidget
from core.forms.base import FormulaireBase

class Formulaire(FormulaireBase, forms.Form):
    activites = forms.CharField(label="Inscrits aux activités", required=True, widget=SelectionActivitesWidget(attrs={"afficher_colonne_detail": True}))
    presents = forms.CharField(label="Uniquement les présents", required=False, widget=DateRangePickerWidget(attrs={"afficher_check": True}))
    tri = forms.ChoiceField(label="Tri", choices=[("nom", "Nom"), ("classe", "Classe")], initial="nom", required=False)
    afficher_signature = forms.BooleanField(label="Afficher la signature", required=False, initial=True, help_text="Une case signature est ajoutée à la fin du document afin de permettre la validation des données par la famille.")
    mode_condense = forms.BooleanField(label="Mode condensé", required=False, initial=False, help_text="Aucune ligne vierge n'est ajoutée aux rubriques.")

    def __init__(self, *args, **kwargs):
        super(Formulaire, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_id = 'form_parametres'
        self.helper.form_method = 'post'

        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-md-2'
        self.helper.field_class = 'col-md-10'

        self.helper.layout = Layout(
            Commandes(annuler_url="{% url 'individus_toc' %}", enregistrer=False, ajouter=False,
                      commandes_principales=[HTML(
                          """Générer le PDF"""),
                      ]),
            Fieldset("Sélection des individus",
                Field("activites"),
                Field("presents"),
            ),
            Fieldset("Options",
                Field("tri"),
                Field("afficher_signature"),
                Field("mode_condense"),
            ),
        )


#sirve para mover archivos
import shutil
from os import mkdir
from os.path import exists, dirname, join
import jinja2
from entity_test import get_metaModelo_Entidad
from entity_test import main2

def main(debug=False):

    this_folder = dirname(__file__)

    metaModeloEntidad = get_metaModelo_Entidad(debug)

    # Construye en modelo para la entidad Comida
    modelo_comida = metaModeloEntidad.model_from_file(join(this_folder, 'Comida.ent'))

    def javatype(s):
        #asimila enteto y texto con la escritura int y String
        return {
                'entero': 'int',
                'texto': 'String'
        }.get(s.name, s.name)

    # crea una carpeta donde poner el HTML
    carpeta_generacion_HTML = join(this_folder, 'htmlGenerado')
    if not exists(carpeta_generacion_HTML):
        mkdir(carpeta_generacion_HTML)

    # inicializa la plantilla
    jinja_env = jinja2.Environment(
        loader=jinja2.FileSystemLoader(this_folder),
        trim_blocks=True,
        lstrip_blocks=True)

    # Carga la plantilla
    plantilla = jinja_env.get_template('Plantilla.template')

    for entity in modelo_comida.entidades:
        # para cada entidad genera un archivo java
        with open(join(carpeta_generacion_HTML,
                       "Menu%s.html" % entity.nombre.capitalize()), 'w') as f:
            f.write(plantilla.render(entidad=entity))
        with open(join(this_folder,"informacion.json")) as  origen:
                   with open(join(carpeta_generacion_HTML,
                              "informacion.json"), 'w') as destino:
                              shutil.copyfileobj(origen,destino)

if __name__ == "__main__":
    main()
    main2()


# encoding: utf-8
"""
Extended Api implementation with an application-specific helpers
----------------------------------------------------------------
"""
from six import iteritems

from flask_restplus_patched import Api as BaseApi

from .namespace import Namespace

class Api(BaseApi):
    """
    Having app-specific handlers here.
    """

    def namespace(self, *args, **kwargs):
        # The only purpose of this method is to pass custom Namespace class
        _namespace = Namespace(*args, **kwargs)
        self.namespaces.append(_namespace)
        return _namespace

    def add_oauth_scope(self, scope_name, scope_description):
        for authorization_settings in self.authorizations.values():
            if authorization_settings['type'].startswith('oauth'):
                assert scope_name not in authorization_settings['scopes'], \
                    "OAuth scope %s already exists" % scope_name
                authorization_settings['scopes'][scope_name] = scope_description

    def add_namespace(self, ns, path=None):
        # Rewrite security rules for OAuth scopes since Namespaces don't have
        # enough information about authorization methods.
        for resource, _, _ in ns.resources:
            for method in resource.methods:
                method_func = getattr(resource, method.lower())

                if (
                        hasattr(method_func, '__apidoc__')
                        and
                        'security' in method_func.__apidoc__
                        and
                        '__oauth__' in method_func.__apidoc__['security']
                ):
                    oauth_scopes = method_func.__apidoc__['security']['__oauth__']['scopes']
                    method_func.__apidoc__['security'] = {
                        auth_name: oauth_scopes
                        for auth_name, auth_settings in iteritems(self.authorizations)
                        if auth_settings['type'].startswith('oauth')
                    }

        super(Api, self).add_namespace(ns, path=path)


import random
import itertools as it
from turtle import *
from my_set import *

"""
Algorithm:
Create a list of all walls
Create a set for each cell, each containing just that one cell.
For each wall, in some random order:
If the cells divided by this wall belong to distinct sets:
Remove the current wall.
Join the sets of the formerly divided cells.
Test end of generation.
"""

def draw_walls(walls, N, scale):
    def draw_wall_0(i, j):
        penup()
        setpos(int(scale * (i + 0.5)), int(scale * (j + 0.5)))
        setheading(270)
        pendown()
        forward(scale)

    def draw_wall_1(i, j):
        penup()
        setpos(int(scale * (i - 0.5)), int(scale * (j + 0.5)))
        setheading(0)
        pendown()
        forward(scale)

    speed("fastest")
    penup()
    setpos(int(scale * (0 - 0.5)), int(scale * (0 - 0.5)))
    setheading(0)
    pendown()
    forward(scale * N)
    left(90)
    forward(scale * N)
    left(90)
    forward(scale * N)
    left(90)
    forward(scale * N)

    for wall in walls:
        i, j, o = wall
        if o == 0:
            draw_wall_0(i, j)
        elif o == 1:
            draw_wall_1(i, j)

def find_set(cells, ij):
    for idx, cell in enumerate(cells):
        if set_in(cell, ij):
            return idx
        return None

if __name__ == "__main__":
    N = 50
    walls = [(i, j, o) for i, j, o in it.product(range(N), range(N), [0, 1])]
    cells = [[(i, j)] for i, j in it.product(range(N), range(N))]
    start = (0, 0)
    end = (N - 1, N - 1)
    while walls:
        i_wall = random.randint(0, len(walls) - 1)
        i, j, o = walls[i_wall]
        i_set1 = find_set(cells, (i, j))
    if o == 0 and i < N - 1:  # mur à l'est ?
        i_set2 = find_set(cells, (i + 1, j))
    elif o == 1 and j < N - 1:  # mur au nord ?
        i_set2 = find_set(cells, (i, j + 1))
    else:
        continue
    if i_set1 != i_set2:  # pourquoi 0 ?
        # A faire:
        # Réunir set1 et set2
        union = set_union(cells[i_set1],cells[i_set2])
        cells[i_set1] = union
        # MAJ cells
        del cells[i_set2]
        # MAJ walls
        del walls[i_wall]
        # Faire ici terminer le while si nécessaire
        if set_in(union, start) and set_in(union, end):
            break
    print(walls)
    draw_walls(walls, N, scale=5)


"""
settings test.
"""

import pytest  # type: ignore

from wandb import Settings
import copy

def test_attrib_get():
    s = Settings()
    s.setdefaults()
    assert s.base_url == "https://api.wandb.ai"

def test_attrib_set():
    s = Settings()
    s.base_url = "this"
    assert s.base_url == "this"

def test_attrib_get_bad():
    s = Settings()
    with pytest.raises(AttributeError):
        s.missing

def test_attrib_set_bad():
    s = Settings()
    with pytest.raises(AttributeError):
        s.missing = "nope"

def test_update_dict():
    s = Settings()
    s.update(dict(base_url="something2"))
    assert s.base_url == "something2"

def test_update_kwargs():
    s = Settings()
    s.update(base_url="something")
    assert s.base_url == "something"

def test_update_both():
    s = Settings()
    s.update(dict(base_url="somethingb"), project="nothing")
    assert s.base_url == "somethingb"
    assert s.project == "nothing"

def test_copy():
    s = Settings()
    s.update(base_url="changed")
    s2 = copy.copy(s)
    assert s2.base_url == "changed"
    s.update(base_url="notchanged")
    assert s.base_url == "notchanged"
    assert s2.base_url == "changed"

def test_invalid_dict():
    s = Settings()
    with pytest.raises(KeyError):
        s.update(dict(invalid="new"))

def test_invalid_kwargs():
    s = Settings()
    with pytest.raises(KeyError):
        s.update(invalid="new")

def test_invalid_both():
    s = Settings()
    with pytest.raises(KeyError):
        s.update(dict(project="ok"), invalid="new")
    assert s.project != "ok"
    with pytest.raises(KeyError):
        s.update(dict(wrong="bad", entity="nope"), project="okbutnotset")
    assert s.entity != "nope"
    assert s.project != "okbutnotset"

def test_freeze():
    s = Settings()
    s.project = "goodprojo"
    assert s.project == "goodprojo"
    s.freeze()
    with pytest.raises(TypeError):
        s.project = "badprojo"
    assert s.project == "goodprojo"
    with pytest.raises(TypeError):
        s.update(project="badprojo2")
    assert s.project == "goodprojo"
    c = copy.copy(s)
    assert c.project == "goodprojo"
    c.project = "changed"
    assert c.project == "changed"

def test_bad_choice():
    s = Settings()
    with pytest.raises(TypeError):
        s.mode = "goodprojo"
    with pytest.raises(TypeError):
        s.update(mode="badpro")


import plotly
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import plotly.express as px
from dash import Dash, dcc, html
import pandas as pd
from dash.dependencies import Input, Output
import dash
import numpy as np
import plotly.tools as tls
import plotly.figure_factory as ff

# df = pd.read_csv("/Users/jishnusrivastava/Documents/Exploratory-Data-Analysis/IBM_HR.csv")
df = pd.read_csv("https://raw.githubusercontent.com/Jks08/Exploratory-Data-Analysis/main/IBM_HR.csv")
df = df.drop(['Over18','EmployeeCount','StandardHours'],axis=1)
df.Attrition.replace(to_replace = dict(Yes = 1, No = 0), inplace = True)
df.describe()
df.tail()

data = [go.Bar(x=df['Age'],y=df['TotalWorkingYears'])]
layout = go.Layout(xaxis=dict(title='Age'),yaxis=dict(title='Total Working Years'))
fig = go.Figure(data,layout=layout)
fig.show()

fig1 = make_subplots(rows=2,cols=2, specs=[[{"type": "bar"}, {"type": "pie"}],[{'type':'histogram'},{'type':'bar'}]],subplot_titles=("Age vs Total Working Hours", "Education pie chart", "Daily Rate vs Years Since Promotion", "Total Working Hours vs Hourly Rate"))

fig1.add_trace(go.Bar(x=df['Age'],y=df['TotalWorkingYears']),row=1,col=1)
fig1.add_trace(go.Pie(labels = df['EducationField'],values=df['DailyRate']),row=1,col=2)
fig1.add_trace(go.Histogram(x=df['YearsSinceLastPromotion'],y=df['DailyRate']),row=2,col=1)
fig1.add_trace(go.Bar(x=df['HourlyRate'],y=df['TotalWorkingYears']),row=2,col=2)

fig1.update_xaxes(title_text="Age of Employee", row=1, col=1)
fig1.update_xaxes(title_text="Field of Education", row=1, col=2)
fig1.update_xaxes(title_text="Years since last promotion", showgrid=False, row=2, col=1)
fig1.update_xaxes(title_text="Hourly Rate", row=2, col=2)

fig1.update_yaxes(title_text="Total Working Hours", row=1, col=1)
fig1.update_yaxes(title_text="Daily Rate", row=1, col=2)
fig1.update_yaxes(title_text="Daily Rate", showgrid=False, row=2, col=1)
fig1.update_yaxes(title_text="Total Working Hours", row=2, col=2)

# fig1.show()

tempFig = px.line_3d(df,x='Age',y='TotalWorkingYears',z='MonthlyIncome', color = 'JobSatisfaction',title='Age vs Total Working Hours vs Monthly Income',template='plotly_dark')

# tempFig = px.pie(df, values='Age', names='EducationField', title='Daily Rate vs Education Field', width=800,height=800)
# tempFig.show()

# options = [{'label':i,'value':i} for i in df.select_dtypes(include=['int64']).columns]
# options
attrition = df[(df['Attrition'] != 0)]
no_attrition = df[(df['Attrition'] == 0)]

trace = go.Bar(x = (len(attrition), len(no_attrition)), y = ['Yes Attrition', 'No Attition'], orientation = 'h', marker=dict(color=['MediumTurquoise', 'tomato']))

# go.Figure(data = [trace]).show()

def plot_distribution(var_select, bin_size):
    corr = df['Attrition'].corr(df[var_select])
    corr = np.round(corr,3)
    tmp1 = attrition[var_select]
    tmp2 = no_attrition[var_select]
    hist_data = [tmp1, tmp2]

    group_labels = ['Yes Attrition', 'No Attrition']
    colors = ['MediumTurquoise', 'tomato']

    fig = ff.create_distplot(hist_data, group_labels, colors = colors, show_hist = True,
                             curve_type='kde', bin_size = bin_size)

    fig['layout'].update(title = var_select+' '+'(corr target ='+ str(corr)+')',autosize=False,width=1000,height=500)
    return fig

def barplot(var_select, x_no_numeric) :
    tmp1 = df[(df['Attrition'] != 0)]
    tmp2 = df[(df['Attrition'] == 0)]
    tmp3 = pd.DataFrame(pd.crosstab(df[var_select],df['Attrition']), )
    tmp3['Attr%'] = tmp3[1] / (tmp3[1] + tmp3[0]) * 100
    if x_no_numeric == True  :
        tmp3 = tmp3.sort_values(1, ascending = False)

    color=['MediumTurquoise', 'tomato']
    trace1 = go.Bar(
        x=tmp1[var_select].value_counts().keys().tolist(),
        y=tmp1[var_select].value_counts().values.tolist(),
        name='Yes Attrition',opacity = 1.0, marker=dict(
        color='red',
        line=dict(color='#000000',width=1)))

    trace2 = go.Bar(
        x=tmp2[var_select].value_counts().keys().tolist(),
        y=tmp2[var_select].value_counts().values.tolist(),
        name='No Attrition', opacity = 1.0, marker=dict(
        color='blue',
        line=dict(color='#000000',width=1)))

    trace3 =  go.Scatter(
        x=tmp3.index,
        y=tmp3['Attr%'],
        yaxis = 'y2',
        name='% Attrition', opacity = 0.6, marker=dict(
        color='black',
        line=dict(color='#000000',width=0.5
        )))

    layout = dict(title =  str(var_select),xaxis=dict(), yaxis=dict(title= 'Count'), yaxis2=dict(range= [-0, 75], overlaying= 'y', anchor= 'x',
                          side= 'right',
                          zeroline=False,
                          showgrid= False,
                          title= '% Attrition'))

    fig = go.Figure(data=[trace1, trace2, trace3], layout=layout)
    fig.update_layout(autosize=False,width=1000,height=500)
    fig.show()

figMulti = make_subplots(rows=1,cols=2,subplot_titles=('Age','DailyRate'))
for trace in plot_distribution('Age', False).select_traces():
    figMulti.add_trace(trace,row=1,col=1)
for trace in plot_distribution('DailyRate', 100).select_traces():
    figMulti.add_trace(trace,row=1,col=2)

figMulti1 = make_subplots(rows=1,cols=2,subplot_titles=('DistanceFromHome','HourlyRate'))
for trace in plot_distribution('DistanceFromHome', False).select_traces():
    figMulti1.add_trace(trace,row=1,col=1)
for trace in plot_distribution('HourlyRate', False).select_traces():
    figMulti1.add_trace(trace,row=1,col=2)

figMulti2 = make_subplots(rows=1,cols=2,subplot_titles=('MonthlyIncome','MonthlyRate'))
for trace in plot_distribution('MonthlyIncome', 100).select_traces():
    figMulti2.add_trace(trace,row=1,col=1)
for trace in plot_distribution('MonthlyRate', 100).select_traces():
    figMulti2.add_trace(trace,row=1,col=2)

figMulti3 = make_subplots(rows=1,cols=2,subplot_titles=('NumCompaniesWorked','PercentSalaryHike'))
for trace in plot_distribution('NumCompaniesWorked', False).select_traces():
    figMulti3.add_trace(trace,row=1,col=1)
for trace in plot_distribution('PercentSalaryHike', False).select_traces():
    figMulti3.add_trace(trace,row=1,col=2)

figMulti4 = make_subplots(rows=1,cols=2,subplot_titles=('TotalWorkingYears','TrainingTimesLastYear'))
for trace in plot_distribution('TotalWorkingYears', False).select_traces():
    figMulti4.add_trace(trace,row=1,col=1)
for trace in plot_distribution('TrainingTimesLastYear', False).select_traces():
    figMulti4.add_trace(trace,row=1,col=2)

figMulti5 = make_subplots(rows=1,cols=2,subplot_titles=('YearsAtCompany','YearsInCurrentRole'))
for trace in plot_distribution('YearsAtCompany', False).select_traces():
    figMulti5.add_trace(trace,row=1,col=1)
for trace in plot_distribution('YearsInCurrentRole', False).select_traces():
    figMulti5.add_trace(trace,row=1,col=2)

figMulti6 = make_subplots(rows=1,cols=2,subplot_titles=('YearsSinceLastPromotion','YearsWithCurrManager'))
for trace in plot_distribution('YearsSinceLastPromotion', False).select_traces():
    figMulti6.add_trace(trace,row=1,col=1)
for trace in plot_distribution('YearsWithCurrManager', False).select_traces():
    figMulti6.add_trace(trace,row=1,col=2)

app = dash.Dash()
app.title = 'Attrition Analysis - JKS'
server = app.server

app.layout = html.H1(children=[
    html.P(
        id="parent",
        children = [html.P(id="IBM_HR", children='IBM HR Attrition Analysis', style={'textAlign':'center','backgroundColor':'beige','color':'Blue'}),
        dcc.Dropdown(id="dropdown",
        options = [{'label':i,'value':i} for i in df.select_dtypes(include=['int64']).columns],
        value=['DailyRate','MonthlyIncome'],
        multi=True),
        dcc.Graph(id="graph"),]),
    html.Div([
        html.P(children='Age vs Total Working Hours vs Monthly Income',style={'textAlign':'center','backgroundColor':'beige','color':'Green'}),
        dcc.Graph(id='graph2',figure=tempFig)
        ]
    ),
    html.Div([
        html.P(children='Some Subplots',style={'textAlign':'center','color':'Red'}),
        dcc.Graph(id='graph3',figure=fig1)
    ]),
    html.Div([
        html.P(children='Attrition vs Age and Daily rate',style={'textAlign':'left','color':'Blue'}),
        dcc.Graph(figure=figMulti)
    ]),
    html.Div([
        html.P(children='Attrition vs Distance from Home and Hourly Rate',style={'textAlign':'left','color':'Blue'}),
        dcc.Graph(figure=figMulti1)
    ]),
    html.Div([
        html.P(children='Attrition vs Monthly Income and Monthly Rate',style={'textAlign':'left','color':'Blue'}),
        dcc.Graph(figure=figMulti2)
    ]),
    html.Div([
        html.P(children='Attrition vs Num Companies Worked and Percent Salary Hike',style={'textAlign':'left','color':'Blue'}),
        dcc.Graph(figure=figMulti3)
    ]),
    html.Div([
        html.P(children='Attrition vs Total Working Years and Training Times Last Year',style={'textAlign':'left','color':'Blue'}),
        dcc.Graph(figure=figMulti4)
    ]),
    html.Div([
        html.P(children='Attrition vs Years At Company and Years In Current Role',style={'textAlign':'left','color':'Blue'}),
        dcc.Graph(figure=figMulti5)
    ]),
    html.Div([
        html.P(children='Attrition vs Years Since Last Promotion and Years With Current Manager',style={'textAlign':'left','color':'Blue'}),
        dcc.Graph(figure=figMulti6)
    ]),
    html.Div([
        html.H1(children='Key Findings and Insights ',style={'textAlign':'left','color':'#00C68B', 'fontSize':50,'fontFamily':'Times New Roman'}),
        html.P(children="ðŸŸ¡ 'Attrition' was at 66.67% for 19 year olds, but then the 'Attrition' rate drastically drops until employees hit the age of 58, whereafter 'Attrition' jumps up to 35.71%.",style={'textAlign':'left','color':'Black', 'fontSize':20,'fontFamily':'Times New Roman'}),
        html.P(children="ðŸŸ¡ When 'YearsAtCompany' was 0 the 'Attrition' rate was 36.36%, whereas when 'Years at Company' became 1, the attrition rate was 34.50%.", style={'textAlign':'left','color':'Black', 'fontSize':20,'fontFamily':'Times New Roman'}),
        html.P(children="ðŸŸ¡ For the 'MaritalStatus - Single' the attrition rate was 25.53%, and interestingly it was much lower for married people at 12.48% and even lower for divorced at 10.09%.", style={'textAlign':'left','color':'Black', 'fontSize':20,'fontFamily':'Times New Roman'}),
        html.P(children="ðŸŸ¡ The 'Attrition' rate was 25.00% for 'JobSatisfaction' of 1, but then it dropped to 16.67% for 'JobSatisfaction' of 2, and then it dropped even further to 12.50% for 'JobSatisfaction' of 3.", style={'textAlign':'left','color':'Black', 'fontSize':20,'fontFamily':'Times New Roman'}),
        html.P(children="ðŸŸ¡ 'EducationField' of Human Resources has an 'Attrition' rate of 25.92%, whereas that of Medical was at 13.57%.", style={'textAlign':'left','color':'Black', 'fontSize':20,'fontFamily':'Times New Roman'}),
        html.P(children="ðŸŸ¡ When 'TotalWorkingYears' was 0 the attrition rate was 45.45%, when 1 the attrition rate was 49.38% and at 40 it was 100%, due to retirement.", style={'textAlign':'left','color':'Black', 'fontSize':20,'fontFamily':'Times New Roman'}),
    ]),
    html.Div([
        html.H1(children="Conclusion",style={'textAlign':'left','color':'#00C68B', 'fontSize':50,'fontFamily':'Times New Roman'}),
        html.P(children="ðŸŸ¡ We conclude that Attrition has a higher percentage when employees are younger than compared to older. Also, as Job Satisfaction increases, Attrition becomes lesser.", style={'textAlign':'left','color':'Black', 'fontSize':15,'fontFamily':'Times New Roman'}),
    ]),
    html.Div([
        html.H1(children='By - JKS ', style={'textAlign':'center','color':'Black', 'fontSize':50,'fontFamily':'Courier New'})
    ]),
    html.Div([
        html.A('Github of JKS', href='http://github.com/Jks08', target='http://github.com/Jks08', style={'textAlign':'center','color':'Black', 'fontSize':20,'fontFamily':'Courier New'})
    ])
], style={'backgroundColor':'White'})

@app.callback(Output("graph", "figure"), [Input("dropdown", "value")])

# def update_graph(dropdown):
#     fig = px.histogram(df, x=dropdown, color="Attrition", title=f"Attrition vs {dropdown}")
#     return fig

# def update_graph(dropdown):
#     print(dropdown)
#     fig = go.Figure([go.Scatter(x=df['Age'],y=df['{}'.format(dropdown)],line=dict(color='firebrick'), mode='lines+markers', name='{}'.format(dropdown))])
#     fig.update_layout(title=f"Attrition vs {dropdown}", xaxis_title="Age", yaxis_title="{}".format(dropdown))
#     return fig

# def update_graph(dropdown):
#     print(dropdown)
#     # fig = go.Figure([go.Bar(x=df['Age'],y=df['{}'.format(dropdown)])])
#     fig = px.line_3d(df,x=df['Age'],y=df['{}'.format(dropdown)],z=df['TotalWorkingYears'],color=df['JobSatisfaction'],title=f"Attrition vs {dropdown}")
#     return fig

# def update_graph(dropdown):
#     print(dropdown)
#     fig = px.bar(df, x=df['Age'], y=df['{}'.format(dropdown)], color=df['Attrition'], title=f"Attrition vs {dropdown}")
#     return fig

def update_graph(dropdown):
    df1 = pd.read_csv("https://raw.githubusercontent.com/Jks08/Exploratory-Data-Analysis/main/IBM_HR.csv")
    print(dropdown)
    fig = px.scatter_matrix(df1, dimensions=dropdown, color="Attrition", title=f"Attrition analysis using {dropdown}",template='plotly_dark')
    return fig

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


from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, QTimer
from enum import Enum

class TimerType(Enum):
    Pom = 0
    ShortBrk = 1
    LongBrk = 2

class Timer(QObject):
    notify = pyqtSignal(str, int)
    notify_progress = pyqtSignal(int, int, int)

    def __init__(self, pom_dur, short_dur, long_dur, long_freq):
        QObject.__init__(self)

        self.pom_dur = pom_dur
        self.short_dur = short_dur
        self.long_dur = long_dur
        self.long_freq = long_freq

        self.timer = QTimer()
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.next)

        self.notification_timer = QTimer()
        self.notification_timer.timeout.connect(self.send_progress)

        self.curr_timer_type = TimerType.Pom
        self.finished_poms = 0

    def send_progress(self):
        #print(f"Send progress: [{self.curr_timer_type} {self.pom_dur} {self.short_dur} {self.long_dur}] {self.timer.remainingTime()}")
        remaining_time = self.timer.remainingTime()
        mins = (remaining_time / 1000) // 60
        secs = (remaining_time / 1000) % 60
        self.notify_progress.emit(mins, secs, (remaining_time/self.timer.interval())*100)

    @pyqtSlot()
    def start(self):
        if self.curr_timer_type == TimerType.Pom:
            self.timer.start(self.pom_dur * 60 * 1000)
            self.notify.emit("Pomodoro", self.pom_dur )
        elif self.curr_timer_type == TimerType.ShortBrk:
            self.timer.start(self.short_dur * 60 * 1000)
            self.notify.emit("Short Break", self.short_dur)
        elif self.curr_timer_type == TimerType.LongBrk:
            self.timer.start(self.long_dur * 60 * 1000)
            self.notify.emit("Long Break", self.long_dur)

        self.notification_timer.start(1000)

    @pyqtSlot()
    def stop(self):
        print("stop")
        self.timer.stop()
        self.notification_timer.stop()

    @pyqtSlot()
    def next(self):
        if self.curr_timer_type == TimerType.Pom:
            self.finished_poms += 1
            if self.finished_poms == self.long_freq:
                self.finished_poms = 0
                self.curr_timer_type = TimerType.LongBrk
            else:
                self.curr_timer_type = TimerType.ShortBrk
        elif self.curr_timer_type == TimerType.ShortBrk:
            self.curr_timer_type = TimerType.Pom
        elif self.curr_timer_type == TimerType.LongBrk:
            self.curr_timer_type = TimerType.Pom

        self.timer.stop()
        self.start()

    @pyqtSlot(int)
    def pom_dur_changed(self, new_dur):
        self.pom_dur = new_dur

    @pyqtSlot(int)
    def short_dur_changed(self, new_dur):
        self.short_dur = new_dur

    @pyqtSlot(int)
    def long_dur_changed(self, new_dur):
        self.long_dur = new_dur

    @pyqtSlot(int)
    def long_freq_changed(self, new_freq):
        self.long_freq = new_freq


from traits.api import Instance, Button
from traitsui.api import (
    EnumEditor,
    HGroup,
    HSplit,
    Item,
    ModelView,
    ObjectColumn,
    TableEditor,
    TextEditor,
    UItem,
    VGroup,
    View,
    VSplit,
)

from mnca_app.mnca_model import MncaModel
from mnca_app.mnca_board_editor import BoolArrayEditor

def optional_int_editor():
    return TextEditor(
        evaluate=lambda x: int(x) if x != "" else None,
        format_func=lambda x: str(x) if x is not None else "",
    )

class MncaView(ModelView):

    model = Instance(MncaModel, allow_none=False)

    randomize_rules = Button("Randomize Rules")

    def _randomize_rules_fired(self):
        self.model.randomize_rules()

    reset_board = Button("Reset Board")

    def _reset_board_fired(self):
        self.model.reset_board()

    clear_board = Button("Clear Board")

    def _clear_board_fired(self):
        self.model.clear_board()

    def rules_table(self):
        return TableEditor(
            sortable=False,
            auto_size=True,
            orientation="vertical",
            edit_view=View(
                Item("mask", editor=EnumEditor(values=sorted(self.model.masks.keys()))),
                Item("lower_limit", editor=optional_int_editor()),
                Item("upper_limit", editor=optional_int_editor()),
                Item("acts_on"),
                Item("result"),
            ),
            columns=[
                ObjectColumn(
                    name="mask",
                    label="Mask",
                    editable=False,
                ),
                ObjectColumn(
                    name="lower_limit",
                    label="Lower",
                    editable=False,
                ),
                ObjectColumn(
                    name="upper_limit",
                    label="Upper",
                    editable=False,
                ),
                ObjectColumn(
                    name="acts_on",
                    label="Acts On",
                    editable=False,
                ),
                ObjectColumn(
                    name="result",
                    label="Result",
                    editable=False,
                )
            ]
        )

    def default_traits_view(self):
        view = View(
            HSplit(
                VGroup(
                    UItem(
                        "model.board",
                        editor=BoolArrayEditor(
                            scale=True,
                            allow_upscaling=False,
                            allow_clipping=False,
                            preserve_aspect_ratio=True,
                        ),
                        resizable=True,
                        springy=True,
                    ),
                    HGroup(
                        Item("model.live_color", label="Life Colour"),
                        Item("model.dead_color", label="Dead Colour"),
                    ),
                ),
                VSplit(
                    VGroup(
                        Item("model.paused", label="Pause"),
                        Item("model.board_size"),
                    ),
                    VGroup(
                        Item("model.reset_life_pct", label="Reset Life %"),
                        UItem("reset_board"),
                        UItem("clear_board"),
                    )
                ),
                VGroup(
                    Item("model.masks_dir", label="Masks Dir"),
                    UItem("model.rules", editor=self.rules_table()),
                    UItem("randomize_rules"),
                ),
                springy=True,
            ),
            resizable=True,
        )
        return view