# validators.py: custom validators for use with WTForms

from wtforms.validators import ValidationError, StopValidation
from app.utils.ascii_checks import isAscii

# a validator is any function accepting (form,field) as arguments
# and capable of raising wtforms.validators.ValidationError

class AsciiOnly():
    '''
        Validator concerning the usage of strictly ascii chars in a text field
    '''
    def __init__(self,message=None):
        if not message:
            message='Please use only ASCII characters.'
        self.message=message

    def __call__(self,form,field):
        if not isAscii(field.data):
            raise ValidationError(self.message)

class IntegerString():
    '''
        Validates (optionally empty strings or) integer-looking strings
    '''
    def __init__(self, allowEmpty=True, message=None):
        if not message:
            message='Please insert a number%s.' % (' or leave blank' if allowEmpty else '')
        self.message=message
        self.allowEmpty=allowEmpty

    def __call__(self,form,field):
        if self.allowEmpty and field.data=='':
            return
        try:
            qnum=int(field.data)
        except:
            # we interrupt the validation chain since usually the next ones, if any, assume numeric
            raise StopValidation(self.message)
        return


import pwd
import os
import sys
import unittest
from subprocess import Popen, PIPE
import re
from difflib import unified_diff
from textwrap import dedent

from lxml import etree
from six import string_types

from aquilon.config import Config, lookup_file_path
from aquilon.worker import depends  # pylint: disable=W0611

from aqdb.utils import copy_sqldb

from networktest import DummyNetworks

DSDB_EXPECT_SUCCESS_FILE = "expected_dsdb_cmds"
DSDB_EXPECT_FAILURE_FILE = "fail_expected_dsdb_cmds"
DSDB_EXPECT_FAILURE_ERROR = "fail_expected_dsdb_error"
DSDB_ISSUED_CMDS_FILE = "issued_dsdb_cmds"
CM_JUSTIFICATION = "No justification found, please supply a TCM or SN ticket."
CM_EMERGENCY = "Use of emergency requires a reason to be supplied."
CM_FORMAT = "Failed to parse justification, no valid TCM or SN ticket found."
CM_EDM = "Executing an emergency change without a justification, EDM has not be called."
CM_WARN = 'Continuing with execution; however in the future this operation will fail.'

