import argparse
from collections import defaultdict

import matplotlib.pyplot as plt
import numpy as np

file_names = [
    'HahnAcyclic',
    'HahnDom',
    'HahnEquational',
    'HahnMaxElt',
    'HahnMinElt',
    'HahnPath',
    'HahnRelationsBasic'
]

raw = defaultdict(list)

def analyze():
    prev, ans = '', True
    proof_stat = defaultdict(int)
    for name in file_names:
        for ls in raw[name]:
            proof_stat['total'] += 1
            p = ''.join(ls)
            if 'kat' in p:
                proof_stat['changed'] += 1
                print(p)
                if prev == p:
                    is_full = ans
                else:
                    is_full = bool(input('full? '))
                    prev = p
                    ans = is_full
                if is_full:
                    proof_stat['full'] += 1
                    if 'kat' in p and 'hkat' not in p:
                        proof_stat['full_proof_with_kat'] += 1
                    if 'hkat' in p:
                        proof_stat['full_proof_with_hkat'] += 1
                    if 'hkat' in p and "hkat''" not in p:
                        proof_stat['full_proof_with_hkat_light'] += 1
                    if "hkat''" in p:
                        proof_stat['full_proof_with_hkat_hard'] += 1
                else:
                    if 'kat' in p and 'hkat' not in p:
                        proof_stat['part_proof_with_kat'] += 1
                    if 'hkat' in p:
                        proof_stat['part_proof_with_hkat'] += 1
                    if 'hkat' in p and "hkat''" not in p:
                        proof_stat['part_proof_with_hkat_light'] += 1
                    if "hkat''" in p:
                        proof_stat['part_proof_with_hkat_hard'] += 1
                    proof_stat['partial'] += 1
            proof_stat['line_total'] += len(ls)

    for k, v in proof_stat.items():
        print(f'>>> {k}: {v}')

    sizes = [proof_stat['total'] - (proof_stat['changed']), proof_stat['full'], proof_stat['partial']]
    print(f'proofs: {sizes}')
    # labels = f'Не именилось: {sizes[0]}', f'Упростилось: {sizes[1]}'
    explode = (0, 0.1, 0.1)

    plt.rcParams.update({'font.size': 28})
    plt.rcParams['figure.figsize'] = 16, 9

    fig, (ax1, ax2) = plt.subplots(1, 2)

    def func(pct, sizes):
        absolute = int(pct / 100. * sum(sizes))
        return "{:.1f}%\n({:d})".format(pct, absolute)

    ax1.pie(sizes, explode=explode, autopct=lambda pct: func(pct, sizes), startangle=90)
    ax1.set_title("Количество доказательств")
    ax1.axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
    ax1.legend(['Не изменилось', 'Полностью автоматизировано', 'Частично автоматизировано'])

    sizes = [2178, 320, 151]
    print(f'lines: {sizes}')
    # labels = (f'Не изменилось: {sizes[0]}', f'Упростилось: {sizes[1]}')
    ax2.pie(sizes, explode=(0, 0.1, 0.1), autopct=lambda pct: func(pct, sizes), startangle=90)
    ax2.set_title('Количество строк')
    ax2.axis('equal')
    plt.savefig('stat.png')

def main(args):
    assert 'temp' in args.path_dir
    for name in file_names:
        with open(f'{args.path_dir}/{name}.v') as f:
            proof = []
            for l in f:
                if "Proof." in l or proof:
                    proof.append(l)
                if "Qed." in l:
                    raw[name].append(proof)
                    proof = []

    analyze()

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("path_dir", type=str)

    main(parser.parse_args())


'''
    problem at : https://codeforces.com/problemset/problem/236/A
'''

username = input()

d = {}

for c in username:
    d[c] = d.get(c, 0) + 1

if len(d.keys()) % 2 == 0:
    print('CHAT WITH HER!')
else:
    print('IGNORE HIM!')


r"""
Welcome to
   ___  _______   ____  __  _____
  / _ |/ ___/ /  / __ \/ / / / _ \
 / __ / /__/ /__/ /_/ / /_/ / // /
/_/ |_\___/____/\____/\____/____/

This a tool to create Android Virtual Devices locally/remotely.

- Prerequisites:
 The manual will be available at
 https://android.googlesource.com/platform/tools/acloud/+/master/README.md

- To get started:
 - Create instances:
    1) To create a remote cuttlefish instance with the local built image.
       Example:
       $ acloud create --local-image
       Or specify built image dir:
       $ acloud create --local-image /tmp/image_dir
    2) To create a local cuttlefish instance using the image which has been
       built out in your workspace.
       Example:
       $ acloud create --local-instance --local-image

 - Delete instances:
   $ acloud delete

 - Reconnect:
   To reconnect adb/vnc to an existing instance that's been disconnected:
   $ acloud reconnect
   Or to specify a specific instance:
   $ acloud reconnect --instance-names <instance_name like ins-123-cf-x86-phone>

 - List:
   List will retrieve all the remote instances you've created in addition to any
   local instances created as well.
   To show device IP address, adb port and instance name:
   $ acloud list
   To show more detail info on the list.
   $ acloud list -vv

-  Pull:
   Pull will download log files or show the log file in screen from one remote
   cuttlefish instance:
   $ acloud pull
   Pull from a specified instance:
   $ acloud pull --instance-name "your_instance_name"

Try $acloud [cmd] --help for further details.

"""

from __future__ import print_function
import argparse
import logging
import os
import platform
import sys
import sysconfig
import traceback

# TODO: Remove this once we switch over to embedded launcher.
# Exit out if python version is < 2.7.13 due to b/120883119.
if (sys.version_info.major == 2
        and sys.version_info.minor == 7
        and sys.version_info.micro < 13):
    print("Acloud requires python version 2.7.13+ (currently @ %d.%d.%d)" %
          (sys.version_info.major, sys.version_info.minor,
           sys.version_info.micro))
    print("Update your 2.7 python with:")
    # pylint: disable=invalid-name
    os_type = platform.system().lower()
    if os_type == "linux":
        print("  apt-get install python2.7")
    elif os_type == "darwin":
        print("  brew install python@2 (and then follow instructions at "
              "https://docs.python-guide.org/starting/install/osx/)")
        print("  - or -")
        print("  POSIXLY_CORRECT=1 port -N install python27")
    sys.exit(1)
# This is a workaround to put '/usr/lib/python3.X' ahead of googleapiclient of
# build system path list to fix python3 issue of http.client(b/144743252)
# that googleapiclient existed http.py conflict with python3 build-in lib.
# Using embedded_launcher(b/135639220) perhaps work whereas it didn't solve yet.
if sys.version_info.major == 3:
    sys.path.insert(0, os.path.dirname(sysconfig.get_paths()['purelib']))

# By Default silence root logger's stream handler since 3p lib may initial
# root logger no matter what level we're using. The acloud logger behavior will
# be defined in _SetupLogging(). This also could workaround to get rid of below
# oauth2client warning:
# 'No handlers could be found for logger "oauth2client.contrib.multistore_file'
DEFAULT_STREAM_HANDLER = logging.StreamHandler()
DEFAULT_STREAM_HANDLER.setLevel(logging.CRITICAL)
logging.getLogger().addHandler(DEFAULT_STREAM_HANDLER)

# pylint: disable=wrong-import-position
from acloud import errors
from acloud.create import create
from acloud.create import create_args
from acloud.delete import delete
from acloud.delete import delete_args
from acloud.internal import constants
from acloud.reconnect import reconnect
from acloud.reconnect import reconnect_args
from acloud.list import list as list_instances
from acloud.list import list_args
from acloud.metrics import metrics
from acloud.powerwash import powerwash
from acloud.powerwash import powerwash_args
from acloud.public import acloud_common
from acloud.public import config
from acloud.public import report
from acloud.public.actions import create_cuttlefish_action
from acloud.public.actions import create_goldfish_action
from acloud.pull import pull
from acloud.pull import pull_args
from acloud.restart import restart
from acloud.restart import restart_args
from acloud.setup import setup
from acloud.setup import setup_args

LOGGING_FMT = "%(asctime)s |%(levelname)s| %(module)s:%(lineno)s| %(message)s"
ACLOUD_LOGGER = "acloud"
_LOGGER = logging.getLogger(ACLOUD_LOGGER)
NO_ERROR_MESSAGE = ""
PROG = "acloud"
_ACLOUD_CONFIG_ERROR = "ACLOUD_CONFIG_ERROR"

# Commands
CMD_CREATE_CUTTLEFISH = "create_cf"
CMD_CREATE_GOLDFISH = "create_gf"

# Config requires fields.
_CREATE_REQUIRE_FIELDS = ["project", "zone", "machine_type"]
_CREATE_CF_REQUIRE_FIELDS = ["resolution"]
# show contact info to user.
_CONTACT_INFO = ("If you have any question or need acloud team support, "
                 "please feel free to contact us by email at "
                 "buganizer-system+419709@google.com")
_LOG_INFO = " and attach those log files from %s"

# pylint: disable=too-many-statements
def _ParseArgs(args):
    """Parse args.

    Args:
        args: Argument list passed from main.

    Returns:
        Parsed args.
    """
    usage = ",".join([
        setup_args.CMD_SETUP,
        create_args.CMD_CREATE,
        list_args.CMD_LIST,
        delete_args.CMD_DELETE,
        reconnect_args.CMD_RECONNECT,
        pull_args.CMD_PULL,
        restart_args.CMD_RESTART,
    ])
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
        usage="acloud {" + usage + "} ...")
    parser = argparse.ArgumentParser(prog=PROG)
    parser.add_argument('--version', action='version', version=(
        '%(prog)s ' + config.GetVersion()))
    subparsers = parser.add_subparsers(metavar="{" + usage + "}")
    subparser_list = []

    # Command "create_cf", create cuttlefish instances
    create_cf_parser = subparsers.add_parser(CMD_CREATE_CUTTLEFISH)
    create_cf_parser.required = False
    create_cf_parser.set_defaults(which=CMD_CREATE_CUTTLEFISH)
    create_args.AddCommonCreateArgs(create_cf_parser)
    subparser_list.append(create_cf_parser)

    # Command "create_gf", create goldfish instances
    # In order to create a goldfish device we need the following parameters:
    # 1. The emulator build we wish to use, this is the binary that emulates
    #    an android device. See go/emu-dev for more
    # 2. A system-image. This is the android release we wish to run on the
    #    emulated hardware.
    create_gf_parser = subparsers.add_parser(CMD_CREATE_GOLDFISH)
    create_gf_parser.required = False
    create_gf_parser.set_defaults(which=CMD_CREATE_GOLDFISH)
    create_gf_parser.add_argument(
        "--emulator_build_id",
        type=str,
        dest="emulator_build_id",
        required=False,
        help="Emulator build used to run the images. e.g. 4669466.")
    create_gf_parser.add_argument(
        "--emulator_branch",
        type=str,
        dest="emulator_branch",
        required=False,
        help="Emulator build branch name, e.g. aosp-emu-master-dev. If specified"
        " without emulator_build_id, the last green build will be used.")
    create_gf_parser.add_argument(
        "--base_image",
        type=str,
        dest="base_image",
        required=False,
        help="Name of the goldfish base image to be used to create the instance. "
        "This will override stable_goldfish_host_image_name from config. "
        "e.g. emu-dev-cts-061118")
    create_gf_parser.add_argument(
        "--tags",
        dest="tags",
        nargs="*",
        required=False,
        default=None,
        help="Tags to be set on to the created instance. e.g. https-server.")

    create_args.AddCommonCreateArgs(create_gf_parser)
    subparser_list.append(create_gf_parser)

    # Command "create"
    subparser_list.append(create_args.GetCreateArgParser(subparsers))

    # Command "setup"
    subparser_list.append(setup_args.GetSetupArgParser(subparsers))

    # Command "delete"
    subparser_list.append(delete_args.GetDeleteArgParser(subparsers))

    # Command "list"
    subparser_list.append(list_args.GetListArgParser(subparsers))

    # Command "reconnect"
    subparser_list.append(reconnect_args.GetReconnectArgParser(subparsers))

    # Command "restart"
    subparser_list.append(restart_args.GetRestartArgParser(subparsers))

    # Command "powerwash"
    subparser_list.append(powerwash_args.GetPowerwashArgParser(subparsers))

    # Command "pull"
    subparser_list.append(pull_args.GetPullArgParser(subparsers))

    # Add common arguments.
    for subparser in subparser_list:
        acloud_common.AddCommonArguments(subparser)

    if not args:
        parser.print_help()
        sys.exit(constants.EXIT_BY_WRONG_CMD)

    return parser.parse_args(args)