class TestBrokerCommand(unittest.TestCase):

    config = None
    scratchdir = None
    dsdb_coverage_dir = None
    sandboxdir = None

    user = None
    realm = None

    aurora_with_node = "oy604c2n6"
    aurora_without_node = "pissp1"
    aurora_without_rack = "oy605c2n6"

    valid_just_tcm = ["--justification", "tcm=123456789"]
    exception_trigger_just_tcm = ["--justification", "tcm=666666666"]
    timeout_trigger_just_tcm = ["--justification", "tcm=111111111"]
    timeout_default_trigger_just_tcm = ["--justification", "tcm=222222222"]
    valid_just_sn = ["--justification", "sn=CHNG123456"]
    invalid_justification = ["--justification", "foo"]
    emergency_just_with_reason = ["--justification", "emergency", "--reason", "Valid reason"]
    emergency_tcm_just_with_reason = ["--justification", "emergency,tcm=123456789", "--reason", "Valid reason"]
    emergency_just_without_reason = ["--justification", "emergency"]
    just_reason = ["--reason", "Valid reason"]

    @classmethod
    def setUpClass(cls):
        cls.config = Config()
        cls.net = DummyNetworks(cls.config)

        cls.scratchdir = cls.config.get("unittest", "scratchdir")
        cls.dsdb_coverage_dir = os.path.join(cls.scratchdir, "dsdb_coverage")

        dirs = [cls.scratchdir, cls.dsdb_coverage_dir]
        for dir in dirs:
            if not os.path.exists(dir):
                os.makedirs(dir)

        # Run klist and store the information
        klist = cls.config.lookup_tool('klist')
        p = Popen([klist], stdout=PIPE, stderr=2)
        out, err = p.communicate()
        m = re.search(r'^\s*(?:Default p|P)rincipal:\s*'
                      r'(?P<principal>(?P<user>\S.*)@(?P<realm>.*?))$',
                      out, re.M)
        cls.principal = m.group('principal')
        cls.realm = m.group('realm')

        cls.user = pwd.getpwuid(os.getuid())[0]

        if not cls.user or not cls.realm:
            raise ValueError("Failed to detect the Kerberos principal.")

        cls.sandboxdir = os.path.join(cls.config.get("broker", "templatesdir"),
                                      cls.user)

        cls.template_extension = cls.config.get("panc", "template_extension")
        cls.gzip_profiles = cls.config.getboolean("panc", "gzip_output")
        if cls.gzip_profiles:
            compress_suffix = ".gz"
        else:
            compress_suffix = ""

        cls.xml_suffix = ".xml" + compress_suffix
        cls.xml_default = cls.config.getboolean("panc", "xml_profiles")

        cls.json_suffix = ".json" + compress_suffix
        cls.json_default = cls.config.getboolean("panc", "json_profiles")

        cls.input_xml = etree.parse(lookup_file_path("input.xml"))

        # Need to import protocol buffers after we have the config
        # object all squared away and we can set the sys.path
        # variable appropriately.
        # It would be simpler just to change sys.path in runtests.py,
        # but this allows for each test to be run individually (without
        # the runtests.py wrapper).
        protodir = cls.config.get("protocols", "directory")
        if protodir not in sys.path:
            sys.path.append(protodir)
        cls.protocols = {}
        for m in ['aqdsystems_pb2', 'aqdnetworks_pb2', 'aqdservices_pb2',
                  'aqddnsdomains_pb2', 'aqdlocations_pb2', 'aqdaudit_pb2',
                  'aqdparamdefinitions_pb2', 'aqdparameters_pb2',
                  'aqdentitlements_pb2']:
            cls.protocols[m] = __import__(m)

    def setUp(self):
        for name in [DSDB_EXPECT_SUCCESS_FILE, DSDB_EXPECT_FAILURE_FILE,
                     DSDB_ISSUED_CMDS_FILE, DSDB_EXPECT_FAILURE_ERROR]:
            path = os.path.join(self.dsdb_coverage_dir, name)
            try:
                os.remove(path)
            except OSError:
                pass

    def tearDown(self):
        if not os.environ.get("AQD_UNITTEST_FAILFAST"):
            return
        if not all(sys.exc_info()):
            copy_sqldb(self.config, target='SNAPSHOT')

    def template_name(self, *template, **args):
        if args.get("sandbox", None):
            dir = os.path.join(self.sandboxdir, args.get("sandbox"))
        elif args.get("domain", None):
            dir = os.path.join(self.config.get("broker", "domainsdir"),
                               args.get("domain"))
        else:
            self.assertTrue(0, "template_name() called without domain or sandbox")
        return os.path.join(dir, *template) + self.template_extension

    def plenary_name(self, *template):
        dir = self.config.get("broker", "plenarydir")
        return os.path.join(dir, *template) + self.template_extension

    def check_plenary_exists(self, *path):
        plenary = self.plenary_name(*path)
        self.assertTrue(os.path.exists(plenary),
                        "Plenary '%s' does not exist." % plenary)

    def check_plenary_gone(self, *path, **kw):
        plenary = self.plenary_name(*path)
        self.assertFalse(os.path.exists(plenary),
                         "Plenary '%s' was not expected to exist." % plenary)
        if kw.get("directory_gone", False):
            dir = os.path.dirname(plenary)
            self.assertFalse(os.path.exists(dir),
                             "Plenary directory '%s' still exists" % dir)

    def check_plenary_contents(self, *path, **kwargs):
        # Passing lists as a keyword arg triggrest a type error
        contains = kwargs.pop('contains', None)
        clean = kwargs.pop('clean', None)
        if not contains and not clean:
            self.assertTrue(0, "check_plenary_contents called without "
                            "contains or clean")

        self.check_plenary_exists(*path)
        plenary = self.plenary_name(*path)
        with open(plenary) as f:
            contents = f.read()

        if isinstance(contains, list):
            for item in contains:
                self.matchoutput(contents, item, "read %s" % plenary)
        elif contains:
            self.matchoutput(contents, contains, "read %s" % plenary)

        if isinstance(clean, list):
            for item in clean:
                self.matchclean(contents, item, "read %s" % plenary)
        elif clean:
            self.matchclean(contents, clean, "read %s" % plenary)

    def find_template(self, *template, **args):
        """ Figure out the extension of an existing template """
        if args.get("sandbox", None):
            dir = os.path.join(self.sandboxdir, args.get("sandbox"))
        elif args.get("domain", None):
            dir = os.path.join(self.config.get("broker", "domainsdir"),
                               args.get("domain"))
        else:
            self.assertTrue(0, "find_template() called without domain or sandbox")

        base = os.path.join(dir, *template)

        for extension in [".tpl", ".pan"]:
            if os.path.exists(base + extension):
                return base + extension
        self.assertTrue(0, "template %s does not exist with any extension" % base)

    def build_profile_name(self, *template, **args):
        base = os.path.join(self.config.get("broker", "cfgdir"),
                            "domains", args.get("domain"),
                            "profiles", *template)
        return base + self.template_extension

    def tail_file(self, file):
        """
        Get last line from given file
        Assert that line is not empty
        :param file:
        :return:
        """
        with open(file, "r") as f:
            for line in f:
                pass
        self.assertTrue(bool(line.strip()), "Last line is empty")
        return line

    msversion_dev_re = re.compile(r'WARNING:msversion:Loading \S* from dev\n')

    def runcommand(self, command, auth=True, **kwargs):
        aq = os.path.join(self.config.get("broker", "srcdir"), "bin", "aq.py")
        if auth:
            port = self.config.get("broker", "kncport")
        else:
            port = self.config.get("broker", "openport")
        if isinstance(command, list):
            args = [str(cmd) for cmd in command]
        else:
            args = [command]
        args.insert(0, sys.executable)
        args.insert(1, aq)
        if "--aqport" not in args:
            args.append("--aqport")
            args.append(port)
        if auth:
            args.append("--aqservice")
            args.append(self.config.get("broker", "service"))
        else:
            args.append("--noauth")
        if "env" in kwargs:
            # Make sure that kerberos tickets are still present if the
            # environment is being overridden...
            env = {}
            for (key, value) in kwargs["env"].items():
                env[key] = value
            for (key, value) in os.environ.items():
                if key.find("KRB") == 0 and key not in env:
                    env[key] = value
            if 'USER' not in env:
                env['USER'] = os.environ.get('USER', '')
            kwargs["env"] = env
        p = Popen(args, stdout=PIPE, stderr=PIPE, **kwargs)
        (out, err) = p.communicate()
        # Strip any msversion dev warnings out of STDERR
        err = self.msversion_dev_re.sub('', err)
        # Lock messages are pretty common...
        err = err.replace('Client status messages disabled, '
                          'retries exceeded.\n', '')
        return (p, out, err)

    def successtest(self, command, **kwargs):
        (p, out, err) = self.runcommand(command, **kwargs)
        self.assertEqual(p.returncode, 0,
                         "Non-zero return code for %s, "
                         "STDOUT:\n@@@\n'%s'\n@@@\n"
                         "STDERR:\n@@@\n'%s'\n@@@\n"
                         % (command, out, err))
        return (out, err)

    def statustest(self, command, **kwargs):
        (out, err) = self.successtest(command, **kwargs)
        self.assertEmptyOut(out, command)
        return err

    def failuretest(self, command, returncode, **kwargs):
        (p, out, err) = self.runcommand(command, **kwargs)
        self.assertEqual(p.returncode, returncode,
                         "Non-%s return code %s for %s, "
                         "STDOUT:\n@@@\n'%s'\n@@@\n"
                         "STDERR:\n@@@\n'%s'\n@@@\n"
                         % (returncode, p.returncode, command, out, err))
        return (out, err)

    def assertEmptyStream(self, name, contents, command):
        self.assertEqual(contents, "",
                         "%s for %s was not empty:\n@@@\n'%s'\n@@@\n"
                         % (name, command, contents))

    def assertEmptyErr(self, contents, command):
        self.assertEmptyStream("STDERR", contents, command)

    def assertEmptyOut(self, contents, command):
        self.assertEmptyStream("STDOUT", contents, command)

    def commandtest(self, command, **kwargs):
        (p, out, err) = self.runcommand(command, **kwargs)
        self.assertEmptyErr(err, command)
        self.assertEqual(p.returncode, 0,
                         "Non-zero return code for %s, "
                         "STDOUT:\n@@@\n'%s'\n@@@\n"
                         % (command, out))
        return out

    def noouttest(self, command, **kwargs):
        out = self.commandtest(command, **kwargs)
        self.assertEqual(out, "",
                         "STDOUT for %s was not empty:\n@@@\n'%s'\n@@@\n"
                         % (command, out))

    def ignoreoutputtest(self, command, **kwargs):
        (p, out, err) = self.runcommand(command, **kwargs)
        # Ignore out/err unless we get a non-zero return code, then log it.
        self.assertEqual(p.returncode, 0,
                         "Non-zero return code for %s, "
                         "STDOUT:\n@@@\n'%s'\n@@@\n"
                         "STDERR:\n@@@\n'%s'\n@@@\n"
                         % (command, out, err))
        return

    # Right now, commands are not implemented consistently.  When that is
    # addressed, this unit test should be updated.
    def notfoundtest(self, command, **kwargs):
        (p, out, err) = self.runcommand(command, **kwargs)
        if p.returncode == 0:
            self.assertEqual(err, "",
                             "STDERR for %s was not empty:\n@@@\n'%s'\n@@@\n" %
                             (command, err))
            self.assertEqual(out, "",
                             "STDOUT for %s was not empty:\n@@@\n'%s'\n@@@\n" %
                             (command, out))
        else:
            self.assertEqual(p.returncode, 4,
                             "Return code for %s was %d instead of %d"
                             "\nSTDOUT:\n@@@\n'%s'\n@@@"
                             "\nSTDERR:\n@@@\n'%s'\n@@@" %
                             (command, p.returncode, 4, out, err))
            self.assertEqual(out, "",
                             "STDOUT for %s was not empty:\n@@@\n'%s'\n@@@\n" %
                             (command, out))
            self.assertTrue(err.find("Not Found") >= 0,
                            "STDERR for %s did not include Not Found:"
                            "\n@@@\n'%s'\n@@@\n" %
                            (command, err))
        return err

    def badrequesttest(self, command, ignoreout=False, **kwargs):
        (p, out, err) = self.runcommand(command, **kwargs)
        self.assertEqual(p.returncode, 4,
                         "Return code for %s was %d instead of %d"
                         "\nSTDOUT:\n@@@\n'%s'\n@@@"
                         "\nSTDERR:\n@@@\n'%s'\n@@@" %
                         (command, p.returncode, 4, out, err))
        self.assertTrue(err.find("Bad Request") >= 0,
                        "STDERR for %s did not include Bad Request:"
                        "\n@@@\n'%s'\n@@@\n" %
                        (command, err))
        if not ignoreout and "--debug" not in command:
            self.assertEqual(out, "",
                             "STDOUT for %s was not empty:\n@@@\n'%s'\n@@@\n" %
                             (command, out))
        return err

    def unauthorizedtest(self, command, auth=False, msgcheck=True, **kwargs):
        (p, out, err) = self.runcommand(command, auth=auth, **kwargs)
        self.assertEqual(p.returncode, 4,
                         "Return code for %s was %d instead of %d"
                         "\nSTDOUT:\n@@@\n'%s'\n@@@"
                         "\nSTDERR:\n@@@\n'%s'\n@@@" %
                         (command, p.returncode, 4, out, err))
        self.assertEqual(out, "",
                         "STDOUT for %s was not empty:\n@@@\n'%s'\n@@@\n" %
                         (command, out))
        self.assertTrue(err.find("Unauthorized:") >= 0,
                        "STDERR for %s did not include Unauthorized:"
                        "\n@@@\n'%s'\n@@@\n" %
                        (command, err))
        if msgcheck:
            self.searchoutput(err, r"Unauthorized (anonymous )?access attempt",
                              command)
        return err

    def internalerrortest(self, command, **kwargs):
        (p, out, err) = self.runcommand(command, **kwargs)
        self.assertEqual(p.returncode, 5,
                         "Return code for %s was %d instead of %d"
                         "\nSTDOUT:\n@@@\n'%s'\n@@@"
                         "\nSTDERR:\n@@@\n'%s'\n@@@" %
                         (command, p.returncode, 5, out, err))
        self.assertEqual(out, "",
                         "STDOUT for %s was not empty:\n@@@\n'%s'\n@@@\n" %
                         (command, out))
        self.assertEqual(err.find("Internal Server Error"), 0,
                         "STDERR for %s did not start with "
                         "Internal Server Error:\n@@@\n'%s'\n@@@\n" %
                         (command, err))
        return err

    def unimplementederrortest(self, command, **kwargs):
        (p, out, err) = self.runcommand(command, **kwargs)
        self.assertEqual(p.returncode, 5,
                         "Return code for %s was %d instead of %d"
                         "\nSTDOUT:\n@@@\n'%s'\n@@@"
                         "\nSTDERR:\n@@@\n'%s'\n@@@" %
                         (command, p.returncode, 5, out, err))
        self.assertEqual(out, "",
                         "STDOUT for %s was not empty:\n@@@\n'%s'\n@@@\n" %
                         (command, out))
        self.assertEqual(err.find("Not Implemented"), 0,
                         "STDERR for %s did not start with "
                         "Not Implemented:\n@@@\n'%s'\n@@@\n" %
                         (command, err))
        return err

    def deprecatednotimplementederrortest(self, command, **kwargs):
        (p, out, err) = self.runcommand(command, **kwargs)
        err_splited = err.splitlines()
        self.assertEqual(p.returncode, 5,
                         "Return code for %s was %d instead of %d"
                         "\nSTDOUT:\n@@@\n'%s'\n@@@"
                         "\nSTDERR:\n@@@\n'%s'\n@@@" %
                         (command, p.returncode, 5, out, err))
        self.assertEqual(out, "",
                         "STDOUT for %s was not empty:\n@@@\n'%s'\n@@@\n" %
                         (command, out))
        self.assertTrue(
            "Command {} is deprecated".format(command[0]) in err_splited[0],
            "'Command {} is deprecated' not in {}".format(command[0],
                                                          err_splited[0]))
        self.assertTrue(err_splited[1].startswith("Not Implemented"),
                        "STDERR 2nd line for %s did not start with "
                        "Not Implemented:\n@@@\n'%s'\n@@@\n" %
                        (command, err))
        return err

    # Test for conflicting or invalid aq client options.
    def badoptiontest(self, command, exit_code=2, **kwargs):
        (p, out, err) = self.runcommand(command, **kwargs)
        self.assertEqual(p.returncode, exit_code,
                         "Return code for %s was %d instead of %d"
                         "\nSTDOUT:\n@@@\n'%s'\n@@@"
                         "\nSTDERR:\n@@@\n'%s'\n@@@" %
                         (command, p.returncode, exit_code, out, err))
        self.assertEqual(out, "",
                         "STDOUT for %s was not empty:\n@@@\n'%s'\n@@@\n" %
                         (command, out))
        return err

    def justificationmissingtest(self, command, **kwargs):
        out = self.unauthorizedtest(command, **kwargs)
        self.matchoutput(out, CM_JUSTIFICATION, command)

    def reasonmissingtest(self, command, **kwargs):
        out = self.unauthorizedtest(command, **kwargs)
        self.matchoutput(out, CM_EMERGENCY, command)

    def justificationformattest(self, command, **kwargs):
        out = self.unauthorizedtest(command, **kwargs)
        self.matchoutput(out, CM_FORMAT, command)

    def emergencynojustification(self, command, **kwargs):
        (out, err) = self.successtest(command, **kwargs)
        self.matchoutput(err, CM_EDM, command)

    def justificationmissingtest_warn(self, command, **kwargs):
        (out, err) = self.successtest(command, **kwargs)
        self.matchoutput(err, CM_JUSTIFICATION, command)
        self.matchoutput(err, CM_WARN, command)

    def partialerrortest(self, command, **kwargs):
        # Currently these two cases behave the same way - same exit code
        # and behavior.
        return self.badoptiontest(command, **kwargs)

    def matchoutput(self, out, s, command):
        self.assertTrue(out.find(s) >= 0,
                        "output for %s did not include '%s':\n@@@\n'%s'\n@@@\n" %
                        (command, s, out))

    def matchclean(self, out, s, command):
        self.assertTrue(out.find(s) < 0,
                        "output for %s includes '%s':\n@@@\n'%s'\n@@@\n" %
                        (command, s, out))

    def searchoutput(self, out, r, command):
        if isinstance(r, string_types):
            m = re.search(r, out, re.MULTILINE)
        else:
            m = re.search(r, out)
        self.assertTrue(m,
                        "output for %s did not match '%s':\n@@@\n'%s'\n@@@\n"
                        % (command, r, out))
        return m

    def searchclean(self, out, r, command):
        if isinstance(r, string_types):
            m = re.search(r, out, re.MULTILINE)
        else:
            m = re.search(r, out)
        self.assertFalse(m,
                         "output for %s matches '%s':\n@@@\n'%s'\n@@@\n" %
                         (command, r, out))

    def output_equals(self, out, s, command):
        # Check if the output is the string 's'. Leading and trailing
        # whitespace, as well as any common indentation, is ignored.
        out = dedent(out).strip()
        s = dedent(s).strip()
        # Calculate the diff only if we have to...
        if out != s:
            diff = unified_diff(s.splitlines(),
                                out.splitlines(),
                                lineterm="",
                                fromfile="Expected output",
                                tofile="Command output")
            self.assertEqual(out, s,
                             "output for %s differs:\n%s"
                             % (command, "\n".join(diff)))

    def output_unordered_equals(self, out, sl, command, match_all=True):
        out = dedent(out).strip()

        unmatched = []
        for s in sl:
            s = dedent(s).strip()
            m = re.search('^{}$'.format(re.escape(s)), out, re.MULTILINE)
            if not m:
                unmatched.append(s)
            else:
                out = out[:max(0, m.start() - 1)] + out[m.end():]

        # Clean-up leftover output
        out = out.strip()

        self.assertFalse(unmatched,
                         'Unmatched blocks for {}:\n{}{}'.format(
                             command, '\n--\n'.join(unmatched),
                             '\n>>> Leftover output:\n{}'.format(out)
                             if bool(out) else ''))

        if match_all:
            # Check that the output is now empty
            self.assertFalse(bool(out),
                             'Output for {} does not perfectly match the '
                             'expected output; in excess:\n{}'.format(
                                 command, out))

    def output_unordered_clean(self, out, sl, command):
        out = dedent(out).strip()
        matched = []
        for s in sl:
            s = dedent(s).strip()
            m = re.search('^{}$'.format(re.escape(s)), out, re.MULTILINE)
            if m:
                matched.append(s)
                out = out[:max(0, m.start() - 1)] + out[m.end():]

        # Clean-up leftover output
        out = out.strip()

        self.assertFalse(matched,
                         'Matched blocks for {}:\n{}{}'.format(
                             command, '\n--\n'.join(matched),
                             '\n>>> Leftover output:\n{}'.format(out)
                             if bool(out) else ''))

    def parse_proto_msg(self, listclass, attr, msg, expect=None):
        protolist = listclass()
        protolist.ParseFromString(msg)
        received = len(getattr(protolist, attr))
        if expect is None:
            self.assertTrue(received > 0,
                            "No %s listed in %s protobuf message\n" %
                            (attr, listclass))
        else:
            self.assertEqual(received, expect,
                             "%d %s expected, got %d\n" %
                             (expect, attr, received))
        return getattr(protolist, attr)

    def protobuftest(self, command, expect=None, **kwargs):
        self.assertTrue(isinstance(command, list),
                        "protobuftest() needs the command passed as a list")

        # Extract the command name
        cmd_name = command[0]
        for part in command[1:]:
            if part.startswith("-"):
                break
            cmd_name += "_" + part

        nodelist = self.input_xml.xpath("/commandline/command[@name='%s']" %
                                        cmd_name)
        self.assertTrue(nodelist and len(nodelist) == 1,
                        "Command '%s' was not found in input.xml" % cmd_name)
        cmd_node = nodelist[0]
        msg_node = None
        for fmt_node in cmd_node.getiterator("format"):
            if fmt_node.attrib["name"] != "proto":
                continue
            msg_node = fmt_node.find("message_class")
            break

        self.assertTrue(msg_node is not None,
                        "Command %s does not have protobuf support" % cmd_name)

        module_name = msg_node.attrib["module"]
        cls_name = msg_node.attrib["name"]

        msg_cls = getattr(self.protocols[module_name], cls_name)
        field = msg_cls.DESCRIPTOR.fields[0]

        out = self.commandtest(command, **kwargs)
        return self.parse_proto_msg(msg_cls, field.name, out, expect=expect)

    @classmethod
    def gitenv(cls, env=None):
        """Configure a known sanitised environment"""
        # The "publish" test abuses gitenv(), and it needs the Python interpreter
        # in the path, because it runs the template unit tests which in turn
        # call the aq command

        if env:
            newenv = env.copy()
        else:
            newenv = {}

        if "USER" not in newenv:
            newenv["USER"] = os.environ.get('USER', '')

        if "PATH" in newenv:
            path = env["PATH"].split(":")
        else:
            # Some reasonable defaults...
            path = ["/bin", "/usr/bin"]

        # The 'aq' command need to run some external tools, so make sure those
        # will be found
        for exe in [sys.executable,
                    cls.config.lookup_tool("git"),
                    cls.config.lookup_tool("knc")]:
            if exe[0] != "/":
                continue

            dir = os.path.dirname(exe)
            if dir not in path:
                path.insert(0, dir)

        newenv["PATH"] = ":".join(path)
        return newenv

    def gitcommand_raw(self, command, **kwargs):
        if isinstance(command, list):
            args = command[:]
        else:
            args = [command]
        args.insert(0, self.config.lookup_tool("git"))
        env = self.gitenv(kwargs.pop("env", None))
        p = Popen(args, stdout=PIPE, stderr=PIPE, env=env, **kwargs)
        return p

    def gitcommand(self, command, **kwargs):
        p = self.gitcommand_raw(command, **kwargs)
        # Ignore out/err unless we get a non-zero return code, then log it.
        (out, err) = p.communicate()
        self.assertEqual(p.returncode, 0,
                         "Non-zero return code for %s, "
                         "STDOUT:\n@@@\n'%s'\n@@@\n"
                         "STDERR:\n@@@\n'%s'\n@@@\n"
                         % (command, out, err))
        return (out, err)

    def gitcommand_expectfailure(self, command, **kwargs):
        p = self.gitcommand_raw(command, **kwargs)
        # Ignore out/err unless we get a non-zero return code, then log it.
        (out, err) = p.communicate()
        self.assertNotEqual(p.returncode, 0,
                            "Zero return code for %s, "
                            "STDOUT:\n@@@\n'%s'\n@@@\n"
                            "STDERR:\n@@@\n'%s'\n@@@\n"
                            % (command, out, err))
        return (out, err)

    def check_git_merge_health(self, repo):
        command = "merge HEAD"
        self.gitcommand(command.split(" "), cwd=repo)
        return

    def grepcommand(self, command, **kwargs):
        if isinstance(command, list):
            args = command[:]
        else:
            args = [command]
        args.insert(0, self.config.lookup_tool("grep"))
        p = Popen(args, stdout=PIPE, stderr=PIPE, **kwargs)
        (out, err) = p.communicate()
        # Ignore out/err unless we get a non-zero return code, then log it.
        if p.returncode == 0:
            return out.splitlines()
        if p.returncode == 1:
            return []
        self.fail("Error return code for %s, "
                  "STDOUT:\n@@@\n'%s'\n@@@\nSTDERR:\n@@@\n'%s'\n@@@\n"
                  % (command, out, err))

    def findcommand(self, command, **kwargs):
        if isinstance(command, list):
            args = command[:]
        else:
            args = [command]
        args.insert(0, self.config.lookup_tool("find"))
        p = Popen(args, stdout=PIPE, stderr=PIPE, **kwargs)
        (out, err) = p.communicate()
        # Ignore out/err unless we get a non-zero return code, then log it.
        if p.returncode == 0:
            return out.splitlines()
        self.fail("Error return code for %s, "
                  "STDOUT:\n@@@\n'%s'\n@@@\nSTDERR:\n@@@\n'%s'\n@@@\n"
                  % (command, out, err))

    def writescratch(self, filename, contents, raw=False):
        scratchfile = os.path.join(self.scratchdir, filename)
        if raw:
            mode = "wb"
        else:
            mode = "w"
        with open(scratchfile, mode) as f:
            f.write(contents)
        return scratchfile

    def readscratch(self, filename, raw=False):
        scratchfile = os.path.join(self.scratchdir, filename)
        if raw:
            mode = "rb"
        else:
            mode = "r"
        with open(scratchfile, mode) as f:
            contents = f.read()
        return contents

    def dsdb_expect(self, command, fail=False, errstr=""):
        if fail:
            filename = DSDB_EXPECT_FAILURE_FILE
        else:
            filename = DSDB_EXPECT_SUCCESS_FILE

        expected_name = os.path.join(self.dsdb_coverage_dir, filename)
        with open(expected_name, "a") as fp:
            if isinstance(command, list):
                fp.write(" ".join(str(cmd) for cmd in command))
            else:
                fp.write(str(command))
            fp.write("\n")
        if fail and errstr:
            errfile = DSDB_EXPECT_FAILURE_ERROR
            expected_name = os.path.join(self.dsdb_coverage_dir, errfile)
            with open(expected_name, "a") as fp:
                fp.write(errstr)
                fp.write("\n")

    def dsdb_expect_add(self, hostname, ip, interface=None, mac=None,
                        primary=None, comments=None, fail=False):
        command = ["add_host", "-host_name", hostname,
                   "-ip_address", str(ip), "-status", "aq"]
        if interface:
            command.extend(["-interface_name",
                            str(interface).replace('/', '_')])
        if mac:
            command.extend(["-ethernet_address", str(mac)])
        if primary:
            command.extend(["-primary_host_name", primary])
        else:
            command.extend(["-manager_grn",
                           self.config.get('dsdb', 'manager_grn')])
        if comments:
            command.extend(["-comments", comments])

        self.dsdb_expect(" ".join(command), fail=fail)

    def dsdb_expect_delete(self, ip, fail=False):
        self.dsdb_expect("delete_host -ip_address %s" % ip, fail=fail)

    def dsdb_expect_update(self, fqdn, iface=None, ip=None, mac=None,
                           comments=None, fail=False):
        command = ["update_aqd_host", "-host_name", fqdn]
        if iface:
            command.extend(["-interface_name", iface])
        if ip:
            command.extend(["-ip_address", str(ip)])
        if mac:
            command.extend(["-ethernet_address", str(mac)])
        if comments is not None:
            command.extend(["-comments", comments])
        self.dsdb_expect(" ".join(command), fail=fail)

    def dsdb_expect_rename(self, fqdn, new_fqdn=None, iface=None,
                           new_iface=None, fail=False):
        command = ["update_aqd_host", "-host_name", fqdn]
        if new_fqdn:
            command.extend(["-new_host_name", new_fqdn])
        if iface:
            command.extend(["-interface_name", iface])
        if new_iface:
            command.extend(["-new_interface_name", new_iface])
        self.dsdb_expect(" ".join(command), fail=fail)

    def dsdb_expect_add_campus(self, campus, comments=None, fail=False,
                               errstr=""):
        command = ["add_campus_aq", "-campus_name", campus]
        if comments:
            command.extend(["-comments", comments])
        self.dsdb_expect(" ".join(command), fail=fail, errstr=errstr)

    def dsdb_expect_del_campus(self, campus, fail=False, errstr=""):
        command = ["delete_campus_aq", "-campus", campus]
        self.dsdb_expect(" ".join(command), fail=fail, errstr=errstr)

    def dsdb_expect_add_campus_building(self, campus, building, fail=False,
                                        errstr=""):
        command = ["add_campus_building_aq", "-campus_name", campus,
                   "-building_name", building]
        self.dsdb_expect(" ".join(command), fail=fail, errstr=errstr)

    def dsdb_expect_del_campus_building(self, campus, building, fail=False,
                                        errstr=""):
        command = ["delete_campus_building_aq", "-campus_name", campus,
                   "-building_name", building]
        self.dsdb_expect(" ".join(command), fail=fail, errstr=errstr)

    def dsdb_verify(self, empty=False):
        issued_name = os.path.join(self.dsdb_coverage_dir, DSDB_ISSUED_CMDS_FILE)

        expected = {}
        for filename in [DSDB_EXPECT_SUCCESS_FILE, DSDB_EXPECT_FAILURE_FILE]:
            expected_name = os.path.join(self.dsdb_coverage_dir, filename)
            try:
                with open(expected_name, "r") as fp:
                    for line in fp:
                        expected[line.rstrip("\n")] = True
            except IOError:
                pass

        # This is likely a logic error in the test
        if not expected and not empty:
            self.fail("dsdb_verify() called when no DSDB commands were "
                      "expected?!?")

        issued = {}
        try:
            with open(issued_name, "r") as fp:
                for line in fp:
                    issued[line.rstrip("\n")] = True
        except IOError:
            pass

        errors = []
        for cmd, dummy in expected.items():
            if cmd not in issued:
                errors.append("'%s'" % cmd)
        # Unexpected DSDB commands are caught by the fake_dsdb script

        if errors:
            self.fail("The following expected DSDB commands were not called:"
                      "\n@@@\n%s\n@@@\n" % "\n".join(errors))

    def verify_buildfiles(self, domain, object,
                          want_exist=True, command='manage',
                          xml=None, json=None):
        buildfiles = []
        exemptfiles = []

        qdir = self.config.get('broker', 'quattordir')
        domaindir = os.path.join(qdir, 'build', domain)

        buildfiles.append(os.path.join(domaindir, object + '.dep'))
        buildfiles.append(self.build_profile_name(object, domain=domain))

        if xml is None:
            xml = self.xml_default
        if json is None:
            json = self.json_default

        if xml:
            buildfiles.append(os.path.join(domaindir, object + self.xml_suffix))
        else:
            exemptfiles.append(os.path.join(domaindir, object + self.xml_suffix))

        if json:
            buildfiles.append(os.path.join(domaindir, object + self.json_suffix))
        else:
            exemptfiles.append(os.path.join(domaindir, object + self.json_suffix))

        for f in buildfiles:
            if want_exist:
                self.assertTrue(os.path.exists(f),
                                "Expecting %s to exist before running %s." %
                                (f, command))
            else:
                self.assertFalse(os.path.exists(f),
                                 "Not expecting %s to exist after running %s." %
                                 (f, command))

        for f in exemptfiles:
            self.assertFalse(os.path.exists(f),
                             "Not expecting %s to exist after running %s." %
                             (f, command))

    def demote_current_user(self, role="nobody"):
        command = ["permission", "--role", role,
                   "--principal", "%s@%s" % (self.user, self.realm)] + self.valid_just_sn
        self.noouttest(command)

    def promote_current_user(self):
        srcdir = self.config.get("broker", "srcdir")
        set_role = os.path.join(srcdir, "sbin", "aqdb_set_role.py")
        env = os.environ.copy()
        env['AQDCONF'] = self.config.baseconfig
        p = Popen([set_role, '--role', 'aqd_admin'],
                  stdout=PIPE, stderr=PIPE, env=env)
        (out, err) = p.communicate()
        self.assertEqual(p.returncode, 0,
                         "Failed to restore admin privs '%s', '%s'." %
                         (out, err))

    def assertTruedeprecation(self, depr_str, testfunc):
        with open(self.config.get("broker", "logfile"), "r") as logfile:
            # Let's seek to the end of it, matching only against the relevant part.
            logfile.seek(0, 2)
            # Now call the function that should generate the deprecation warning
            testfunc()
            self.assertTrue(elem for elem in logfile if depr_str in elem)

    @staticmethod
    def dynname(ip, domain="aqd-unittest.ms.com"):
        return "dynamic-%s.%s" % (str(ip).replace(".", "-"), domain)


import pytest
from App_Code import create_app, db

app = create_app()

@pytest.fixture(scope='module')
def client():
    app.config['TESTING'] = True

    with app.test_client() as client:
        yield client

# Test case for database connection
def test_database_connection():
    with app.app_context():
        try:
            db.engine.connect()
            assert True  # Successfully connected to the database
        except Exception as e:
            assert False, f"Database connection test failed: {e}"


import time, os
from flask import Flask, json
from flask_cors import CORS
import yfinance as yf
import numpy as np
from datetime import datetime as dt

from .query import api_request, search_yahoo_tickers, FuncException, FieldException
from .utils import format_ticker_response_json
from .errors import ERROR_DICT, Error

app = Flask(__name__, instance_relative_config=True)
app.config.from_mapping(
    SECRET_KEY='dev',
    DATABASE=os.path.join(app.instance_path, 'index.sqlite')
)
CORS(app)

try:
    os.makedirs(app.instance_path)
except OSError:
    pass

from . import db
db.init_app(app)

@app.route('/time')
def get_current_time():
    return {'time': time.time()}

@app.route('/ticker_query/<symbol>', methods=('GET',))
def get_ticker_list(symbol):
    try:
        res = api_request('SYMBOL_SEARCH', keywords=symbol)
        status = 200

        print(res)

        if res.get('bestMatches') is not None:
            res = format_ticker_response_json(res['bestMatches'])
        else:
            res = {'error': Error.FORMAT_ERROR.value, 'message': ERROR_DICT[Error.FORMAT_ERROR]}
            status = 500

        return json_response(res, status=status)
    except FuncException:
        return json_response({'error': Error.REQUEST_ERROR.value, 'message': ERROR_DICT[Error.REQUEST_ERROR]}, status=400)
    except FieldException:
        return json_response({'error': Error.REQUEST_ERROR.value, 'message': ERROR_DICT[Error.REQUEST_ERROR]}, status=400)
    except Exception:
        return json_response({'error': Error.SERVER_ERROR.value, 'message': ERROR_DICT[Error.SERVER_ERROR]}, status=500)