# pylint: disable=too-many-branches
def _VerifyArgs(parsed_args):
    """Verify args.

    Args:
        parsed_args: Parsed args.

    Raises:
        errors.CommandArgError: If args are invalid.
        errors.UnsupportedCreateArgs: When a create arg is specified but
                                      unsupported for a particular avd type.
                                      (e.g. --system-build-id for gf)
    """
    if parsed_args.which == create_args.CMD_CREATE:
        create_args.VerifyArgs(parsed_args)
    if parsed_args.which == setup_args.CMD_SETUP:
        setup_args.VerifyArgs(parsed_args)
    if parsed_args.which == CMD_CREATE_CUTTLEFISH:
        if not parsed_args.build_id and not parsed_args.branch:
            raise errors.CommandArgError(
                "Must specify --build_id or --branch")
    if parsed_args.which == CMD_CREATE_GOLDFISH:
        if not parsed_args.emulator_build_id and not parsed_args.build_id and (
                not parsed_args.emulator_branch and not parsed_args.branch):
            raise errors.CommandArgError(
                "Must specify either --build_id or --branch or "
                "--emulator_branch or --emulator_build_id")
        if not parsed_args.build_target:
            raise errors.CommandArgError("Must specify --build_target")
        if (parsed_args.system_branch
                or parsed_args.system_build_id
                or parsed_args.system_build_target):
            raise errors.UnsupportedCreateArgs(
                "--system-* args are not supported for AVD type: %s"
                % constants.TYPE_GF)

    if parsed_args.which in [
            create_args.CMD_CREATE, CMD_CREATE_CUTTLEFISH, CMD_CREATE_GOLDFISH
    ]:
        if (parsed_args.serial_log_file
                and not parsed_args.serial_log_file.endswith(".tar.gz")):
            raise errors.CommandArgError(
                "--serial_log_file must ends with .tar.gz")

def _ParsingConfig(args, cfg):
    """Parse config to check if missing any field.

    Args:
        args: Namespace object from argparse.parse_args.
        cfg: AcloudConfig object.

    Returns:
        error message about list of missing config fields.
    """
    missing_fields = []
    if args.which == create_args.CMD_CREATE and args.local_instance is None:
        missing_fields = cfg.GetMissingFields(_CREATE_REQUIRE_FIELDS)
    if args.which == CMD_CREATE_CUTTLEFISH:
        missing_fields.extend(cfg.GetMissingFields(_CREATE_CF_REQUIRE_FIELDS))
    if missing_fields:
        return "Missing required configuration fields: %s" % missing_fields
    return None

def _SetupLogging(log_file, verbose):
    """Setup logging.

    This function define the logging policy in below manners.
    - without -v , -vv ,--log_file:
    Only display critical log and print() message on screen.

    - with -v:
    Display INFO log and set StreamHandler to acloud parent logger to turn on
    ONLY acloud modules logging.(silence all 3p libraries)

    - with -vv:
    Display INFO/DEBUG log and set StreamHandler to root logger to turn on all
    acloud modules and 3p libraries logging.

    - with --log_file.
    Dump logs to FileHandler with DEBUG level.

    Args:
        log_file: String, if not None, dump the log to log file.
        verbose: Int, if verbose = 1(-v), log at INFO level and turn on
                 logging on libraries to a StreamHandler.
                 If verbose = 2(-vv), log at DEBUG level and turn on logging on
                 all libraries and 3rd party libraries to a StreamHandler.
    """
    # Define logging level and hierarchy by verbosity.
    shandler_level = None
    logger = None
    if verbose == 0:
        shandler_level = logging.CRITICAL
        logger = logging.getLogger(ACLOUD_LOGGER)
    elif verbose == 1:
        shandler_level = logging.INFO
        logger = logging.getLogger(ACLOUD_LOGGER)
    elif verbose > 1:
        shandler_level = logging.DEBUG
        logger = logging.getLogger()

    # Add StreamHandler by default.
    shandler = logging.StreamHandler()
    shandler.setFormatter(logging.Formatter(LOGGING_FMT))
    shandler.setLevel(shandler_level)
    logger.addHandler(shandler)
    # Set the default level to DEBUG, the other handlers will handle
    # their own levels via the args supplied (-v and --log_file).
    logger.setLevel(logging.DEBUG)

    # Add FileHandler if log_file is provided.
    if log_file:
        fhandler = logging.FileHandler(filename=log_file)
        fhandler.setFormatter(logging.Formatter(LOGGING_FMT))
        fhandler.setLevel(logging.DEBUG)
        logger.addHandler(fhandler)

def main(argv=None):
    """Main entry.

    Args:
        argv: A list of system arguments.

    Returns:
        Job status: Integer, 0 if success. None-zero if fails.
        Stack trace: String of errors.
    """
    args = _ParseArgs(argv)
    _SetupLogging(args.log_file, args.verbose)
    _VerifyArgs(args)
    _LOGGER.info("Acloud version: %s", config.GetVersion())

    cfg = config.GetAcloudConfig(args)
    parsing_config_error = _ParsingConfig(args, cfg)
    # TODO: Move this check into the functions it is actually needed.
    # Check access.
    # device_driver.CheckAccess(cfg)

    reporter = None
    if parsing_config_error:
        reporter = report.Report(command=args.which)
        reporter.UpdateFailure(parsing_config_error, _ACLOUD_CONFIG_ERROR)
    elif args.which == create_args.CMD_CREATE:
        reporter = create.Run(args)
    elif args.which == CMD_CREATE_CUTTLEFISH:
        reporter = create_cuttlefish_action.CreateDevices(
            cfg=cfg,
            build_target=args.build_target,
            build_id=args.build_id,
            branch=args.branch,
            kernel_build_id=args.kernel_build_id,
            kernel_branch=args.kernel_branch,
            kernel_build_target=args.kernel_build_target,
            system_branch=args.system_branch,
            system_build_id=args.system_build_id,
            system_build_target=args.system_build_target,
            bootloader_branch=args.bootloader_branch,
            bootloader_build_id=args.bootloader_build_id,
            bootloader_build_target=args.bootloader_build_target,
            gpu=args.gpu,
            num=args.num,
            serial_log_file=args.serial_log_file,
            autoconnect=args.autoconnect,
            report_internal_ip=args.report_internal_ip,
            boot_timeout_secs=args.boot_timeout_secs,
            ins_timeout_secs=args.ins_timeout_secs)
    elif args.which == CMD_CREATE_GOLDFISH:
        reporter = create_goldfish_action.CreateDevices(
            cfg=cfg,
            build_target=args.build_target,
            build_id=args.build_id,
            emulator_build_id=args.emulator_build_id,
            branch=args.branch,
            emulator_branch=args.emulator_branch,
            kernel_build_id=args.kernel_build_id,
            kernel_branch=args.kernel_branch,
            kernel_build_target=args.kernel_build_target,
            gpu=args.gpu,
            num=args.num,
            serial_log_file=args.serial_log_file,
            autoconnect=args.autoconnect,
            tags=args.tags,
            report_internal_ip=args.report_internal_ip,
            boot_timeout_secs=args.boot_timeout_secs)
    elif args.which == delete_args.CMD_DELETE:
        reporter = delete.Run(args)
    elif args.which == list_args.CMD_LIST:
        list_instances.Run(args)
    elif args.which == reconnect_args.CMD_RECONNECT:
        reconnect.Run(args)
    elif args.which == restart_args.CMD_RESTART:
        reporter = restart.Run(args)
    elif args.which == powerwash_args.CMD_POWERWASH:
        reporter = powerwash.Run(args)
    elif args.which == pull_args.CMD_PULL:
        reporter = pull.Run(args)
    elif args.which == setup_args.CMD_SETUP:
        setup.Run(args)
    else:
        error_msg = "Invalid command %s" % args.which
        sys.stderr.write(error_msg)
        return constants.EXIT_BY_WRONG_CMD, error_msg

    if reporter and args.report_file:
        reporter.Dump(args.report_file)
    if reporter and reporter.errors:
        error_msg = "\n".join(reporter.errors)
        help_msg = _CONTACT_INFO
        if reporter.data.get(constants.ERROR_LOG_FOLDER):
            help_msg += _LOG_INFO % reporter.data.get(constants.ERROR_LOG_FOLDER)
        sys.stderr.write("Encountered the following errors:\n%s\n\n%s.\n" %
                         (error_msg, help_msg))
        return constants.EXIT_BY_FAIL_REPORT, error_msg
    return constants.EXIT_SUCCESS, NO_ERROR_MESSAGE

if __name__ == "__main__":
    EXIT_CODE = None
    EXCEPTION_STACKTRACE = None
    EXCEPTION_LOG = None
    LOG_METRICS = metrics.LogUsage(sys.argv[1:])
    try:
        EXIT_CODE, EXCEPTION_STACKTRACE = main(sys.argv[1:])
    except Exception as e:
        EXIT_CODE = constants.EXIT_BY_ERROR
        EXCEPTION_STACKTRACE = traceback.format_exc()
        EXCEPTION_LOG = str(e)
        raise
    finally:
        # Log Exit event here to calculate the consuming time.
        if LOG_METRICS:
            metrics.LogExitEvent(EXIT_CODE,
                                 stacktrace=EXCEPTION_STACKTRACE,
                                 logs=EXCEPTION_LOG)


import sys
import re
import argparse
import os
import json

regex_flags = re.MULTILINE | re.VERBOSE