@app.route('/ticker_query_yahoo/<symbol>', methods=('GET',))
def get_ticker_list_yahoo(symbol):
    try:
        res = search_yahoo_tickers(symbol)
        status = 200

        if res.get('data') is not None:
            if res['data'].get('items') is not None:
                res = format_ticker_response_json(res['data']['items'])
            else:
                res = {'error': Error.FORMAT_ERROR.value, 'message': ERROR_DICT[Error.FORMAT_ERROR]}
        else:
            res = {'error': Error.FORMAT_ERROR.value, 'message': ERROR_DICT[Error.FORMAT_ERROR]}

        return json_response(res)
    except Exception:
        return json_response({'error' : Error.SERVER_ERROR.value, 'message': ERROR_DICT[Error.SERVER_ERROR]}, status=500)

@app.route('/ticker_history_yahoo/<symbol>', methods=('GET',))
def get_ticker_history_yahoo(symbol):
    try:
        res = yf.Ticker(symbol)
        history = res.history(period='max').reset_index().to_dict()
        info = res.info

        dates = np.array(list(history['Date'].values()), dtype=dt)

        format_date = lambda date : dt.strftime(date, '%d-%b-%Y')
        format_dates = np.vectorize(format_date)

        history['Date'] = list(format_dates(dates))

        res = {
            'history': history,
            'info': info
        }

        status = 200

        return json_response(res)
    except Exception as e:
        print(e)
        return json_response({'error': Error.SERVER_ERROR.value, 'message': ERROR_DICT[Error.SERVER_ERROR]}, status=500)

def json_response(payload, status=200):
    return (json.dumps(payload), status, {'content-type': 'application/json'})


from endpoints.crud import AuthUser, Token
from flask import Blueprint, make_response, request

auth = Blueprint(
    "authentication",
    __name__,
)

@auth.route("/registration", methods=["POST"])
async def registration():
    user = AuthUser()
    registration_res = await user.create_new_user(request.get_json())
    return make_response(registration_res)

@auth.route("/login", methods=["POST"])
async def login():
    user = AuthUser()
    login_res = await user.login_user(request.get_json())
    return make_response(login_res)

@auth.route("/token/refresh", methods=["POST"])
async def refresh_access_token():
    token = Token()
    new_access_token = await token.update_access_token(request.get_json())
    return make_response(new_access_token)


import sys

target=list(map(str,sys.stdin.readline().strip("\n"))) # abcd 커서가 존재할 수 있는 위치는 5곳
target2=[]

n=int(sys.stdin.readline())

for i in range(n):
    command=list(map(str,sys.stdin.readline().strip("\n")))

    if command[0]=='L': # 왼쪽으로 1칸 이동
        if len(target)==0:
            continue
        target2.append(target.pop()) # target2에 target의 마지막 원소 삽입

    elif command[0]=='D': # 오른쪽으로 1칸 이동
        if len(target2)==0:
            continue
        target.append(target2.pop()) # target에 target2의 마지막 원소 삽입

    elif command[0]=='B': # 커서 왼쪽의 문자 삭제
        if len(target)==0:
            continue
        target.pop()

    else: # 삽입
        target.append(command[2])

target.extend(reversed(target2))

print(''.join(target))

#----------------------------------------------------------------------------------------

from collections import deque

dequeue=deque(input())
queue=deque([])

n=int(input())

for i in range(n):
    command=list(input().split())

    if command[0]=='P': # 추가
        dequeue.append(command[1])

    elif command[0]=='B': # 삭제
        if dequeue:
            dequeue.pop()

    elif command[0]=='L': # << 이동
        if dequeue:
            queue.appendleft(dequeue.pop())

    elif command[0]=='D':
        if queue:
            dequeue.append(queue.popleft())

result=dequeue+queue

print(''.join(result))


"""Example of Cross Validation and Grid Search for Model Hyperparameters"""
import pyspark
import numpy as np
import argparse

from pyspark.ml.regression import RandomForestRegressor
from pyspark.ml.evaluation import RegressionEvaluator
from pyspark.ml.tuning import ParamGridBuilder, TrainValidationSplit, CrossValidator

from pyspark.sql import SparkSession
from pyspark.sql.functions import udf
from pyspark.sql.types import *

#initialize spark session
spark = SparkSession\
        .builder\
        .appName("Test")\
        .config('spark.sql.warehouse.dir', 'file:///C:/')\
        .getOrCreate()

sc = spark.sparkContext

def main():
    parser = argparse.ArgumentParser(description='Pyspark Training')
    parser.add_argument('--data', type=str,
        default="../../../data/sample_linear_regression_data.txt",
        help='Data location.')
    parser.add_argument('--cross_val', type=bool, default=False, help='whether to use cross_validation')
    args = parser.parse_args()

    data = spark.read.format("libsvm").load(args.data)

    # Split the data into training and test sets (30% held out for testing)
    (train, test) = data.randomSplit([0.7, 0.3])

    # Train a RandomForest model.
    rf = RandomForestRegressor()

    # Create a grid of hyperparameters. Each combination will be tested.
    paramGrid = ParamGridBuilder()\
        .addGrid(rf.numTrees, [2, 25]) \
        .addGrid(rf.maxDepth, [2, 6])\
        .addGrid(rf.maxBins, [15, 30])\
        .build()

    if args.cross_val:
        # Run five-fold cross validation to find best hyperparamters.
        crossval = CrossValidator(estimator=rf,
                          estimatorParamMaps=paramGrid,
                          evaluator=RegressionEvaluator(labelCol="label", predictionCol="prediction", metricName="rmse"),
                          numFolds=5)  # use 3+ folds in practice

        model = crossval.fit(train)
    else:
        # Grid search for best hyperparameters with a single validation set.
        tvs = TrainValidationSplit(estimator=rf,
                                   estimatorParamMaps=paramGrid,
                                   evaluator=RegressionEvaluator(labelCol="label", predictionCol="prediction", metricName="rmse"),
                                   # 80% of the data will be used for training, 20% for validation.
                                   trainRatio=0.8)

        # Run TrainValidationSplit, and choose the best set of parameters.
        model = tvs.fit(train)

    # Make predictions.
    predictions = model.transform(test)

    # Select (prediction, true label) and compute test error
    evaluator = RegressionEvaluator(
        labelCol="label", predictionCol="prediction", metricName="rmse"
    )

    rmse = evaluator.evaluate(predictions)
    print("Root Mean Squared Error (RMSE) on test data = %g" % rmse)

if __name__=="__main__":
    main()


import pygame
import math

class CannonBall(pygame.sprite.Sprite):
    """
    The CannonBall class inherits from the pygame.sprite.Sprite class.
    This class keeps track over all the cannon ball sprite objects in the game.

    It requires 8 parameters:
    The X position, The Y position
    The X veloity, The Y velocity
    gravity and friction
    cannon_ball and cannon_ball_group
    """
    def __init__(self, pos_x, pos_y, vel_x, vel_y, gravity, friction, cannon_ball, cannon_ball_group):
        super().__init__()
        self.image = cannon_ball.copy()
        self.rect = self.image.get_rect(center=(500, 680))
        self.rect.center = [pos_x, pos_y]
        self.vel_x = vel_x
        self.vel_y = vel_y
        self.gravity = gravity
        self.friction = friction
        cannon_ball_group.add(self)

    def update(self, GAME_SCREEN, cannon_wheel, rotated_cannon, rotated_cannon_rect):
        self.rect.x += self.vel_x
        self.rect.y += self.vel_y
        self.vel_y += self.gravity

        # Hard Coding the Collision with the wall
        if self.rect.x > 920 and self.rect.x < 955 and self.rect.y > 480:
            self.rect.x = 920
            self.vel_x = -self.vel_x / 2

        if self.rect.y >= 700:
            self.rect.y = 700

            #Setting up bounce mechanic
            if self.vel_y > 2:
                self.vel_y = -self.vel_y / 2
            else:
                self.vel_y = 0

            # Losing horizontal velocity due to friction
            if self.vel_x >= 0:
                self.vel_x -= self.friction
            elif self.vel_x < 0:
                self.vel_x += self.friction

        # Destroys the ball after it stops moving
        if self.vel_x < 0.5 and self.vel_x > -0.5 and self.vel_y > -0.5 and self.vel_y < 0.5:
            self.vel_y = 0
            self.vel_x = 0
            self.kill()

        GAME_SCREEN.blit(self.image, (self.rect.x, self.rect.y))
        GAME_SCREEN.blit(rotated_cannon, rotated_cannon_rect.topleft)
        GAME_SCREEN.blit(cannon_wheel, pygame.Rect(65, 640, 10, 10))

    def returnDistance(self):
        return self.rect.x
    def returnVelocityX(self):
        return self.vel_x
    def returnVelocityY(self):
        return self.vel_y

def calculateVector(x, y):
    return math.sqrt(x ** 2 + y ** 2)

def calculateAngle(mouseX, mouseY, cannonX, cannonY):
    return math.atan2(mouseX - cannonX, mouseY - cannonY)

def drawBackground(GAME_SCREEN, background, cannon_wheel, wall, render_text, render_instructions, render_distance, display_distance, render_vel_x, render_vel_y, display_vel_x, display_vel_y, rotated_cannon, rotated_cannon_rect):
    # Alternate Background Settings
    # GAME_SCREEN.fill(SKY_BLUE)
    # pygame.draw.rect(GAME_SCREEN, GRASS_GREEN, pygame.Rect(0, 700, 1200, 100))

    GAME_SCREEN.blit(background, (0, 0))

    GAME_SCREEN.blit(rotated_cannon, rotated_cannon_rect.topleft)
    GAME_SCREEN.blit(cannon_wheel, pygame.Rect(65, 640, 10, 10))
    GAME_SCREEN.blit(wall, pygame.Rect(900, 500, 100, 100))

    GAME_SCREEN.blit(render_text, pygame.Rect(300, 90, 100, 100))
    GAME_SCREEN.blit(render_instructions, pygame.Rect(310, 60, 100, 100))
    GAME_SCREEN.blit(render_distance, pygame.Rect(880, 150, 100, 100))
    GAME_SCREEN.blit(display_distance, pygame.Rect(1090, 150, 100, 100))
    GAME_SCREEN.blit(render_vel_x, pygame.Rect(903, 180, 100, 100))
    GAME_SCREEN.blit(display_vel_x, pygame.Rect(1090, 180, 100, 100))
    GAME_SCREEN.blit(render_vel_y, pygame.Rect(929, 210, 100, 100))
    GAME_SCREEN.blit(display_vel_y, pygame.Rect(1090, 210, 100, 100))