syscall_regex = re.compile(r'''
__syscall\s+                    # __syscall attribute, must be first
([^(]+)                         # type and name of system call (split later)
[(]                             # Function opening parenthesis
([^)]*)                         # Arg list (split later)
[)]                             # Closing parenthesis
''', regex_flags)

struct_tags = ["__subsystem", "__net_socket"]

tagged_struct_decl_template = r'''
%s\s+                           # tag, must be first
struct\s+                       # struct keyword is next
([^{]+)                         # name of subsystem
[{]                             # Open curly bracket
'''

def tagged_struct_update(target_list, tag, contents):
    regex = re.compile(tagged_struct_decl_template % tag, regex_flags)
    items = [mo.groups()[0].strip() for mo in regex.finditer(contents)]
    target_list.extend(items)

def analyze_headers(multiple_directories):
    syscall_ret = []
    tagged_ret = {}

    for tag in struct_tags:
        tagged_ret[tag] = []

    for base_path in multiple_directories:
        for root, dirs, files in os.walk(base_path, topdown=True):
            dirs.sort()
            files.sort()
            for fn in files:

                # toolchain/common.h has the definitions of these tags which we
                # don't want to trip over
                path = os.path.join(root, fn)
                if (not (path.endswith(".h") or path.endswith(".c")) or
                        path.endswith(os.path.join(os.sep, 'toolchain',
                                                   'common.h'))):
                    continue

                with open(path, "r", encoding="utf-8") as fp:
                    contents = fp.read()

                try:
                    syscall_result = [(mo.groups(), fn)
                                      for mo in syscall_regex.finditer(contents)]
                    for tag in struct_tags:
                        tagged_struct_update(tagged_ret[tag], tag, contents)
                except Exception:
                    sys.stderr.write("While parsing %s\n" % fn)
                    raise

                syscall_ret.extend(syscall_result)

    return syscall_ret, tagged_ret

def update_file_if_changed(path, new):
    if os.path.exists(path):
        with open(path, 'r') as fp:
            old = fp.read()

        if new != old:
            with open(path, 'w') as fp:
                fp.write(new)
    else:
        with open(path, 'w') as fp:
            fp.write(new)

def parse_args():
    global args
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter, allow_abbrev=False)

    parser.add_argument("-i", "--include", required=True, action='append',
                        help='''include directories recursively scanned
                        for .h files.  Can be specified multiple times:
                        -i topdir1 -i topdir2 ...''')
    parser.add_argument(
        "-j", "--json-file", required=True,
        help="Write system call prototype information as json to file")
    parser.add_argument(
        "-t", "--tag-struct-file", required=True,
        help="Write tagged struct name information as json to file")

    args = parser.parse_args()

def main():
    parse_args()

    syscalls, tagged = analyze_headers(args.include)

    # Only write json files if they don't exist or have changes since
    # they will force an incremental rebuild.

    syscalls_in_json = json.dumps(
        syscalls,
        indent=4,
        sort_keys=True
    )
    update_file_if_changed(args.json_file, syscalls_in_json)

    tagged_struct_in_json = json.dumps(
        tagged,
        indent=4,
        sort_keys=True
    )
    update_file_if_changed(args.tag_struct_file, tagged_struct_in_json)

if __name__ == "__main__":
    main()


import time
import logging
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import ActionChains
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import StaleElementReferenceException
from utilities.utils import Utils

class TestReviewPage:
    log = Utils.custlogger(logLevel=logging.WARNING)

    def __init__(self, driver, wait):
        self.driver = driver
        self.wait = wait

    def test_sort(self, sortby, sort_id):
        #sort_id = 'wc-block-components-sort-select__select-0'
        self.wait.until(EC.element_to_be_clickable((By.ID, sort_id)))
        dropdown = self.driver.find_element(By.ID, sort_id)
        dd = Select(dropdown)
        dd.select_by_index(sortby)
        self.log.warning("Sorted the Reviews")
        time.sleep(5)

    def backtotop(self):
        backtotop = self.driver.find_element(By.XPATH, "//span[contains(text(),'Back to top')]")
        self.driver.execute_script("arguments[0].scrollIntoView();", backtotop)
        backtotop.click()
        self.log.warning("Moved to Top of page")

    def loadmorereviews(self):
        current_reviews = self.driver.find_elements(By.XPATH,
                                                    "//div[@class='main-content clear-fix boxed-wrapper']//li")
        loadmore = self.driver.find_element(By.XPATH, "//button[@class='wp-block-button__link']")
        while bool(loadmore):
            try:
                loadmore.click()
                loadmore = self.driver.find_element(By.XPATH, "//button[@class='wp-block-button__link']")
                self.driver.execute_script("arguments[0].scrollIntoView();", loadmore)
            except (NoSuchElementException, StaleElementReferenceException):
                loadmore = False
        self.log.warning("Loaded all reviews ")
        load_reviews = self.driver.find_elements(By.XPATH,
                                                 "//div[@class='main-content clear-fix boxed-wrapper']//li")
        list1 = [len(load_reviews), len(current_reviews)]
        return list1

    def review_checkbox(self):
        review_checkbox = self.driver.find_element(By.ID, "wp-comment-cookies-consent")
        review_checkbox.click()
        self.driver.execute_script("arguments[0].scrollIntoView();", review_checkbox)
        self.driver.implicitly_wait(10)
        checkbox = self.driver.find_element(By.ID, "wp-comment-cookies-consent").is_selected()
        return checkbox


from django.urls import path
from . import views
urlpatterns = [
    path('',views.home,name='home'),
   path('ilan/<str:pk>',views.listing,name='ilan'),
   path('ilanac/',views.createListing,name='create-listing'),
   path('kayit/',views.registerPage,name='kayit'),
   path('profil/',views.userProfile,name='profile'),
   path('profile/<str:pk>',views.profileCheck,name='check'),
   path('giris/',views.loginPage,name='giris'),
   path('logout/',views.logoutUser,name = "logout"),
   path('update-listing/<str:pk>/',views.updateListing, name="update-listing"),
   path('delete-listing/<str:pk>/',views.deleteListing, name="delete-listing"),
   path('delete-comment/<str:pk>/',views.deleteComment, name="delete-comment"),
   path('favori/<str:pk>',views.favori,name='favori'),
   path('sil/<str:pk>',views.favoriSil,name='sil')
]


from src.metric.CompoundMetric import CompoundMetric
from src.metric.SampleMetricManager import SampleMetricManager
from src.core.Setupable import SetupMode
from src.metric.CompoundMetricManager import CompoundMetricManager
from typing import Any
from cleanfid import fid
from src.population.Population import Population
from src.dataset.FFHQDataset import FFHQDataset
import numpy as np
from pathlib import Path

FID_NAME = "FID"
FID_CALC_MODES = ["clean", "legacy_tensorflow", "legacy_pytorch"]
FID_DEFAULT_CALC_MODE = "clean"

# TODO: Fix this:
#! Only works when equal to zero, gets pickle error otherwise
NUM_WORKERS = 0

class FIDCompoundMetric(CompoundMetric):
    def __init__(
        self,
        cmm: CompoundMetricManager,
        smm: SampleMetricManager = None,
    ):
        """
        Constructor for FIDCompoundMetric class, subclass of the CompoundMetric class.

        Args:
            cmm (CompoundMetricManager): Manager used by metrics. Population and dataset is derived
                from this manager.
            smm (SampleMetricManager, optional): Not used for this metric. Defaults to None.
        """
        super(FIDCompoundMetric, self).__init__(FID_NAME, cmm, smm)

        # Init storage structure for this metric
        self._fid = dict()

    def reg_setup_modes(self) -> dict[str, SetupMode]:
        ds = self.get_dataset()
        return {
            f"statistics_{fcm}_{ds.get_name(ds.get_resolution())}": SetupMode(
                True,
                lambda _, fcm=fcm: self._setup(fcm),
                lambda fcm=fcm: self._is_ready(fcm),
            )
            for fcm in FID_CALC_MODES
        }

    def _setup(self, calc_mode: str = FID_DEFAULT_CALC_MODE) -> None:
        """
        Setup the needed statistics to calculate the metric.

        Note that each dataset and `calc_mode` combination needs a calculated statistic.

        For more information regarding `calc_mode`, see the documentation for `calc()`.

        Args:
            calc_mode (str, optional): Calc mode determines FID implementation, different statistics
                needed for different implementations. See documentation on `calc()` for more information.
                Defaults to `FID_DEFAULT_CALC_MODE` ("clean").

        Raises:
            ValueError: Error when non-valid `calc_mode`, valid modes are defined by `FID_CALC_MODES`.
        """
        # Check calc_mode
        if calc_mode not in FID_CALC_MODES:
            raise ValueError(
                f"{calc_mode} not supported, supported modes: {FID_CALC_MODES}"
            )

        # Calculate custom statistics
        ds = self.get_dataset()
        fid.make_custom_stats(
            ds.get_name(ds.get_resolution()), str(ds.get_image_dir()), mode=calc_mode
        )

    def _is_ready(self, calc_mode=FID_DEFAULT_CALC_MODE) -> bool:
        """
        Checks if compound metric is ready for calculations.

        Args:
            calc_mode (str, optional): Calc mode determines FID implementation, different statistics
                needed for different implementations. See documentation on `calc()` for more information.
                Defaults to `FID_DEFAULT_CALC_MODE` ("clean").

        Raises:
            ValueError: Error when non-valid `calc_mode`, valid modes are defined by `FID_CALC_MODES`.

        Returns:
            bool: True if the compound metrics is ready for calculations.
        """
        # Check calc_mode
        if calc_mode not in FID_CALC_MODES:
            raise ValueError(
                f"{calc_mode} not supported, supported modes: {FID_CALC_MODES}"
            )

        ds = self.get_dataset()

        if type(ds).get_resolution_invariant_name() == "FFHQ" and (
            ds.get_resolution() == 256 or ds.get_resolution() == 1024
        ):
            # pre-computed statistic by clean-fid
            return True
        else:
            return fid.test_stats_exists(ds.get_name(), calc_mode)

    def _move_filtered_files(self, source_files: list[Path]) -> Path:
        # Look for temp name not taken
        while True:
            target = (
                Population.POPULATION_ROOT_DIR
                / f"temp_filtered_population{np.random.randint(10000,99999)}"
            )
            if not (target.is_file() or target.is_dir()):
                break

        # Create temp directory
        Path.mkdir(target)

        # Move filtered files to temp directory
        for image_file in source_files:
            image_file.rename(target.joinpath(image_file.name))

        return target

    def _move_filtered_files_back(self, source: Path) -> None:
        target = Population.POPULATION_ROOT_DIR / self.get_population().get_name()
        # Check if source file exists
        if not source.exists():
            raise FileNotFoundError(f"Could not find file: '{source.absolute()}'")

        # Check if target file exists
        if not target.exists():
            raise FileNotFoundError(f"Could not find file: '{target.absolute()}'")

        # Move filtered files back to population directory
        for image_file in source.glob("*"):
            image_file.rename(target.joinpath(image_file.name))

        # Remove temp directory
        source.rmdir()

    def calc(self, filter_bit: int = 1, **parameters: Any) -> Any:
        """
        Calculates the FID given the dataset and the population.

        No setup is needed for FFHQ 256/1024, if using other custom datasets `calc()`
        requires the user to run `setup()` first.

        Args:
            filter_bit (int, optional): Filter bit used to select a subset of the
                population. Defaults to 1 (IdentityFilter).
            calc_mode (str, optional): Either "clean", "legacy_tensorflow, or "legacy_pytorch".
                This decides how the FID score should be calculated, i.e., using clean-fid,
                regular tensorflow implementation, or pytorch implementation. Default is "clean" (clean-fid).
        Raises:
            ValueError: Error when non-valid `calc_mode`, valid modes are defined by `FID_CALC_MODES`.
            ValueError: Error when the name of the dataset in conjunction with the
                specified `calc_mode` don't have a pre-computed statistic.
            RuntimeError: When clean-fid library gets an error.
            FileNotFoundError: When incorrect path is provided when moving files.
        Returns:
            Any: The FID value.
        """
        # Fetch parameters
        calc_mode = self._check_calc_mode(parameters)

        # Move files to temp folder
        uris = self._population.get_filtered_data(filter_bit)[
            self._population.COLUMN_URI
        ]
        uris = [Path(str_path) for str_path in list(uris)]
        pop_path = self._move_filtered_files(uris)

        # Get variables for use in FID
        ds = self.get_dataset()
        resolution = ds.get_resolution()
        fid_score = None

        if type(ds).get_resolution_invariant_name() == "FFHQ" and (
            ds.get_resolution() == 256 or ds.get_resolution() == 1024
        ):
            # Use pre-computed statistic by clean-fid
            try:
                fid_score = fid.compute_fid(
                    str(pop_path),
                    dataset_name=type(ds).get_resolution_invariant_name(),
                    dataset_res=resolution,
                    mode=calc_mode,
                    dataset_split="trainval70k",
                    num_workers=NUM_WORKERS,
                )
            except Exception as error:
                self._move_filtered_files_back(pop_path)
                print("Something went wrong when calculating FID using clean-fid.")
                print(repr(error))
                raise
        else:
            # Use custom pre-computed statistic
            dataset_name = ds.get_name(resolution)

            # Check if statistic exists
            if fid.test_stats_exists(dataset_name, calc_mode):
                try:
                    fid_score = fid.compute_fid(
                        str(pop_path),
                        dataset_name=dataset_name,
                        mode=calc_mode,
                        dataset_split="custom",
                        num_workers=NUM_WORKERS,
                    )
                except Exception as error:
                    # Move back files
                    self._move_filtered_files_back(pop_path)
                    print("Something went when calculating FID using clean-fid.")
                    print(repr(error))
                    raise

            else:
                # Move back files
                self._move_filtered_files_back(pop_path)
                raise ValueError(
                    f"Statistic named '{dataset_name}' with `calc_mode` '{calc_mode}'"
                    " has no statistic. Double check `calc_mode` or run 'setup()'"
                )

        # Move back files
        self._move_filtered_files_back(pop_path)

        # Save result
        self._fid[calc_mode] = fid_score
        return fid_score

    def get(self, calc_if_missing: bool = False, **parameters: Any) -> Any:
        # Check parameters
        calc_mode = self._check_calc_mode(parameters)

        # Check if metric already calculated
        if calc_mode in self._fid.keys() and self._fid[calc_mode] is not None:
            return self._fid[calc_mode]

        # Check if calculate when missing
        elif calc_if_missing:
            return self.calc(**parameters)

        else:
            return None

    def print_result(self) -> None:
        for calc_mode, fid_score in self._fid.items():
            print(calc_mode + " FID: ", fid_score)

    def plot_result(self) -> None:
        pass

    def _check_calc_mode(self, parameters) -> str:
        # Fetch parameters
        if "calc_mode" in parameters.keys():
            calc_mode = parameters["calc_mode"]

            # Check calc_mode
            if calc_mode not in FID_CALC_MODES:
                raise ValueError(
                    f"{calc_mode} not supported, supported modes: {FID_CALC_MODES}"
                )
        else:
            calc_mode = FID_DEFAULT_CALC_MODE
        return calc_mode