def main():
    pygame.init()

    # Constants
    SCREEN_HEIGHT = 800
    SCREEN_WIDTH = 1200
    SCREEN_RESOLUTION = (SCREEN_WIDTH, SCREEN_HEIGHT)
    FRAME_RATE = 60
    GRAVITY = .5
    FRICTION = 0.5

    # Alternate Background Colors for sky and ground
    SKY_BLUE = (135, 206, 235)
    GRASS_GREEN = (69, 100, 56)
    WHITE = (255, 255, 255)

    GAME_SCREEN = pygame.display.set_mode(SCREEN_RESOLUTION)
    pygame.display.set_caption("2D Cannon Projectile Motion Simulator")

    # Creates the clock object to make 60 frames a second
    clock = pygame.time.Clock()

    # Setting up background
    background = pygame.image.load('background4.jpg')
    background = pygame.transform.smoothscale(background, (SCREEN_WIDTH, SCREEN_HEIGHT))

    # Load and Scale Cannon and Ball Image
    cannon = pygame.image.load('cannon_base.png')
    cannon = pygame.transform.smoothscale(cannon, (180, 150))

    cannon_wheel = pygame.image.load('cannon_wheel.png')
    cannon_wheel = pygame.transform.scale(cannon_wheel, (150, 150))

    cannon_ball = pygame.image.load('blue_cannon_ball.png')
    cannon_ball = pygame.transform.smoothscale(cannon_ball, (33, 33))

    wall = pygame.image.load('wall.png')
    wall = pygame.transform.smoothscale(wall, (100, 250))

    # Setting the font and text
    # Setting the font and text
    bold_font = pygame.font.Font('OpenSans-Bold.ttf', 24)
    reg_font = pygame.font.Font('OpenSans-Regular.ttf', 20)

    display_text = 'The farther your mouse is, the farther you shoot!'
    render_text = bold_font.render(display_text, True, WHITE)

    instructions_text = 'Instructions: Left click on your mouse to shoot'
    render_instructions = bold_font.render(instructions_text, True, WHITE)

    # Creating the Statistics to display in the screen
    distance_text = 'Cannon Ball Distance:'
    render_distance = reg_font.render(distance_text, True, WHITE)
    distance = '0'
    display_distance = reg_font.render(distance, True, WHITE)

    velocity_x_text = 'Horizontal Velocity: '
    velocity_y_text = 'Vertical Velocity: '
    vel_x, vel_y = '0', '0'
    render_vel_x = reg_font.render(velocity_x_text, True, WHITE)
    render_vel_y = reg_font.render(velocity_y_text, True, WHITE)
    display_vel_x = reg_font.render(vel_x, True, WHITE)
    display_vel_y = reg_font.render(vel_y, True, WHITE)

    #global cannon_ball_group
    cannon_ball_group = pygame.sprite.Group()

    # Game Loop
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if mouseX > cannon_pos[0]:
                    # shooting_angle = math.degrees(calculateAngle(mouseX, mouseY, cannon_pos[0], cannon_pos[1])) - 90
                    mouseX, mouseY = pygame.mouse.get_pos()
                    distanceX, distanceY = cannon_pos[0] + (math.cos(math.radians(angle)) * 30), cannon_pos[1] - (math.sin(math.radians(angle)) * 60) - 25

                    # Shooting Velocity is determined by the distance the mouse is from the cannon
                    # The farther the mouse is, the farther the cannon will shoot
                    shootingVelX, shootingVelY = (mouseX - cannon_pos[0]) / 40, (cannon_pos[1] - mouseY) / 20
                    CannonBall(distanceX, distanceY, shootingVelX, -shootingVelY, GRAVITY, FRICTION, cannon_ball, cannon_ball_group)

        mouseX, mouseY = pygame.mouse.get_pos()
        cannon_pos = [150, 680]
        cannon_rect = cannon.get_rect(center=cannon_pos)

        # Rotates the cannon to track the mouse
        degreeX, degreeY = mouseX - cannon_rect.centerx, mouseY - cannon_rect.centery
        angle = math.degrees(math.atan2(-degreeY, degreeX)) - 32
        rotated_cannon = pygame.transform.rotate(cannon, angle)
        rotated_cannon_rect = rotated_cannon.get_rect(center=cannon_rect.center)

        # Drawing the the sky, ground, and the cannon
        drawBackground(GAME_SCREEN, background, cannon_wheel, wall, render_text, render_instructions, render_distance, display_distance, render_vel_x, render_vel_y, display_vel_x, display_vel_y ,rotated_cannon, rotated_cannon_rect)

        # Update each cannon in the screen
        index = 0
        for cannonball in cannon_ball_group:
            cannonball.update(GAME_SCREEN, cannon_wheel, rotated_cannon, rotated_cannon_rect)
            index += 1
            if len(cannon_ball_group) == 1 or index == len(cannon_ball_group) - 1:
                display_distance = reg_font.render(str(cannonball.returnDistance()), True, WHITE)
                display_vel_x = reg_font.render(str(int(cannonball.returnVelocityX())), True, WHITE)
                display_vel_y = reg_font.render(str(-int(cannonball.returnVelocityY())), True, WHITE)

        pygame.display.flip()
        clock.tick(FRAME_RATE)

    pygame.quit()

if __name__ == "__main__":
    main()


import os

from django.http import JsonResponse
from django.core.cache import cache

from common import keys
from common import stat
from user import logics
from user.models import User
from user.models import Profile
from user.forms import UserForm
from user.forms import ProfileForm

def get_vcode(request):
    '''用户获取验证码接口'''
    phonenum = request.GET.get('phonenum')
    result = logics.send_vcode(phonenum)
    if result:
        return JsonResponse({'code': stat.OK, 'data': None})
    else:
        return JsonResponse({'code': stat.SMS_ERR, 'data': None})

def submit_vcode(request):
    '''用户提交验证码接口，并执行登陆注册'''
    # 获取参数
    phonenum = request.POST.get('phonenum')
    vcode = request.POST.get('vcode')
    # print(vcode)
    # print(phonenum)

    cached_vcode = cache.get(keys.VCODE % phonenum)
    # print(cached_vcode)

    # 检查验证码
    if vcode and cached_vcode and vcode == cached_vcode:
        try:
            user = User.objects.get(phonenum=phonenum)
        except User.DoesNotExist:
            user = User.objects.create(phonenum=phonenum, nickname=phonenum)

        # 将用户状态记录到Session
        request.session['uid'] = user.id

        return JsonResponse({'code': stat.OK, 'data': user.to_dict()})

    else:
        return JsonResponse({'code': stat.VCODE_ERR, 'data': None})

def get_profile(request):
    '''获取个人交友资料'''
    uid = request.session['uid']
    # try:
    #     profile = Profile.objects.get(id=uid)
    # except Profile.DoesNotExist:
    #     profile = Profile.objects.create(id=uid)
    profile, _ = Profile.objects.get_or_create(id=uid)
    return JsonResponse({'code':stat.OK, 'data':profile.to_dict()})

def set_profile(request):
    '''修改个人、交友资料'''

    # 验证用户表的数据
    user_form = UserForm(request.POST)
    if not user_form.is_valid():
        return JsonResponse({'code': stat.USER_FORM_ERR, 'data': user_form.errors})

    # 验证个人资料表的数据
    profile_form = ProfileForm(request.POST)
    if not profile_form.is_valid():
        return JsonResponse({'code': stat.PROFILE_FORM_ERR, 'data': profile_form.errors})

    # 更新user数据
    uid = request.session['uid']
    user = User.objects.get(id=uid)
    user.__dict__.update(user_form.cleaned_data)

    # 更新Profile数据
    profile, _ = Profile.objects.get_or_create(id=uid)
    profile.__dict__.update(profile_form.cleaned_data)

    user.save()
    profile.save()
    return JsonResponse({'code': stat.OK, 'data': None})

def upload_avatar(request):
    '''上传个人头像接口'''

    # 取出文件对象
    uid = request.session.get('uid')
    avatar_file = request.FILES.get('avatar')

    logics.upload_avatar.delay(uid, avatar_file)

    return JsonResponse({'code': stat.OK, 'data': None})


import csv
from datetime import date

from django.contrib import admin
from django.db.models.query import QuerySet
from django.db.models.fields.files import FieldFile
from django.http import HttpResponse

from .models import UserProfile
from .models import Query
from .models import Invitation
from .models import Verification

def prep_field(request, obj, field, manyToManySep=';'):
    """ Returns the field as a unicode string. If the field is a callable, it
    attempts to call it first, without arguments.
    """
    if '__' in field:
        bits = field.split('__')
        field = bits.pop()

        for bit in bits:
            obj = getattr(obj, bit, None)

            if obj is None:
                return ""

    attr = getattr(obj, field)

    if isinstance(attr, (FieldFile,)):
        attr = request.build_absolute_uri(attr.url)

    output = attr() if callable(attr) else attr

    if isinstance(output, (list, tuple, QuerySet)):
        output = manyToManySep.join([str(item) for item in output])
    return str(output) if output else ""

def export_csv_action(description="Export as CSV", fields=None, exclude=None,
                      header=True, manyToManySep=';'):
    """ This function returns an export csv action. """

    def export_as_csv(modeladmin, request, queryset):
        """ Generic csv export admin action.
        Based on http://djangosnippets.org/snippets/2712/
        """

        opts = modeladmin.model._meta
        field_names = [field.name for field in opts.fields]
        labels = []

        if exclude:
            field_names = [f for f in field_names if f not in exclude]

        elif fields:
            field_names = [field for field, _ in fields]
            labels = [label for _, label in fields]

        response = HttpResponse(content_type='text/csv')
        namefile = "rec_invitations_%s" % (date.today(), )
        response['Content-Disposition'] = 'attachment; filename=%s.csv' % (
            namefile, )

        writer = csv.writer(response)

        if header:
            writer.writerow(labels if labels else field_names)

        for obj in queryset:
            writer.writerow(
                [prep_field(request, obj, field, manyToManySep)
                 for field in field_names])
        return response
    export_as_csv.short_description = description
    export_as_csv.acts_on_all = True
    return export_as_csv

@admin.register(UserProfile)
class UserAdmin(admin.ModelAdmin):
    list_display = ('firstname', 'lastname', 'email', 'acceptance', 'created',
                    'modified', )
    list_filter = ('created', 'acceptance', )
    search_fields = ('email', )

@admin.register(Query)
class QueryAdmin(admin.ModelAdmin):
    list_display = ('description', 'user', 'created', 'modified', 'raw_data', )
    search_fields = ('user', )

@admin.register(Invitation)
class InvitationAdmin(admin.ModelAdmin):
    list_display = (
        'inviter', 'email', 'count', 'state', 'created', 'modified', )
    search_fields = ['email', 'inviter__email']
    list_filter = ('state', 'count', 'created', 'modified', )
    actions = (
        export_csv_action("Export Invitations Report",
                          fields=[
                              ('email', 'Invitado'),
                              ('inviter__email', 'Invitante'),
                              ('count', 'Reiteraciones'),
                              ('created', 'Fecha de Invitacion',),
                              ('modified', 'ambio Estado-Reiteracion'), ],
                          header=True,
                          manyToManySep=';'
                          ),)

@admin.register(Verification)
class VerificationAdmin(admin.ModelAdmin):
    list_display = ('user', 'token', )
    search_fields = ('user__email', )


import numpy as np
import cv2

# multiple cascades: https://github.com/Itseez/opencv/tree/master/data/haarcascades

face_cascade = cv2.CascadeClassifier('C:/Users/My Pc/AppData/Local/Programs/Python/Python37-32/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')

img = cv2.imread('faces2.png')
scale_factor = 1.3
while 1:
    faces = face_cascade.detectMultiScale(img, scale_factor  , 5)

    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

    print("number of faces found {} " .format(len(faces)))

    cv2.imshow('img', img)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
cv2.destroyAllWindows()


import numpy as np

from sklearn.metrics import accuracy_score, f1_score
from sklearn.model_selection import train_test_split
from load_datasets import load_dataset, import_amazon_dataset
from classic_methods.clustering.clust_classifier import get_community_based_pred
from classic_methods.node_features.feat_classifier import (
    FeatureExtractor,
    feature_prediction,
)
from classic_methods.node2vec.node2vec import (
    get_node2vec_embeddings,
    node2vec_prediction,
)

if __name__ == "__main__":
    # Uncomment one of the following line in order to load to load either Pubmed, Citeseer or Cora or the Amazon dataset using BERT embedding or TFI-IDF.
    g = load_dataset("Citeseer", to_netx=True)  # "Pubmed", "Cora", "Citeseer"
    # g = import_amazon_dataset('amazon_dataset/edges.csv', 'amazon_dataset/BERT_embeddings2.csv', embedding='BERT')
    # g = import_amazon_dataset('amazon_dataset/edges.csv', 'amazon_dataset/TF_IDF_embeddings.csv', embedding='TF_IDF')

    node_list = list(g.nodes)
    label_list = [g.nodes[i]["y"] for i in range(len(node_list))]

    extractor = FeatureExtractor()
    features = extractor.global_feature_extract(g, node_list)
    train_features, test_features, train_labels, test_labels = train_test_split(
        features, label_list, shuffle=False
    )
    comm_pred = feature_prediction(train_features, train_labels, test_features)
    print(
        "\n\nglobal features based classifier accuracy =",
        accuracy_score(test_labels, comm_pred),
        "\n\n",
    )
    print(
        "\n\nglobal features based classifier F1-score =",
        f1_score(test_labels, comm_pred, average="weighted"),
        "\n\n",
    )

    del features
    del train_features
    del test_features
    del train_labels
    del test_labels

    features = extractor.node_feature_extract(g, node_list)
    features = np.array(features, dtype=np.float16)
    train_features, test_features, train_labels, test_labels = train_test_split(
        features, label_list, shuffle=False
    )
    comm_pred = feature_prediction(train_features, train_labels, test_features)
    print(
        "\n\nnode features based classifier accuracy =",
        accuracy_score(test_labels, comm_pred),
        "\n\n",
    )
    print(
        "\n\nnode features based classifier F1-score =",
        f1_score(test_labels, comm_pred, average="weighted"),
        "\n\n",
    )

    features = extractor.full_feature_extract(g, node_list)
    train_features, test_features, train_labels, test_labels = train_test_split(
        features, label_list, shuffle=False
    )
    comm_pred = feature_prediction(train_features, train_labels, test_features)
    print(
        "\n\nnode and global features based classifier accuracy =",
        accuracy_score(test_labels, comm_pred),
        "\n\n",
    )
    print(
        "\n\nnode and global features based classifier F1-score =",
        f1_score(test_labels, comm_pred, average="weighted"),
        "\n\n",
    )

    train_nodes, test_nodes, train_labels, test_labels = train_test_split(
        node_list, label_list, shuffle=False
    )
    comm_pred = get_community_based_pred(g, train_nodes, train_labels, test_nodes)
    print(
        "\n\ncommunity based classifier accuracy =",
        accuracy_score(test_labels, comm_pred),
        "\n\n",
    )
    print(
        "\n\ncommunity based classifier F1-score =",
        f1_score(test_labels, comm_pred, average="weighted"),
        "\n\n",
    )

    embeddings = get_node2vec_embeddings(g)
    train_embeddings, test_embeddings, train_labels, test_labels = train_test_split(
        embeddings, label_list, shuffle=False
    )
    node2pred = node2vec_prediction(train_embeddings, train_labels, test_embeddings)
    print(
        "\n\nnode2vec embeddings based classifier accuracy =",
        accuracy_score(test_labels, node2pred),
        "\n\n",
    )
    print(
        "\n\nnode2vec embeddings based classifier F1-score =",
        f1_score(test_labels, node2pred, average="weighted"),
        "\n\n",
    )


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

#Read provided data as dataframe
data=pd.read_csv("srajend2.csv",header=-1)
#print(data.head(3))
#print(data[5][0])

for i in range(data.shape[1]-1):
    mean = np.mean(data[i])
    print("mean X"+str(i)+": "+ str(mean))

    var = np.var(data[i])
    print("Variance of X"+str(i)+": "+ str(var))

    plt.figure()
    plt.hist(data[i], bins='auto')
    plt.title("Histogram for X"+str(i))
    plt.show()

    plt.figure(2)
    plt.boxplot(data[i])
    plt.title("BoxPlot for X" + str(i))
    plt.show()
correlation=data.corr()
print("Correlation Matrix: \n", correlation)

#Remove outliers
data=data[(np.abs(stats.zscore(data)) < 2.5).all(axis=1)]
#Box plot after removing outliers
for i in range(0,data.shape[1]-1,1):
    plt.figure()
    plt.boxplot(data[i])
    plt.title("BoxPlot for X" + str(i))
    plt.show()

correlation=data.corr()
print("Correlation Matrix after removing outliers: \n", correlation)


import torch, torchvision
import detectron2
from detectron2.utils.logger import setup_logger
import numpy as np
import os, json, cv2, random
import scipy.sparse
import pyamg
from sys import exit as e
from torch.nn import functional as F
from torch import nn
from skimage import exposure
from skimage.exposure import match_histograms
from tqdm import tqdm

from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer
from detectron2.data import MetadataCatalog, DatasetCatalog
setup_logger()
from modules.util import imshow, show
from modules.poisson import solve_poisson

# https://github.com/fbessho/PyPoi
def blend(img_target, img_source, img_mask, offset=(0, 0)):
  new_mask= 1 - img_mask
  copy_img = cv2.bitwise_and(img_source, img_source, mask = img_mask.astype(np.uint8) * 255)
  cat_img = copy_img + cv2.bitwise_and(img_target, img_target, mask=new_mask.astype(np.uint8) * 255)
  # compute regions to be blended
  region_source = (
      max(-offset[0], 0),
      max(-offset[1], 0),
      min(img_target.shape[0] - offset[0], img_source.shape[0]),
      min(img_target.shape[1] - offset[1], img_source.shape[1]))
  region_target = (
      max(offset[0], 0),
      max(offset[1], 0),
      min(img_target.shape[0], img_source.shape[0] + offset[0]),
      min(img_target.shape[1], img_source.shape[1] + offset[1]))
  region_size = (region_source[2] - region_source[0], region_source[3] - region_source[1])

  # clip and normalize mask image
  img_mask = img_mask[region_source[0]:region_source[2], region_source[1]:region_source[3]]
  img_mask[img_mask == 0] = False
  img_mask[img_mask != False] = True

  # determines the diagonals on the coefficient matrix
  positions = np.where(img_mask)
  # setting the positions to be in a flatted manner
  positions = (positions[0] * region_size[1]) + positions[1]

  # row and col size of coefficient matrix
  n = np.prod(region_size)

  main_diagonal = np.ones(n)
  main_diagonal[positions] = 4
  diagonals = [main_diagonal]
  diagonals_positions = [0]

  # creating the diagonals of the coefficient matrix
  for diagonal_pos in [-1, 1, -region_size[1], region_size[1]]:
      in_bounds_indices = None
      if np.any(positions + diagonal_pos > n):
          in_bounds_indices = np.where(positions + diagonal_pos < n)[0]
      elif np.any(positions + diagonal_pos < 0):
          in_bounds_indices = np.where(positions + diagonal_pos >= 0)[0]
      in_bounds_positions = positions[in_bounds_indices]

      diagonal = np.zeros(n)
      diagonal[in_bounds_positions + diagonal_pos] = -1
      diagonals.append(diagonal)
      diagonals_positions.append(diagonal_pos)
  A = scipy.sparse.spdiags(diagonals, diagonals_positions, n, n, 'csr')

  # create poisson matrix for b
  P = pyamg.gallery.poisson(img_mask.shape)

  # get positions in mask that should be taken from the target
  inverted_img_mask = np.invert(img_mask.astype(np.bool)).flatten()
  positions_from_target = np.where(inverted_img_mask)[0]

  # for each layer (ex. RGB)
  for num_layer in range(img_target.shape[2]):
      # get subimages
      t = img_target[region_target[0]:region_target[2], region_target[1]:region_target[3], num_layer]
      s = img_source[region_source[0]:region_source[2], region_source[1]:region_source[3], num_layer]
      t = t.flatten()
      s = s.flatten()

      # create b
      b = P * s
      b[positions_from_target] = t[positions_from_target]

      # solve Ax = b
      x = scipy.sparse.linalg.spsolve(A, b)

      # assign x to target image
      x = np.reshape(x, region_size)
      x = np.clip(x, 0, 255)
      x = np.array(x, img_target.dtype)
      # print(num_layer)
      # imshow(x)
      # imshow(img_source[:, :, num_layer])
      # x = match_histograms(x, img_source[:, :, num_layer], multichannel=True)
      # imshow(x)
      # e()
      img_target[region_target[0]:region_target[2], region_target[1]:region_target[3], num_layer] = x
      # img_target[region_target[1]:region_target[3], region_target[0]:region_target[2], num_layer] = x
  return img_target