import pytest
from pathlib import Path
import tempfile
from django.conf import settings
from snoop import digest, models, pst
from snoop.content_types import guess_content_type

pytestmark = pytest.mark.skipif(not settings.SNOOP_READPST_BINARY,
    reason="SNOOP_READPST_BINARY not set")

PST_JANE_AND_DOE = {
    'parent': None,
    'path': "pst/flags_jane_doe.pst",
    'files': [
        "pst-test-2@aranetic.com/5.eml",
        "pst-test-2@aranetic.com/Inbox/1.eml",
        "pst-test-2@aranetic.com/Inbox/2.eml",
        "pst-test-2@aranetic.com/Inbox/3.eml",
        "pst-test-2@aranetic.com/Inbox/4.eml",
        "pst-test-2@aranetic.com/Inbox/5.eml",
        "pst-test-2@aranetic.com/Inbox/6.eml",
        "pst-test-2@aranetic.com/Sent Items/1.eml",
        "pst-test-2@aranetic.com/Sent Items/2.eml",
    ],
    'md5': '699502e6b8c005e0f2b3d523cf9479cc',
    'sha1': '7638280179f243ad10fcb4cd651bbfb5d979f5ab',
    'filename': 'flags_jane_doe.pst',
    'type': 'email-archive',
}

EMAIL_TWO = {
    'parent': PST_JANE_AND_DOE,
    'path': 'pst-test-2@aranetic.com/Inbox/2.eml',
    'md5': '46e5c10ee1603086e6fcf20acc4d1581',
    'sha1': '23e41ddfb84491bfc593fc7cc9d4b76b5a15e130',
    'type': 'email',
}

@pytest.fixture(autouse=True)
def no_models(monkeypatch):
    def disable(item, attr, default):
        def dummy(*a, **k):
            return default
        monkeypatch.setattr(item, attr, dummy)
    class DummyDocument:
        id = 0
    disable(models.Ocr.objects, 'filter', [])
    disable(models.Ocr.objects, 'all', [])
    disable(models.Document.objects, 'get_or_create', (DummyDocument(), False))

@pytest.yield_fixture(autouse=True)
def archive_dir(monkeypatch):
    with tempfile.TemporaryDirectory() as tmp:
        monkeypatch.setattr(pst, 'CACHE_ROOT', Path(tmp))
        yield

def doc_obj(obj, collection):
    filename = obj.get('filename') or obj['path'].split('/')[-1]
    content_type = guess_content_type(filename)
    doc = models.Document(
        path=obj['path'],
        content_type=content_type,
        filename=filename,
        collection=collection,
    )
    doc.save = lambda *a, **k: None
    if obj.get('sha1'):
        doc.sha1 = obj['sha1']
    if obj.get('md5'):
        doc.md5 = obj['md5']
    if obj.get('parent'):
        doc.container = doc_obj(obj['parent'], collection)
    return doc

def digest_obj(obj, collection):
    return digest.digest(doc_obj(obj, collection))

def assert_archive_consistence(obj, collection):
    data = digest_obj(obj, collection)
    print(data)
    keys = ['filename', 'sha1', 'md5', 'type', 'text']
    for key in keys:
        if key in obj:
            assert obj[key] == data[key]

def test_simple_pst_data(document_collection):
    assert_archive_consistence(PST_JANE_AND_DOE, document_collection)
    assert_archive_consistence(EMAIL_TWO, document_collection)

def test_pst_email(document_collection):
    data = digest_obj(EMAIL_TWO, document_collection)
    assert "This email has never been read." in data['text']


"""Split DBFs into multiple fields."""
__author__ = "Martin Lacayo-Emery <popanalyst@gmail.com>"

import os
import sys
#add absolute path for shapefile library (relative to file import)
sys.path.append(sys.argv[0][:sys.argv[0].rfind("\\")+1]+"\\lib\\shp")
import databasefile

def separateFile(dbfName,fieldName,folder,stem,namingScheme):
    dbf=databasefile.DatabaseFile([],[],[],dbfName)
    fieldIndex=dbf.index(fieldName)
    files=separate(dbf,fieldIndex,stem,namingScheme)

    #make output directory if it does not exist
    if not os.path.isdir(folder):
        os.mkdir(folder)
    for name,dbf in files:
        dbf.writeFile(folder+"\\"+name+".dbf")

def separate(dbf,fieldIndex,stem,namingScheme):
    d={}
    n=[]
    for row in dbf:
        id=row[fieldIndex]
        if d.has_key(id):
            d[id].addRow(row)
        else:
            n.append(id)
            d[id]=databasefile.DatabaseFile(dbf.fieldnames,dbf.fieldspecs,[row])
    results=[]
    if namingScheme==0:
        for id in n:
            results.append((stem+id.strip(),d[id]))
    else:
        for i,id in enumerate(n):
            results.append((stem+str(i),d[id]))
    return results


import os

from wagtail import __version__ as WAGTAIL_VERSION

PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

ALLOWED_HOSTS = ["*"]

DATABASES = {
    "default": {
        "NAME": "wagtailpurge-test.sqlite",
        "ENGINE": "django.db.backends.sqlite3",
    }
}

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
        "LOCATION": "default-location",
    },
    "secondary": {
        "BACKEND": "django.core.cache.backends.dummy.DummyCache",
    },
    "tertiary": {
        "BACKEND": "django.core.cache.backends.dummy.DummyCache",
    },
}

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [os.path.join(PROJECT_DIR, "templates")],
        "APP_DIRS": True,
        "OPTIONS": {
            "context_processors": [
                "django.template.context_processors.debug",
                "django.template.context_processors.request",
                "django.contrib.auth.context_processors.auth",
                "django.contrib.messages.context_processors.messages",
            ],
        },
    }
]

INSTALLED_APPS = [
    "wagtailpurge",
    "wagtailpurge.testapp",
    "modelcluster",
    "taggit",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "django.contrib.sites",
    "wagtail.admin",
    "wagtail.sites",
    "wagtail.search",
    "wagtail.users",
    "wagtail.images",
    "wagtail.documents",
    "wagtail.contrib.frontend_cache",
    "wagtail.contrib.modeladmin",
]
if WAGTAIL_VERSION >= "3":
    INSTALLED_APPS.append("wagtail")
else:
    INSTALLED_APPS.append("wagtail.core")

MIDDLEWARE = [
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
]

ROOT_URLCONF = "wagtailpurge.testapp.urls"
WAGTAIL_SITE_NAME = "Wagtailpurge"
LOGIN_URL = "wagtailadmin_login"
LOGIN_REDIRECT_URL = "wagtailadmin_home"
SECRET_KEY = "fake-key"

# Django i18n
TIME_ZONE = "Europe/London"
USE_TZ = True

# Used in Wagtail emails
BASE_URL = "https://localhost:8000"

# Don't redirect to HTTPS in tests
SECURE_SSL_REDIRECT = False

# Use default static files storage for tests
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.StaticFilesStorage"
STATIC_ROOT = os.path.join(PROJECT_DIR, "static")
STATIC_URL = "/static/"