def extend_boundary(mask, src, inc):
  mask_orig = np.copy(mask)
  mask = torch.from_numpy(mask).unsqueeze(0).unsqueeze(0)
  weight = torch.Tensor([
    [0, 1, 0],
    [1, 0, 1],
    [0, 1, 0]
  ]).type(mask.dtype)
  mask = F.conv2d(F.pad(mask, (1, 1, 1, 1)), weight.unsqueeze(0).unsqueeze(0)).squeeze().detach().numpy()
  src_2 = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
  src_2 = cv2.normalize(src_2, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
  # imshow(mask * 255)
  n_mask = cv2.resize(mask, (int(mask.shape[0] * 1.1), int(mask.shape[1] * 1.1)), interpolation=cv2.INTER_CUBIC)
  # imshow(n_mask * 255)
  diff_r = n_mask.shape[0] - mask.shape[0]
  diff_c = n_mask.shape[1] - mask.shape[1]
  new_mask = n_mask[diff_r//2:n_mask.shape[0] - diff_r//2, diff_c//2:n_mask.shape[1] - diff_c//2]
  new_mask = cv2.resize(new_mask, (mask.shape[0], mask.shape[1]))
  boundary_mask = np.where(new_mask==4, 0, new_mask)
  new_mask = cv2.normalize(new_mask, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
  boundary_mask = np.where(mask==4, 0, mask)
  new_mask = cv2.normalize(mask, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
  boundary_mask = cv2.normalize(boundary_mask, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
  return new_mask, boundary_mask

def get_masks(im):
  cfg = get_cfg()
  cfg.MODEL.DEVICE='cpu'
  cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
  cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5
  cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
  predictor = DefaultPredictor(cfg)
  outputs = predictor(im)
  segments = np.asarray(outputs["instances"].pred_masks)
  boxes = outputs["instances"].pred_boxes
  return segments

def combine_img(configs):
  source_path = configs["args"]["source"]
  target_path = configs["args"]["target"]
  output_path = configs["args"]["output"]
  img_size = configs["args"]["img_size"]

  i = 0
  for tgt in tqdm(os.listdir(target_path)):
    target = os.path.join(target_path, tgt)
    for src in os.listdir(source_path):
      source = os.path.join(source_path, src)
      im = cv2.imread(source)
      tgt = cv2.imread(target)
      rs, cs, _ = im.shape
      rd, cd, _ = tgt.shape
      im  = cv2.resize(im, (img_size, img_size))
      tgt  = cv2.resize(tgt, (img_size, img_size))
      segments = get_masks(im)
      for mask in (segments.astype(np.uint8)):
        mask, boundary_mask = extend_boundary(mask, im, 30)
        if np.count_nonzero(mask==1) < configs["args"]["threshold"]:
          print(np.count_nonzero(mask==1))
          continue
        if configs["args"]["blend_type"] == "copy_paste":
          new_mask = 1 - mask
          cat_img = cv2.bitwise_and(im, im, mask = mask) + cv2.bitwise_and(tgt, tgt, mask = new_mask)
        elif configs["args"]["blend_type"] == "poisson":
          cv2.imwrite("./input/mask_plane.png", mask * 255)
          # new_mask= 1 - mask
          # cat_img = cv2.bitwise_and(im, im, mask = mask.astype(np.uint8) * 255) + cv2.bitwise_and(tgt, tgt, mask = new_mask.astype(np.uint8) * 255)
          # cat_img = blend(np.copy(cat_img), np.copy(im), np.copy(boundary_mask))
          # cat_img = solve_poisson(np.copy(tgt), np.copy(im), np.copy(mask), boundary_mask)
          cat_img = blend(np.copy(tgt), np.copy(im), np.copy(mask))
          # imshow(cat_img)
          # print(im.shape, tgt.shape, mask.shape)
          # cat_img = cv2.seamlessClone(im, tgt, mask * 255, (rd//2, cd//2), cv2.MIXED_CLONE)
        cv2.imwrite(f"{output_path}/{i}.png", cat_img)
        i+=1


import pickle
import gzip
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import interp1d

import os
os.chdir('/home/lab_abel/Heatwaves/Data/compact')

def analyse_direct(block):

    with gzip.open('long_series', 'rb') as f:
        T=pickle.load(f)

    anomaly=T-np.mean(T)
    print('mean = ',np.mean(T))

    def running_mean(x, N):
        cumsum = np.cumsum(np.insert(x, 0, 0))
        return (cumsum[N:] - cumsum[:-N]) / float(N)

    T90=running_mean(anomaly,24*90)

    A_max=[]
    T_block=block
    M=int(len(T90)/(24*T_block))
    for i in range(M):
        A_max.append((T90[i*24*T_block:i*24*T_block+24*T_block]).max())

    A_max=np.sort(A_max)
    A_hot=A_max[A_max>0.01]

    m=len(A_hot)

    Ret=[]
    prob=[]
    for i in range(m):
        t=-T_block/(np.log((1-(m-i)/M)))
        Ret.append(t/365)
        prob.append(1-np.exp(-T_block/t))

    plt.scatter((Ret),A_hot[:],s=10, alpha=0.5, facecolors='none', edgecolors='black',
    label='1000 year direct run')
    # plt.plot((Ret),A_hot[:],
    # label='1000 year direct run')

def analyse_GKTL(exp):

    with open('prob_'+str(exp), 'rb') as f:
        p=pickle.load(f)

    with open('T_'+str(exp), 'rb') as f:
        T=pickle.load(f)

    # with open('link_'+str(exp), 'rb') as f:
    #     link=pickle.load(f)

    def running_mean(x, N):
        cumsum = np.cumsum(np.insert(x, 0, 0))
        return (cumsum[N:] - cumsum[:-N]) / float(N)

    A_max=[]
    for e in T:
        A_max.append(np.max(running_mean((np.array(e)-298.3797386241071)[:], 3*24*90)))

    a, p = zip(*sorted(zip(A_max, p)))

    # print(np.sum(p))

    # index=0
    # for i in range(len(a)):
    #     if a[i]>0.01:
    #         break
    #     index+=1

    # a=a[index:];p=p[index:]

    r=[]
    for i in range(len(a)):
        T=-(128-90)/np.log(1-np.sum(p[i:]))
        # T=(128-90)/np.sum(p[i:])
        r.append((T)/365)

    # plt.plot(r,a, label='GKTL k=10', color='red', linewidth='0.8')

    # r_interpol_range=np.linspace(0,1000000,10000001, endpoint=True)
    r_interpol_range=np.power(10, np.linspace(-1,8,1000000, endpoint=True))
    f = interp1d(r, a)
    r_interpol=r_interpol_range[np.logical_and(r_interpol_range>np.min(r), r_interpol_range<np.max(r))]
    a_interpol=f(r_interpol)

    mean=np.mean(a_interpol); std=np.std(a_interpol)
    front=0;rear=len(a_interpol)
    for i in range(len(a_interpol)):
        if a_interpol[i]<mean-1.0*std:
            front=i+1
        if a_interpol[i]<mean+1.0*std:
            rear= i+1

    a_interpol=a_interpol[front:rear];r_interpol=r_interpol[front:rear]

    # plt.plot(r_interpol,a_interpol, label=exp)
    return r_interpol,a_interpol

analyse_direct(38)

r=np.power(10, np.linspace(-1,8,1000000, endpoint=True))
print(r.min(), r.max())
c=np.zeros(len(r))
val=np.zeros(len(r))
val2=np.zeros(len(r))

for exp in  ['10b', '20', '20b', '30', '40', '40b', '50' ]:
    r_temp, a_temp=analyse_GKTL(exp)
    mask=np.logical_and(r>=r_temp.min(), r<=r_temp.max())
    val[mask]=val[mask]+a_temp
    val2[mask]=val2[mask]+a_temp*a_temp
    c[mask]=c[mask]+1

a_avg=val/c
std=np.sqrt(val2/c-(val*val)/(c*c))
print(std.min(),std.max())

plt.plot(r,a_avg, label='GKTL run',color='red',linewidth=1.5)
# plt.fill_between(r,a_avg-std,a_avg+std,color="grey",alpha=0.3)
plt.grid()
plt.xscale('log')
plt.xlabel('Return time (years)')
plt.ylabel('Anomaly of 90 day avg temperature (K)')
plt.legend()
# plt.xlim([0,70000000])
plt.xticks([1/10,1,10,100,1000,10000,100000,1000000,1000000])
plt.ylim([0,3])
plt.show()

analyse_direct(38)

front=0;rear=len(c)
stop=0
for i in range(len(c)):
    if c[i]>=1 and stop==0:
        front=i+1
        stop=1
    if c[i]>=3:
        rear= i+1

a_avg=a_avg[front:rear];r=r[front:rear];std=std[front:rear]

z = np.polyfit(np.log10(r), a_avg, 5)
P=np.polyval(z,np.log10(r))
print(z)
plt.plot(r,P, label='GKTL run',color='red',linewidth=1.5)
plt.fill_between(r,P-std,P+std,color='grey',alpha=0.2)

plt.grid()
plt.xscale('log')
plt.xlabel('Return time (years)')
plt.ylabel('Anomaly of 90 day avg temperature (K)')
plt.legend()
# plt.xlim([0,70000000])
plt.xticks([1/10,1,10,100,1000,10000,100000,1000000,1000000])
plt.ylim([0,3])
plt.show()


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

import sys
import codecs

from setuptools import setup, find_packages
from setuptools.command.test import test as TestCommand

import araisan

class PyTest(TestCommand):
    # `$ python setup.py test' simply installs minimal requirements
    # and runs the tests with no fancy stuff like parallel execution.
    def finalize_options(self):
        TestCommand.finalize_options(self)
        self.test_args = [
            '--doctest-modules', '--verbose',
            './araisan', './tests'
        ]
        self.test_suite = True

    def run_tests(self):
        import pytest
        sys.exit(pytest.main(self.test_args))

tests_require = [
    # Pytest needs to come last.
    # https://bitbucket.org/pypa/setuptools/issue/196/
    'pytest-cov',
    'pytest'
]

extras_require = {}

install_requires = [
    'pyyaml',
]

devstatus = 'Development Status :: 5 - Production/Stable'
if 'b' in araisan.__version__:
    devstatus = 'Development Status :: 4 - Beta'
elif 'a' in araisan.__version__:
    devstatus = 'Development Status :: 3 - Alpha'

setup(
    name='araisan',
    version=araisan.__version__,
    description=araisan.__doc__.strip(),
    long_description='',
    url='https://github.com/moeoverflow/Araisan',
    download_url='https://github.com/moeoverflow/Araisan',
    author=araisan.__author__,
    author_email='0xbbc@0xbbc.com',
    license=araisan.__licence__,
    packages=find_packages(),
    entry_points={
        'console_scripts': [
            'araisan = araisan.__main__:main',
        ],
    },
    extras_require=extras_require,
    install_requires=install_requires,
    tests_require=tests_require,
    cmdclass={'test': PyTest},
    classifiers=[
        devstatus,
        'Programming Language :: Python',
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.1',
        'Programming Language :: Python :: 3.2',
        'Programming Language :: Python :: 3.3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Environment :: Console',
        'Intended Audience :: Developers',
        'Intended Audience :: System Administrators',
        'Intended Audience :: Information Technology',
        'License :: OSI Approved :: MIT License',
        'Topic :: Terminals',
        'Topic :: Utilities'
    ],
)


from PyQt5.QtWidgets import QFileDialog
from controllers.base_controller import BaseController
from views.main_window_view import MainWindowView

class MainWindowController(BaseController):
    def __init__(self):
        main_view = MainWindowView(self, title="QuickTail")
        super().__init__(view=main_view)

        self._tabs = []
        self._current_tab = None

    def open_file(self):
        # file_dialog = QFileDialog.getOpenFileName()
        file_dialog, check = QFileDialog.getOpenFileName(None, "QFileDialog.getOpenFileName()",
                                    "", "All Files (*);;Python Files (*.py);;Text Files (*.txt)")

        if check:
            print(file_dialog)