# By default, Django uses a computationally difficult algorithm for passwords hashing.
# We don't need such a strong algorithm in tests, so use MD5
PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"]

WAGTAILFRONTENDCACHE = {
    "dummy": {
        "BACKEND": "wagtailpurge.utils.DummyFECacheBackend",
        "LOCATION": "http://localhost:8000",
    },
}

WAGTAILIMAGES_IMAGE_MODEL = "testapp.CustomImage"


from transformers import AutoTokenizer, TFAutoModelForSeq2SeqLM

def translate(text: str):
    model_name = "hcho22/opus-mt-ko-en-finetuned-kr-to-en"
    #model_name = "../model/" #if running local
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    model = TFAutoModelForSeq2SeqLM.from_pretrained(model_name)

    input_text = text
    tokenized = tokenizer([input_text], return_tensors='np')
    out = model.generate(**tokenized, max_length=128)

    with tokenizer.as_target_tokenizer():
        result = tokenizer.decode(out[0], skip_special_tokens = True)

    return result


#Result: 100/100
#Solution was keep dividing the number by 2
#until it wasn't even anymore. As if the number was odd, then every even number
#would win the game
for tc in range(int(input())):
    n = int(input())
    while n >= 1:
        if n % 2 != 0: #if number is no longer even
            print(n//2) #then all evens before this odd number is the ans
            break
        else:
            n //=2 #keep dividing while number is even


import logging
from threading import Lock
from time import time

logging.basicConfig(format='%(message)s', filename="../result/GHS.log", level=logging.INFO, filemode='w')
lock = Lock()
def log(time, string):
    with lock:
        logging.info(f'{time:03.3f}) {string}')

class Channel:
    def __init__(self, node):
        self.node = node
        self.times = []
        self.messages = []
        self.mutex = Lock()

    def search(self, left, right, receiveTime):

        while right > left + 1:
            middle = (right + left) // 2

            if receiveTime >= self.times[middle - 1]:
                left = middle
            else:
                right = middle

        if right == left + 1 and receiveTime >= self.times[left]:
            return right

        return left

    def addToQueue(self, receiveTime, message, new=True):
        self.mutex.acquire()

        index = self.search(0, len(self.times), receiveTime)
        self.times.insert(index, receiveTime)
        self.messages.insert(index, message)

        self.mutex.release()

        if new:
            self.node.increaseMessage(message.getSize())
            log((time() - self.node.getTime()), f"node {self.node.getId()} {message}")

    def getMessage(self):

        if len(self.times) > 0 and self.times[0] <= time():
            self.mutex.acquire()
            message = self.messages.pop(0)
            self.times.pop(0)
            self.mutex.release()
            return message

        return None


class Solution:
    def maximumGap(self, nums: List[int]) -> int:
        n = len(nums)
        if n < 2: return 0

        mmax, mmin = float('-inf'), float('inf')

        for num in nums:
            mmax = max(mmax, num)
            mmin = min(mmin, num)

        gap = math.ceil((mmax - mmin) / (n - 1)) or 1
        bucket_max = [float('-inf') for _ in range(n)]
        bucket_min = [float('inf') for _ in range(n)]

        for num in nums:
            index = (num - mmin) // gap
            bucket_max[index] = max(bucket_max[index], num)
            bucket_min[index] = min(bucket_min[index], num)

        maxGap = float('-inf')
        prevMax = mmin

        for i in range(n):
            if bucket_max[i] == float('-inf') and bucket_min[i] == float('inf'): continue

            maxGap = max(maxGap, bucket_min[i] - prevMax)
            prevMax = bucket_max[i]

        return maxGap


import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from time import time

class Particle:
    def __init__(self, dt, r0, b, v0):
        self.m = 1
        self.alpha = -1000

        r = np.sqrt(b*b + r0*r0)
        theta = np.pi-np.arctan(b/r0)

        self.dt = dt
        self.r = r
        self.theta = theta
        self.r_ = v0 * np.cos(theta)
        self.theta_ = -v0 * np.sin(theta) / r

    def getCoords(self):
        return [self.r * np.cos(self.theta), self.r * np.sin(self.theta)]

    def timestep(self):
        r = self.r
        r_ = self.r_
        m = self.m
        alpha = self.alpha
        th = self.theta
        th_ = self.theta_
        r__ = alpha / (m*r*r) + r * th_ * th_
        th__ = -2*r_*th_/r

        self.r_ += r__ * self.dt
        self.r += self.r_ * self.dt
        self.theta_ += th__ * self.dt
        self.theta += self.theta_ * self.dt

def main():
    fig = plt.figure()
    ax = plt.axes(xlim=(-50, 50), ylim=(-50, 50), aspect='equal')
    ax.grid()
    linep, = ax.plot([], [], lw=1)

    ptcl = Particle(0.001, 0.00001, 20, 7.1)

    x = []
    y = []
    def init():
        linep.set_data([], [])
        return linep,

    def animate(i):
        ptcl.timestep()
        coords = ptcl.getCoords()
        x.append(coords[0])
        y.append(coords[1])
        linep.set_data(x, y)
        return linep,
    t0 = time()
    animate(0)
    t1 = time()
    intv = ptcl.dt * 1000 - (t1-t0)
    anim = animation.FuncAnimation(fig, animate, init_func=init, frames=300, interval=intv, blit=True)
    plt.show()

main()


# you can write to stdout for debugging purposes, e.g.
# print("this is a debug message")

def solution(D, S):
    if 1 <= D <= 5:
        multiply_dict = {
            "one": 1,
            "two": 2,
            "three": 3,
            "four": 4,
            "five": 5
        }
        return D * multiply_dict[S]

print(solution(4, "two"))


from sys import stdin

A, B = [int(x) for x in stdin.readline().rstrip().split()]
x, y = A, B
while y > 0:
    x, y = y, x % y
ans = A * B // x
if ans > 10**18:
    print('Large')
else:
    print(ans)


import bpy
from bpy import props
from bpy.props import *
import math
import sys
import mathutils
from mathutils import *
import random
from random import *
import decimal
import time
import gc
import traceback
from bpy.types import Panel
from bpy.types import AnyType
from rna_prop_ui import PropertyPanel
from decimal import *
import threading
#import code
#namespace = globals().copy()
#namespace.update(locals())
#code.interact(local=namespace)

gc.enable()

def makeMaterial(name, diffuse, specular, alpha):
    mat = bpy.data.materials.new(name)
    mat.diffuse_color = diffuse
    mat.diffuse_shader = 'LAMBERT'
    mat.diffuse_intensity = 1.0
    mat.specular_color = specular
    mat.specular_shader = 'COOKTORR'
    mat.specular_intensity = 0.5
    mat.alpha = alpha
    mat.ambient = 1
    return mat

red = makeMaterial('Red',      (1,0,0), (1  ,1  ,1), 1)
yellow = makeMaterial('Yellow',(1,1,0), (1  ,1  ,1), 1)
blue = makeMaterial('Blue',    (0,0,1), (1  ,1  ,1), 1)
green = makeMaterial('Green',  (0,1,0), (0.5,0.5,0), 0.5)
white = makeMaterial('White',  (1,1,1), (0.5,0.5,0), 0.5)
black = makeMaterial('Black',  (0,0,0), (0.5,0.5,0), 0.5)

def setMaterial(ob, mat):
    me = ob.data
    me.materials.append(mat)

def getColor(color):
    if color == 'Red':
       return red
    if color == 'Blue':
       return blue
    if color == 'Yellow':
       return yellow
    if color == 'Green':
       return green
    if color == 'White':
       return white
    if color == 'Black':
       return black
    else:
       return black

def hideObject(ob, C, Instant):
    T = bpy.context.scene.Frames
    ob.Hidden = True
    #ob.hide = False
    pl = bpy.data.objects['Velocity('+str(ob.Num)+')']
    pl.location = (0,0,0) #Move vector to center of object
    ob.location = (0,0,10000) #Move far away from view
    X = C + 120
    if X > T: X = T
    if Instant == False:
        pl.keyframe_insert(data_path="location", index=-1, frame=C)
        ob.keyframe_insert(data_path="location", index=-1, frame=X)
        ob.keyframe_insert(data_path="location", index=-1, frame=T)
    else:
        pl.keyframe_insert(data_path="location", index=-1, frame=C)
        pl.keyframe_insert(data_path="location", index=-1, frame=T)
        ob.keyframe_insert(data_path="location", index=-1, frame=C)
        ob.keyframe_insert(data_path="location", index=-1, frame=T)

def accel(x, v, dt):
    """Some function that determines acceleration from current
    position, velocity, and timestep."""
    return v

def rk4(x, v, a, dt):
    """This should return (position, velocity) tuple object
    after time dt has passed? Done in replacement of rambogogogo()
    x: initial position (number-like object)
    v: initial velocity (number-like object)
    accel: acceleration function accel(x,v,dt) (created above)
    dt: timestep (number)"""
    x1 = x
    v1 = v
    a1 = accel(x1, v1, 0)

    x2 = x + 0.5*v1*dt
    v2 = v + 0.5*a1*dt
    a2 = accel(x2, v2, dt/2.0)

    x3 = x + 0.5*v2*dt
    v3 = v + 0.5*a2*dt
    a3 = accel(x3, v3, dt/2.0)

    x4 = x + v3*dt
    v4 = v + a3*dt
    a4 = accel(x4, v4, dt)

    xf = x + (dt/6.0)*(v1 + 2*v2 + 2*v3 + v4)
    vf = v + (dt/6.0)*(a1 + 2*a2 + 2*a3 + a4)

    return xf, vf

def rambogogogo(ob,i):
    dt = bpy.context.scene.dt
    G = bpy.context.scene.G
    scn = bpy.context.scene
    pl = bpy.data.objects['Velocity('+str(ob.Num)+')']
    Vv = (pl.location * 25.0)
    ob.select = True
    ob.keyframe_insert(data_path="location", index=-1)
    obsize = (ob.dimensions[0] + ob.dimensions[1] + ob.dimensions[2]) / 6
    for a in bpy.data.objects:
        if a.name != ob.name:
            if a.Hidden == False and ob.Hidden == False:
                d = distance(ob,a)
                r = ob.location - a.location
                Fv = -((G*ob.Mass*a.Mass)/(d**2))*r
                Vv += (Fv*dt)/ob.Mass
                if (d < obsize):
                    if ob.Hidden == False:
                        if scn.Inelastic == True:
                            collision(ob,a,0,i)
                        if scn.Elastic == True:
                            collision(ob,a,1,i)
    bpy.ops.transform.translate(value = Vv*dt)
    ob.select = False #Done working with the particle
    pl.select = True
    pl.location = Vv / 25.0
    pl.keyframe_insert(data_path="location", index=-1)
    pl.select = False
    if ob.location.magnitude > 5000: hideObject(ob,i,False)
    return

def collision(A,B,C,i):
    Ma = A.Mass
    Mb = B.Mass
    La = A.location
    Lb = B.location
    plA = bpy.data.objects['Velocity('+str(A.Num)+')']
    plB = bpy.data.objects['Velocity('+str(B.Num)+')']

    Va = plA.location
    Vb = plB.location
    vfA = ((C * Mb) * ((Vb-Va) + (Ma*Va) + (Mb*Vb))) / (Ma+Mb)
    vfB = ((C * Ma) * ((Va-Vb) + (Ma*Va) + (Mb*Vb))) / (Ma+Mb)
    VNew = vfA + vfB
    MNew = Ma + Mb
    LNew = (La + Lb) / 2
    if Ma > Mb:
        B.select = True
        scale = Ma/Mb
        B.location = A.location
        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
        bpy.ops.mesh.delete(type="VERT")
        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
        B.select = False
        A.select = True
    if Ma < Mb:
        A.select = True
        scale = Mb/Ma
        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
        bpy.ops.mesh.delete(type="VERT")
        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
        A.select = False
        B.select = True

def createObject():
    num = bpy.context.scene.Number
    for n in range(num):
        origin = Vector((0,0,0))
        loc = bpy.context.scene
        count = loc.objCounter
        if loc.RandL == True:
            origin = Vector((
            randint(loc.minL, loc.maxL),
            randint(loc.minL, loc.maxL),
            randint(loc.minL, loc.maxL)))
        else:
            origin = loc.Location
        if  loc.AutoS == True:
            object_size = round(uniform(loc.minS, loc.maxS),1)
        else:
            object_size = loc.Size

        bpy.ops.mesh.primitive_uv_sphere_add(
        segments=loc.Segments,
        ring_count=loc.Rings,
        size= object_size,
        location = origin)
        ob = bpy.context.object
        #bpy.types.Object.Size to add custom variables to active object
        #variable can be accessed by bpy.context.object.Size = 1 (READ ONLY)
        #to make writeable variable use bpy.types.Object.Size = MyClass()

        bpy.types.Object.Num = IntProperty()
        bpy.types.Object.Hidden = BoolProperty(name = "Is Hidden")
        bpy.types.Object.Mass = IntProperty()
        bpy.types.Object.Velocity = FloatVectorProperty()
        bpy.types.Object.Saved_Velocity = FloatVectorProperty()
        bpy.types.Object.Saved_Location = FloatVectorProperty()
        bpy.types.Object.Type = StringProperty()
        bpy.types.Object.Size = FloatProperty()

        ob.show_name = False
        ob.Hidden = False #notice from delcaration above
        ob.name = loc.Name + '(' + str(loc.objCounter) + ')'
        ob.data.name = 'Mesh(' + str(loc.objCounter) + ')'
        ob.Num = loc.objCounter
        ob.Size = object_size

        setMaterial(bpy.context.object, getColor(loc.Color))

        T = ob.dimensions[0] + ob.dimensions[1] + ob.dimensions[2]
        base = T / 3 #Average of the objects Three Dimensions
        if loc.AutoM == True: ob.Mass = round(base*(loc.Multiple**loc.Power),0)
        else: ob.Mass = loc.Mass * (loc.Multiple ** loc.Power)

        ob['Saved_Location'] = ob.location    #Default location is saved
        ob['Type'] = 'Particle'

        bpy.ops.mesh.primitive_plane_add()
        pl = bpy.context.object
        pl.name = 'Velocity(' + str(ob.Num) + ')'
        bpy.ops.object.mode_set(mode='EDIT', toggle=False)
        bpy.ops.mesh.delete(type="VERT")
        pl.parent = ob
        pl.Hidden = True
        if loc.RandV == True:
            pl.location[0] = randint(loc.minV, loc.maxV)
            pl.location[1] = randint(loc.minV, loc.maxV)
            pl.location[2] = randint(loc.minV, loc.maxV)
        else: pl.location = loc.Velocity
        pl['Saved_Location'] = pl.location
        pl['Type'] = 'Velocity'
        pl.Num = loc.objCounter
        bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
        loc.objCounter += 1
    return

def distance (A,B):
    (x1,y1,z1) = A.location
    (x2,y2,z2) = B.location
    dist = math.sqrt((x1-x2)**2+(y1-y2)**2+(z1-z2)**2)
    return dist

def run(origin):
    global n
    scn = bpy.context.scene
    t = scn.FrameKeys
    scn.frame_start = 0
    scn.frame_end = scn.Frames
    n = scn.frame_end
    base = int(round(n/60))
    for ob in bpy.data.objects:
        if ob.Type == 'Particle':
            Px = ob.location[0] #Location
            Py = ob.location[1] #Location
            Pz = ob.location[2] #Location
        if ob.Type == 'Velocity':
            Vx = ob.location[0] #Velocity
            Vy = ob.location[1] #Velocity
            Vz = ob.location[2] #Velocity
        Ax = [0.0] #Acceleration
        Ay = [0.0] #Acceleration
        Az = [0.0] #Acceleration

    for i in range(n+1):
        X = int(round(i/base))
        bpy.context.scene.Status = ('%3s%% Complete' % (round(i/n*100,1)))
        sys.stdout.write('\r%3s%% [%s>%s]' % (round(i/n*100,1), '='*X, ' '*(60-X)))
        sys.stdout.flush()
        for object in bpy.data.objects:
           if object.Hidden == False:
               rambogogogo(object,t)
        bpy.ops.anim.change_frame(frame = t)
        t += 1
    gc.collect()

def initGlobalProperties(scn):
    bpy.types.Scene.G = FloatProperty(
        name = "",
        description = "Gravitational Constant",
        default = 0.60,
        step = 1,
        min = 0,
        max = 2000)
    bpy.types.Scene.dt = FloatProperty(
        name = "",
        description = "Delta Time Constant",
        default = 0.0010,
        step = 0.01,
        subtype = 'TIME',
        unit = 'TIME',
        min = 0.0001,
        max = 10,
        precision=3)
    bpy.types.Scene.Frames = IntProperty(
        description = "How far apart should key frames be? Larger number slows movement speed down without changing the Delta Time Constant.",
        name = "",
        default = 1000,
        min = 60,
        max = 999999999)
    bpy.types.Scene.FrameKeys = IntProperty(
        description = "How far apart should key frames be? Larger number slows movement speed down without changing the Delta Time Constant.",
        name = "",
        default = 1,
        min = 0,
        max = 50)
    bpy.types.Scene.Status = StringProperty(
        name = "Status")
    return

initGlobalProperties(bpy.context.scene)

def initLocalProperties(scn):
    bpy.types.Scene.objCounter = bpy.props.IntProperty()
    if scn.objCounter <= 1: scn.objCounter = 1
    bpy.types.Scene.Rings = IntProperty(
        description = "Number of rings, smaller size generates rougher objects.",
        name = "",
        default = 2,
        min = 0,
        max = 25)
    bpy.types.Scene.Segments = IntProperty(
        description = "Number of segments, smaller size generates rougher objects.",
        name = "",
        default = 2,
        min = 0,
        max = 25)
    bpy.types.Scene.Size = FloatProperty(
        description = "Size of the object",
        name = "",
        default = 1.0,
        step=10,
        min = 0.0,
        max = 50.0)
    bpy.types.Scene.Mass = FloatProperty(
        description = "Specific Mass for Each Object",
        name = "",
        default = 3.33,
        step=1,
        min = 0.0,
        max = 500.0)
    bpy.types.Scene.Multiple = IntProperty(
        description = "Multiplier for the mass of each object.",
        name = "",
        default = 10,
        min = -500,
        max = 500)
    bpy.types.Scene.Power = IntProperty(
        description = "Multiplier for the mass of each object.",
        name = "",
        default = 2,
        min = -30,
        max = 30)
    bpy.types.Scene.Number = IntProperty(
        description = "Number of Objects to Generate",
        name = "",
        default = 1,
        step=10,
        min = 0,
        max = 500)
    bpy.types.Scene.minV = IntProperty(
        description = "Minimum Value",
        name = "",
        default = -100,
        min = -5000,
        max = 5000)
    bpy.types.Scene.maxV = IntProperty(
        description = "Maximum Value",
        name = "",
        default = 100,
        min = -5000,
        max = 5000)
    bpy.types.Scene.minL = IntProperty(
        description = "Minimum Value",
        name = "",
        default = -500,
        min = -5000,
        max = 5000)
    bpy.types.Scene.maxL = IntProperty(
        description = "Maximum Value",
        name = "",
        default = 500,
        min = -5000,
        max = 5000)
    bpy.types.Scene.minS = FloatProperty(
        description = "Maximum Value",
        name = "",
        default = 0.1,
        step=1,
        min = 0,
        max = 50.0)
    bpy.types.Scene.maxS = FloatProperty(
        description = "Maximum Value",
        name = "",
        default = 5.0,
        step=1,
        min = 0,
        max = 50.0)
    bpy.types.Scene.Location= IntVectorProperty(
        name="Location",
        description="Location Vector",
        subtype = 'XYZ',
        default=(0, 0, 0))
    bpy.types.Scene.Name = StringProperty(
        default = "Object",
        name = "")
    bpy.types.Scene.Velocity = IntVectorProperty(
        name="Velocity",
        description="Velocity Vector",
        subtype = 'XYZ',
        default=(0, 0, 0))
    bpy.types.Scene.AutoS = BoolProperty(
        name = "Random Object Size",
        description = "If selected, the random range below will be used to generate a random object size between the minimum and maximum values.")
    bpy.types.Scene.Inelastic = BoolProperty(
        name = "Inelastic Collision",
        description = "If selected, when particles collide collisions will be calculated using inelastic properties.")
    bpy.types.Scene.Elastic = BoolProperty(
        name = "Elastic Collision",
        description = "If selected, when particles collide collisions will be calculated using elastic properties.")
    bpy.types.Scene.RandV = BoolProperty(
        name = "Random",
        description = "If selected, the random range below will be used to generate a random vector between the minimum and maximum values.")
    bpy.types.Scene.AutoM = BoolProperty(
        name = "Auto",
        description = "If selected, the size of each Object will be a variable in their mass.")
    bpy.types.Scene.RandL = BoolProperty(
        name = "Random",
        description = "If selected, the random range below will be used to generate a random vector between the minimum and maximum values.")
    bpy.types.Scene.Hidden = BoolProperty(
        name = "Hidden",
        description = "If selected, the script will skip this object in its calculations.")
    bpy.types.Scene.Color = EnumProperty(
        items = [('Red', 'Red', 'One'),
                 ('Blue', 'Blue', 'Two'),
                 ('Yellow', 'Yellow', 'Three'),
                 ('Green', 'Green', 'Four'),
                 ('White', 'White', 'Five'),
                 ('Black', 'Black', 'Six')],
        name = "Color")
    return

initLocalProperties(bpy.context.scene)

def resetGlobal(scn):
    scn['Status'] = "0% Complete"
    scn['FrameKeys'] = 1
    scn['Frames'] = 1000
    scn['G'] = 0.06
    scn['dt'] = 0.0010
    scn['Inelastic'] = True
    scn['Elastic'] = False
    return

def resetLocal(scn):
    scn['Rings'] = 5
    scn['Segments'] = 10
    scn['Size'] = 1.0
    scn['Color'] = 0
    scn['RandL'] = True
    scn['AutoS'] = True
    scn['AutoM'] = True
    scn['RandV'] = True
    scn['Number'] = 1
    scn['Mass'] = 3.33
    scn['Multiple'] = 10
    scn['Name'] = "Particle"
    scn['Power'] = 5
    scn['minV'] = -100
    scn['maxV'] =  100
    scn['minL'] = -100
    scn['maxL'] =  100
    scn['minS'] =  0.10
    scn['maxS'] =  5.00
    scn['Velocity'] = (0, 0, 0)
    scn['Location'] = (0, 0, 0)
    return

class Calculate(bpy.types.Operator):
    bl_idname = "calc.now"
    bl_label = "Calculate Now"
    bl_description = "Calculate the Current Scene / Objects"
    def execute(self, context):
        try: bpy.ops.object.mode_set(mode='OBJECT')
        except:
            print("Warning: bpy.ops.object.mode_set(mode='OBJECT') Failed...")
            sys.stdout.flush()
        run(Vector((0,0,0)))
        return {'FINISHED'}

class Reset_Global(bpy.types.Operator):
    bl_idname = "reset.global"
    bl_label = "Reset Global"
    bl_description = "Reset all of the settings in this Box"
    def execute(self, context):
        resetGlobal(bpy.context.scene)
        return {'FINISHED'}

class Delete_All(bpy.types.Operator):
    bl_idname = "delete.all"
    bl_label = "Delete All"
    bl_description = "Delete all of the objects in the scene"
    def execute(self, context):
        try: bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
        except: pass #If this causes an error thats ok, we just need to try at least once.
        candidate_list = [item.name for item in bpy.data.objects if item.type == "MESH"]
        for object_name in candidate_list:
            bpy.data.objects[object_name].select = True
        bpy.ops.object.delete()
        for item in bpy.data.meshes:
            bpy.data.meshes.remove(item)
        bpy.context.scene.objCounter = 1
        return {'FINISHED'}

class Delete_Selected(bpy.types.Operator):
    bl_idname = "delete.selected"
    bl_label = "Delete Selected"
    bl_description = "Delete the Selected object and its Child objects."
    def execute(self, context):
        bpy.ops.object.delete()
        return {'FINISHED'}

class Clear_Keyframes_All(bpy.types.Operator):
    bl_idname = "clear.keyframes_all"
    bl_label = "Clear Keyframes"
    bl_description = "Clear all of the keyframes for every object in the scene."
    def execute(self, context):
        for ob in bpy.data.objects:
            ob['Hidden'] = False
            ob.select = True
            bpy.ops.anim.keyframe_clear_v3d()
            ob.select = False
        return {'FINISHED'}

class Reset_Velocity_All(bpy.types.Operator):
    bl_idname = "reset.velocity_all"
    bl_label = "Reset Velocities"
    bl_description = "Reset all of the velocites to the saved state."
    def execute(self, context):
        for ob in bpy.data.objects:
            if ob.Type == 'Velocity': ob.location = ob['Saved_Location']
        return {'FINISHED'}

class Save_Velocity_All(bpy.types.Operator):
    bl_idname = "save.velocity_all"
    bl_label = "Save Velocities"
    bl_description = "Saves the velocity vector for all objects."
    def execute(self, context):
        for ob in bpy.data.objects:
            if ob.Type == 'Velocity': ob.location = ob['Saved_Location']
        return {'FINISHED'}

class Reset_Location_All(bpy.types.Operator):
    bl_idname = "reset.location_all"
    bl_label = "Reset Locations"
    bl_description = "Reset all of the object locations to the saved state."
    def execute(self, context):
        for ob in bpy.data.objects:
            if ob.Type == 'Particle': ob.location = ob['Saved_Location']
        return {'FINISHED'}

class Save_Location_All(bpy.types.Operator):
    bl_idname = "save.location_all"
    bl_label = "Save Locations"
    bl_description = "Saves the location for all particle objects."
    def execute(self, context):
        for ob in bpy.data.objects:
            if ob.Type == 'Particle': ob.location = ob['Saved_Location']
        return {'FINISHED'}

class GlobalUI(bpy.types.Panel):
    bl_label = "Orbital Simulation Panel"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"

    def draw(self, context):
        scn = bpy.context.scene
        layout = self.layout

        row = layout.row()
        box = row.box()
        box.label("Global Settings",icon="WORLD")
        split = box.split(percentage=0.60)
        col = split.column(align=True)
        col.label("Gravitational Constant")
        col.label("Delta Time Constant")
        col.label("Insert Frame Every")
        col.label("Frames / Calculations")
        col = split.column(align=True)
        col.prop(scn, 'G')
        col.prop(scn, 'dt')
        col.prop(scn, 'FrameKeys')
        col.prop(scn, 'Frames')

        split = box.split()
        col = split.column(align=True)
        col.prop(scn, 'Inelastic')
        col.prop(scn, 'Elastic')

        split = box.split()
        col = split.column(align=True)
        col.operator("calc.now")
        col.operator("reset.global")
        split = box.split(percentage=0.50)
        col = split.column(align=True)
        col.operator("delete.all")
        col.operator("save.velocity_all")
        col.operator("save.location_all")
        col = split.column(align=True)
        col.operator("delete.selected")
        col.operator("reset.velocity_all")
        col.operator("reset.location_all")
        split = box.split()
        split.operator("clear.keyframes_all")
        box.prop(scn, 'Status')

class LocalUI(bpy.types.Panel):
    bl_label = "Orbital Simulation Panel"
    bl_icon = "WORLD"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    def draw(self, context):
        layout = self.layout
        self = bpy.context.scene
        row = layout.row()
        box = row.box()
        box.label("Object Settings", icon='OBJECT_DATA')

        split = box.split(percentage=0.20)
        col = split.column()
        col.label("Name")
        col = split.column()
        col.prop(self,"Name")

        split = box.split(percentage=0.50)
        col = split.column()
        col.label("Number")
        col.label("Object Mass")

        col = split.column()
        col.prop(self, 'Number')
        col.prop(self, 'AutoM')

        split = box.split(percentage=0.33)
        col = split.column(align=True)
        col.label("Base")
        col.prop(self, 'Mass')
        col = split.column(align=True)
        col.label("Multiple")
        col.prop(self, 'Multiple')
        col = split.column(align=True)
        col.label("Power")
        col.prop(self, 'Power')
        split = box.split()
        col = split.column()
        col.label("Example: 20 * 10 ^ 2")

        split = box.split(percentage=0.50)
        col = split.column(align=True)
        col.prop(self, 'Velocity')

        col = split.column(align=True)
        col.prop(self, 'RandV')
        col.label("Random Range")
        col.prop(self, 'minV')
        col.prop(self, 'maxV')

        split = box.split(percentage=0.50)
        col = split.column(align=True)
        col.prop(self, 'Location')

        col = split.column(align=True)
        col.prop(self, 'RandL')
        col.label("Random Range")
        col.prop(self, 'minL')
        col.prop(self, 'maxL')
        box.prop(self, 'Color')

        split = box.split(percentage=0.60)
        col = split.column()
        col.label("Size")
        col.label("Ring Count")
        col.label("Segments")
        col.prop(self, 'AutoS')

        col = split.column()
        col.prop(self, 'Size')
        col.prop(self, 'Rings')
        col.prop(self, 'Segments')
        col.label("Random Range")
        col.prop(self, 'minS')
        col.prop(self, 'maxS')

        split = box.split(percentage=0.50)
        split.alignment = 'EXPAND'
        col = split.column()
        col.operator("local.variables", text="Create Object(s)").number=2
        col = split.column()
        col.operator("local.variables", text="Reset Settings").number=3
        #self.layout.prop(bpy.context.active_object, '["foo"]')

class Local_Variables(bpy.types.Operator):
    bl_idname = "local.variables"
    bl_label = "Print Variables"
    number = bpy.props.IntProperty()
    box = bpy.props.IntProperty()
    error_message = StringProperty(name="Error Message")

    def execute(self, context):
        if self.number == 2:
            try: bpy.ops.object.mode_set(mode='OBJECT')
            except: pass #If this causes an error thats ok, we just need to try at least once.
            createObject()
        if self.number == 3:
            resetLocal(bpy.context.scene)
        return{'FINISHED'}

def printProp(label, key, scn):
    try:
        val = scn[key]
    except:
        val = 'Undefined'
    print("%s %s %s" % (label, key, val))
    sys.stdout.flush()

class MessageOperator(bpy.types.Operator):
    bl_idname = "error.message"
    bl_label = "Message"
    type = StringProperty()
    message = StringProperty()
    # Below is how to call the above class generating a message box
    # bpy.ops.error.message('INVOKE_DEFAULT',
    # type = "Error",
    # message = 'Found "return" on line %d' % n)
    def execute(self, context):
        self.report({'INFO'}, self.message)
        print(self.message)
        return {'FINISHED'}

    def invoke(self, context, event):
        wm = context.window_manager
        return wm.invoke_popup(self, width=400, height=200)

    def draw(self, context):
        self.layout.label("A message has arrived")
        row = self.layout.split(0.25)
        row.prop(self, "type")
        row.prop(self, "message")
        row = self.layout.split(0.80)
        row.label("")
        row.operator("error.ok")

class OkOperator(bpy.types.Operator):
    bl_idname = "error.ok"
    bl_label = "OK"
    def execute(self, context):
        return {'FINISHED'}

bpy.utils.register_class(OkOperator)
bpy.utils.register_class(MessageOperator)
bpy.utils.register_module(__name__)


#!/usr/bin/env python3
import re
import os
import serial
import threading
import queue
import traceback
import time

class Shapeoko(object):
    """Shapeoko SO1 driver -- interfaces with marlin in gcode"""

    class Axes:
        x='X'
        y='Y'
        z='Z'

    def __init__(self, device, rate=115200, speed=9000, verbose=False, autocalibrate=False):
        """initialise parameters and start main loop;
              device - serial port, e.g. /dev/serial/by-id/shapeoko
              rate - serial baud rate
              speed - initial shapeoko movement speed in mm min^-1
              verbose - print the serial communications to stdout
              autocalibrate - recalibrate the shapeoko after disconnections
                              and return to the last known position"""

        self.device = device
        self.rate = rate
        self._speed = speed
        self.verbose = verbose
        self.autocalibrate = autocalibrate
        self.last = None
        self.journal = None

        # action queue
        self.queue = queue.Queue()
        self.thread = threading.Thread(target=self.main)
        self.thread.daemon = True
        self.thread.start()
        self._com = None

    def main(self):
        """main loop, supports hotplugging"""
        SerialException = serial.serialutil.SerialException
        while True:
            try:
                with serial.Serial(self.device, self.rate, timeout=1) as com:
                    self._com = com
                    self.loop(com)
            except (FileNotFoundError, TypeError, SerialException):
                print("Shapeoko connection error...")
                time.sleep(1)
            except Exception as e:
                print("Unknown error whilst trying to connect to the Shapeoko...")
                print(traceback.format_exc())
                print()
                time.sleep(10)

    def loop(self, com):
        """loop -- a single serial session, sends commands to the
                   shapeoko and sets events when each is complete ('ok')"""

        # the shapeoko sometimes needs a second to startup
        time.sleep(1)
        print("Connected to Shapeoko")

        # recalibrate the shapeoko after hotplugging
        # and return to the last known position
        prequeue = queue.Queue()
        if self.autocalibrate:
            prequeue.put(("G28 XYZ", threading.Event(), [False], 30))
            if self.last:
                pos = "X{x:f} Y{y:f} Z{z:f} F8000".format(**self.last)
                prequeue.put(("G1 %s" % pos, threading.Event(), [False], 30))
            if self.journal:
                prequeue.put(self.journal)

        while com.isOpen():
            # run the autocalibration queue first
            q = self.queue if prequeue.empty() else prequeue

            try:
                # retrueve a queued command
                if q != prequeue:
                    # store the command in progress
                    # in case of cable unplugging
                    self.journal = q.get(True, 1)
                    cmd, event, status, timeout = self.journal
                else:
                    cmd, event, status, timeout = q.get(True, 1)

            except queue.Empty:
                # checks if the cable is unplugged
                # also allows verbose output even when
                # no command is being done
                while True:
                    line = com.readline()
                    try:
                        if len(line) and self.verbose:
                            print(line[:-1].decode())
                        elif not len(line):
                            break
                    except:
                        pass
                continue

            try:
                com.write(("%s\r\n" % cmd).encode())
                com.flush()
                if self.verbose:
                    print("$ %s" % cmd)

                # timeout
                beginning = time.time()
                while True:
                    line = com.readline()

                    # verbose logging and command stati
                    try:
                        msg = line[:-1].decode()
                        if len(msg) and self.verbose:
                            print(msg)
                        status[1].append(msg)
                    except:
                        pass

                    # command complete
                    if line[:2] == b'ok':
                        status[0] = True
                        # quick fix for issues #3 - homing borks movement, reinit fixes it
                        #if cmd.startswith("G28"):
                        #    self._com.close()
                        #    self._com = serial.Serial(self.device, self.rate, timeout=1)
                        break

                    # command timed out
                    if time.time() > beginning + timeout:
                        break
            finally:
                q.task_done()
                event.set()

    def do(self, cmd, timeout=30, nopos=False):
        """do the specified command and block until 'ok' received,
           some commands are asynchronous (e.g. G1) and so do(...)
           may return before completion; use do_wait(...)"""

        status = [False]
        event = threading.Event()
        self.queue.put((cmd, event, status, timeout))
        event.wait(timeout)

        # query the current position so autocalibration can return to it
        if not nopos and self.autocalibrate:
            self.last = self.position()

        return status[0]

    def do_wait(self, cmd, timeout=30, nopos=False):
        """do the specified command and block until all
           queued commands are complete (M400)"""

        beginning = time.time()
        status = self.do(cmd, timeout, nopos=True)
        self.wait(beginning + timeout - time.time(), nopos=nopos)
        return status

    def do_get(self, cmd, timeout=30, nopos=False):
        """do a command and return any status messages received,
           e.g. for determining the current head position"""

        status = [False, []]
        event = threading.Event()
        self.queue.put((cmd, event, status, timeout))
        event.wait(timeout)
        self.wait(timeout, nopos=True)

        # query the current position so autocalibration can return to it
        if not nopos and self.autocalibrate:
            self.last = self.position()

        return status[0], status[1]

    def do_seq(self, *cmds, timeout=30):
        """do a sequence of commands and block until all finished"""

        status = True
        for cmd in ("M400",) + cmds + ("M400",):
            status &= self.do(cmd, timeout)
            if not status:
                break
        return status

    def speed(self, value):
        """change the speed, in mm min^-1
           NB the shapeoko struggles with speed over 9000!"""
        self._speed = min(9000, value)

    def home(self, *axes, timeout=30):
        """calibrate the axes (all of xyz if none specified),
           axes should be a list of axes to calibrate from
           XY.Axes.* (though can in general be given as 'X', ..."""
        cmd = "G28 %s" % ''.join(axes)
        return self.do(cmd, timeout)

    def move(self, x=None, y=None, z=None, timeout=30):
        """move the head to a given position"""

        symbols = ['X', 'Y', 'Z', 'F']
        params = [x, y, z, self._speed]
        args = ' '.join('%c%f' % (symbol,param) for symbol,param in
                    zip(symbols,params) if param is not None)
        return self.do_wait("G1 %s" % args, timeout)

    def position(self, timeout=30, count=True):
        """determine the current stepper-estimated position"""

        status, data = self.do_get("M114", timeout, nopos=True)
        def parse(line):
            try:
                a, b = line.lower().split('count')
                pattern = re.compile(r"([a-z]):\s*([-+]?[0-9]+\.[0-9]+)")
                matches = re.findall(pattern, b if count else a)
                return dict((axis, float(pos)) for axis,pos in matches)
            except:
                return None
        parsed = [p for p in map(parse, data) if p is not None]
        return parsed[-1] if len(parsed) else {}

    def wait(self, timeout=30, nopos=False):
        """wait for all commands to complete"""
        return self.do("M400", nopos=nopos)

    def kill(self):
        """emergency stop the shapeoko"""

        try:
            for _ in range(3):
                print("EMERGENCY STOP!!!")

                # probably not thread safe, but who cares,
                # this is an emergency!!!!
                self._com.write(b'\r\nM112\r\n')
                self._com.flush()
                time.sleep(1)
        finally:
            os._exit(1)

if __name__ == '__main__':
    import cmd
    import glob
    import signal

    class ShapeokoInterpreter(cmd.Cmd):
        """Nice shell for controlling the Shapeoko"""

        prompt = 'Shapeoko# '
        def __init__(self):
            cmd.Cmd.__init__(self)
            self.shap = None
            signal.signal(signal.SIGINT, self.do_kill)

        def emptyline(self):
            pass

        def do_load(self, port):
            """  load [serial]
                     Load a shapeoko.
                         [serial] - Connect to the file /dev/serial/by-id/[serial] """
            self.do_close()
            try:
                if port == "":
                    port = "usb-Arduino__www.arduino.cc__0042_6493633303735140D0A0-if00"
                self.shap = Shapeoko("/dev/serial/by-id/"+str(port), verbose=True)
            except Exception as e:
                print("*** Error opening device: %s" % e)

        def complete_load(self, text, line, begidx, endidx):
            prefix = "/dev/serial/by-id/"
            devices = [a[len(prefix):] for a in glob.glob(prefix + "*")]
            beg = line.partition(' ')[2].strip()
            off = len(beg) - len(text)
            return [a[off:] for a in devices if a.startswith(beg)]

        def do_close(self, *args):
            """  close
                     Close the comm channel with the shapeoko"""
            if self.shap is not None:
                del self.shap
                self.shap = None
                print("Closed already open comm channel...")

        def serial_cmd(method):
            def checked_cmd(self, *args):
                if self.shap is None:
                    print("*** Load a shapeoko first! [load <n>] where n is the ttyACM number")
                    return
                return method(self, *args)
            return checked_cmd

        def help_home(self):
            print("home [xyz]\n\
    Home the axes passed as an argument.\n\
        Usage: home x - Home x axis\n\
            home xy - Home x axis and y axis\n\
            home yz - Home y axis and z axis\n\
            home xyz - Home all axes\n\
            home zy - Home y axis and z axis")

        @serial_cmd
        def do_home(self, axes):
            Axes = Shapeoko.Axes
            handled = 0
            args = []
            if "x" in axes:
                args.append(Axes.x)
                handled = 1
            if "y" in axes:
                args.append(Axes.y)
                handled = 1
            if "z" in axes:
                args.append(Axes.z)
                handled = 1
            if handled is 0:
                print("*** Usage: home [xyz]")
                return
            print("Homing ", args)
            try:
                self.shap.home(*args)
            except:
                print("*** Error sending homing command")

        def help_move(self):
            print("move x y z\n\
    Move the head simultaneously in [x,y,z].\n\
    Must pass all three arguments, use - for no movement\n\
        Usage: move 100 0 0 = move to (100,0,0)\n\
               move 100 100 - = move to (100,100) in x and y direction\n\
        The firmware should prevent overdriving the motors.")

        @serial_cmd
        def do_move(self, mov):
            l = mov.split()
            if(len(l) < 3):
                print("*** Usage: move x y z (Use - for no movement on an axis)")
                return
            l = [(float(a) if a is not "-" else None) for a in l]
            print("Moving x=",l[0],", y=",l[1], ", z=", l[2])
            try:
                self.shap.move(l[0] , l[1], l[2])
            except:
                print("*** Error sending move command")

        @serial_cmd
        def do_send(self, code):
            if code.strip() is "":
                print("*** Usage: send [g-code]")
                return
            try:
                self.shap.do(code)
            except:
                print("*** Error sending g-code")

        @serial_cmd
        def do_speed(self, set):
            if set.strip() is "":
                print("*** Usage: speed [speed in mm min^-1]")
                return
            self.shap.speed(float(set))
            print("Set speed to ", set)

        @serial_cmd
        def do_pos(self, *args):
            pos = self.shap.position()
            print(pos)

        def do_kill(self, *args):
            if self.shap is not None:
                self.shap.kill()

        def do_EOF(self, line):
            self.do_close()
            print("*** Bye!")
            return True

        @serial_cmd
        def do_figure(self, *args):
            self.shap.do_seq("G28 XY", "G1 Y40 F%d"%self.shap._speed, "G3 X80 I40", "G2 I40", "G3 X0 I-40")

        def help_figure(self):
            print("figure\n\
    Draw a figure of 8 in an 80x160 box.")

    ShapeokoInterpreter().cmdloop()


from typing import Any
from airflow.models import BaseOperator
from airflow.utils.context import Context
from airflow.utils.decorators import apply_defaults
from custom.Movielens_hook import MovielensHook
import os
import json

class MovielensFetchRatingsOperator(BaseOperator):
    template_fields = ("_start_date", "_end_date", "_output_path")

    @apply_defaults
    def __init__(
        self,
        conn_id,
        output_path,
        start_date="{{ds}}",
        end_date="{{next_ds}}",
        **kwargs,
    ):
        super(MovielensFetchRatingsOperator, self).__init__(**kwargs)

        self._conn_id = conn_id
        self._output_path = output_path
        self._start_date = start_date
        self._end_date = end_date

    def execute(self, context: Context) -> Any:
        hook = MovielensHook(self._conn_id)

        try:
            self.log.info(
                f"Fetching ratings for {self._start_date} to {self._end_date}"
            )
            ratings = list(
                hook.get_ratings(start_date=self._start_date, end_date=self._end_date)
            )
            self.log.info(f"Fetched {len(ratings)} ratings")
        finally:
            hook.close()

        self.log.info(f"Writing ratings to {self._output_path}")
        output_dir = os.path.dirname(self._output_path)
        os.makedirs(output_dir, exist_ok=True)

        with open(self._output_path, "w") as file_:
            json.dump(ratings, fp=file_)