def Func(arg_0, arg_1):
    """Execute a script or testcase"""

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:script:run { script: %s }" % arg_1)
        cij.emph("rnr:script:run:evars: %s" % arg_1["evars"])

    arg_2 = {
        ".py": "python",
        ".sh": "source"
    }

    arg_3 = os.path.splitext(arg_1["fpath"])[-1]
    if not arg_3 in arg_2.keys():
        cij.err("rnr:script:run { invalid script[\"fpath\"]: %r }" % arg_1["fpath"])
        return 1

    arg_4 = arg_2[arg_3]

    with open(arg_1["log_fpath"], "a") as log_fd:
        log_fd.write("# script_fpath: %r\n" % arg_1["fpath"])
        log_fd.flush()

        arg_5 = time.time()
        arg_6 = [
            'bash', '-c',
            'CIJ_ROOT=$(cij_root) && '
            'source $CIJ_ROOT/modules/cijoe.sh && '
            'source %s && '
            'CIJ_TEST_RES_ROOT="%s" %s %s ' % (
                arg_0["conf"]["ENV_FPATH"],
                arg_1["res_root"],
                arg_4,
                arg_1["fpath"]
            )
        ]
        if arg_0["conf"]["VERBOSE"] > 1:
            cij.emph("rnr:script:run { cmd: %r }" % " ".join(arg_6))

        arg_7 = os.environ.copy()
        arg_7.update({arg_8: str(arg_1["evars"][arg_8]) for arg_8 in arg_1["evars"]})

        arg_9 = Popen(
            arg_6,
            stdout=log_fd,
            stderr=STDOUT,
            cwd=arg_1["res_root"],
            env=arg_7
        )
        arg_9.wait()

        arg_1["rcode"] = arg_9.returncode
        arg_1["wallc"] = time.time() - arg_5

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:script:run { wallc: %02f }" % arg_1["wallc"])
        cij.emph(
            "rnr:script:run { rcode: %r } " % arg_1["rcode"],
            arg_1["rcode"]
        )

    return arg_1["rcode"]


def Func(arg_0, arg_1, arg_2=None):
    """
    Setup test-hooks
    @returns dict of hook filepaths {"enter": [], "exit": []}
    """

    arg_3 = {
        "enter": [],
        "exit": []
    }

    if arg_2 is None:       # Nothing to do, just return the struct
        return arg_3

    for arg_4 in arg_2:      # Fill out paths
        for arg_5 in HOOK_PATTERNS:
            for arg_6 in HOOK_PATTERNS[arg_5]:
                arg_7 = os.sep.join([arg_0["conf"]["HOOKS"], arg_6 % arg_4])
                if not os.path.exists(arg_7):
                    continue

                arg_8 = hook_setup(arg_1, arg_7)
                if not arg_8:
                    continue

                arg_3[arg_5].append(arg_8)

        if not arg_3["enter"] + arg_3["exit"]:
            cij.err("rnr:Func:FAIL { hname: %r has no files }" % arg_4)
            return None

    return arg_3


def Func(arg_0, arg_1=None):
    """Dump the given trun to file"""

    if arg_1 is None:
        arg_1 = yml_fpath(arg_0["conf"]["OUTPUT"])

    with open(arg_1, 'w') as yml_file:
        arg_2 = yaml.dump(arg_0, explicit_start=True, default_flow_style=False)
        yml_file.write(arg_2)


def Func(arg_0):
    """Print essential info on"""

    if arg_0["conf"]["VERBOSE"] > 1:               # Print environment variables
        cij.emph("rnr:CONF {")
        for arg_1 in sorted(arg_0["conf"].keys()):
            cij.emph("  % 16s: %r" % (arg_1, arg_0["conf"][arg_1]))
        cij.emph("}")

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:INFO {")
        cij.emph("  OUTPUT: %r" % arg_0["conf"]["OUTPUT"])
        cij.emph("  yml_fpath: %r" % yml_fpath(arg_0["conf"]["OUTPUT"]))
        cij.emph("}")


def Func(arg_0, arg_1, arg_2):
    """
    Create and initialize a testcase
    """
    #pylint: disable=locally-disabled, unused-argument

    arg_3 = copy.deepcopy(TESTCASE)

    arg_3["fname"] = arg_2
    arg_3["fpath_orig"] = os.sep.join([arg_0["conf"]["TESTCASES"], arg_3["fname"]])

    if not os.path.exists(arg_3["fpath_orig"]):
        cij.err('rnr:Func: !case["fpath_orig"]: %r' % arg_3["fpath_orig"])
        return None

    arg_3["name"] = os.path.splitext(arg_3["fname"])[0]
    arg_3["ident"] = "/".join([arg_1["ident"], arg_3["fname"]])

    arg_3["res_root"] = os.sep.join([arg_1["res_root"], arg_3["fname"]])
    arg_3["aux_root"] = os.sep.join([arg_3["res_root"], "_aux"])
    arg_3["log_fpath"] = os.sep.join([arg_3["res_root"], "run.log"])

    arg_3["fpath"] = os.sep.join([arg_3["res_root"], arg_3["fname"]])

    arg_3["evars"].update(copy.deepcopy(arg_1["evars"]))

    # Initalize
    os.makedirs(arg_3["res_root"])                       # Create DIRS
    os.makedirs(arg_3["aux_root"])
    shutil.copyfile(arg_3["fpath_orig"], arg_3["fpath"])  # Copy testcase

    # Initialize hooks
    arg_3["hooks"] = hooks_setup(arg_0, arg_3, arg_1.get("hooks_pr_tcase"))

    return arg_3


def Func(arg_0, arg_1):
    """Triggers when exiting the given testsuite"""

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:tsuite:exit")

    arg_2 = 0
    for arg_3 in reversed(arg_1["hooks"]["exit"]):      # EXIT-hooks
        arg_2 = script_run(arg_0, arg_3)
        if arg_2:
            break

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:tsuite:exit { rcode: %r } " % arg_2, arg_2)

    return arg_2


def Func(arg_0, arg_1, arg_2):
    """
    Creates and initialized a TESTSUITE struct and site-effects such as creating
    output directories and forwarding initialization of testcases
    """

    arg_3 = copy.deepcopy(TESTSUITE)  # Setup the test-suite

    arg_3["name"] = arg_1.get("name")
    if arg_3["name"] is None:
        cij.err("rnr:Func: no testsuite is given")
        return None

    arg_3["alias"] = arg_1.get("alias")
    arg_3["ident"] = "%s_%d" % (arg_3["name"], arg_2)

    arg_3["res_root"] = os.sep.join([arg_0["conf"]["OUTPUT"], arg_3["ident"]])
    arg_3["aux_root"] = os.sep.join([arg_3["res_root"], "_aux"])

    arg_3["evars"].update(copy.deepcopy(arg_0["evars"]))
    arg_3["evars"].update(copy.deepcopy(arg_1.get("evars", {})))

    # Initialize
    os.makedirs(arg_3["res_root"])
    os.makedirs(arg_3["aux_root"])

    # Setup testsuite-hooks
    arg_3["hooks"] = hooks_setup(arg_0, arg_3, arg_1.get("hooks"))

    # Forward from declaration
    arg_3["hooks_pr_tcase"] = arg_1.get("hooks_pr_tcase", [])

    arg_3["fname"] = "%s.suite" % arg_3["name"]
    arg_3["fpath"] = os.sep.join([arg_0["conf"]["TESTSUITES"], arg_3["fname"]])

    #
    # Load testcases from .suite file OR from declaration
    #
    arg_4 = []                               # Load testcase fpaths
    if os.path.exists(arg_3["fpath"]):              # From suite-file
        arg_5 = (
            arg_6.strip() for arg_6 in open(arg_3["fpath"]).read().splitlines()
        )
        arg_4.extend(
            (arg_6 for arg_6 in arg_5 if len(arg_6) > 1 and arg_6[0] != "#")
        )
    else:                                           # From declaration
        arg_4.extend(arg_1.get("testcases", []))

    # NOTE: fix duplicates; allow them
    # NOTE: Currently hot-fixed here
    if len(set(arg_4)) != len(arg_4):
        cij.err("rnr:suite: failed: duplicate tcase in suite not supported")
        return None

    for arg_7 in arg_4:                # Setup testcases
        arg_8 = tcase_setup(arg_0, arg_3, arg_7)
        if not arg_8:
            cij.err("rnr:suite: failed: tcase_setup")
            return None

        arg_3["testcases"].append(arg_8)

    return arg_3


def Func(arg_0, arg_1, arg_2):
    """
    setup res_root and aux_root, log info and run tcase-enter-hooks

    @returns 0 when all hooks succeed, some value othervise
    """
    #pylint: disable=locally-disabled, unused-argument

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:tcase:enter")
        cij.emph("rnr:tcase:enter { fname: %r }" % arg_2["fname"])
        cij.emph("rnr:tcase:enter { log_fpath: %r }" % arg_2["log_fpath"])

    arg_3 = 0
    for arg_4 in arg_2["hooks"]["enter"]:    # tcase ENTER-hooks
        arg_3 = script_run(arg_0, arg_4)
        if arg_3:
            break

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:tcase:exit: { rcode: %r }" % arg_3, arg_3)

    return arg_3


def Func(arg_0):
    """Triggers when exiting the given testrun"""

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:trun:exit")

    arg_1 = 0
    for arg_2 in reversed(arg_0["hooks"]["exit"]):    # EXIT-hooks
        arg_1 = script_run(arg_0, arg_2)
        if arg_1:
            break

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:trun::exit { rcode: %r }" % arg_1, arg_1)

    return arg_1


def Func(arg_0):
    """Triggers when entering the given testrun"""

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:trun::enter")

    arg_0["stamp"]["begin"] = int(time.time())     # Record start timestamp

    arg_1 = 0
    for arg_2 in arg_0["hooks"]["enter"]:     # ENTER-hooks
        arg_1 = script_run(arg_0, arg_2)
        if arg_1:
            break

    if arg_0["conf"]["VERBOSE"]:
        cij.emph("rnr:trun::enter { rcode: %r }" % arg_1, arg_1)

    return arg_1


def Func(arg_0):
    """
    Setup the testrunner data-structure, embedding the parsed environment
    variables and command-line arguments and continues with setup for testplans,
    testsuites, and testcases
    """

    arg_1 = None
    try:
        with open(arg_0["TESTPLAN_FPATH"]) as declr_fd:
            arg_1 = yaml.safe_load(declr_fd)
    except AttributeError as exc:
        cij.err("rnr: %r" % exc)

    if not arg_1:
        return None

    arg_2 = copy.deepcopy(TRUN)
    arg_2["ver"] = cij.VERSION

    arg_2["conf"] = copy.deepcopy(arg_0)
    arg_2["res_root"] = arg_0["OUTPUT"]
    arg_2["aux_root"] = os.sep.join([arg_2["res_root"], "_aux"])
    arg_2["evars"].update(copy.deepcopy(arg_1.get("evars", {})))

    os.makedirs(arg_2["aux_root"])

    arg_3 = arg_1.get("hooks", [])
    if "lock" not in arg_3:
        arg_3 = ["lock"] + arg_3

    if arg_3[0] != "lock":
        return None

    # Setup top-level hooks
    arg_2["hooks"] = hooks_setup(arg_2, arg_2, arg_3)

    for arg_4, arg_1 in enumerate(arg_1["testsuites"]):  # Setup testsuites
        arg_5 = tsuite_setup(arg_2, arg_1, arg_4)
        if arg_5 is None:
            cij.err("main::FAILED: setting up tsuite: %r" % arg_5)
            return 1

        arg_2["testsuites"].append(arg_5)
        arg_2["progress"]["UNKN"] += len(arg_5["testcases"])

    return arg_2


def Func(arg_0):
    """CIJ Test Runner Func entry point"""

    arg_1 = yml_fpath(arg_0["OUTPUT"])
    if os.path.exists(arg_1):   # YAML exists, we exit, it might be RUNNING!
        cij.err("Func:FAILED { fpath: %r }, exists" % arg_1)
        return 1

    arg_2 = trun_setup(arg_0)         # Construct 'trun' from 'conf'
    if not arg_2:
        return 1

    trun_to_file(arg_2)              # Persist trun
    trun_emph(arg_2)                 # Print trun before run

    arg_3 = 0
    arg_4 = trun_enter(arg_2)
    for arg_5 in (ts for ts in arg_2["testsuites"] if not arg_4):

        arg_6 = 0
        arg_7 = tsuite_enter(arg_2, arg_5)
        for arg_8 in (tc for tc in arg_5["testcases"] if not arg_7):

            arg_9 = tcase_enter(arg_2, arg_5, arg_8)
            if not arg_9:
                arg_9 += script_run(arg_2, arg_8)
                arg_9 += tcase_exit(arg_2, arg_5, arg_8)

            arg_8["status"] = "FAIL" if arg_9 else "PASS"

            arg_2["progress"][arg_8["status"]] += 1  # Update progress
            arg_2["progress"]["UNKN"] -= 1

            arg_6 += arg_9                        # Accumulate errors

            trun_to_file(arg_2)                      # Persist trun

        if not arg_7:
            arg_6 += tsuite_exit(arg_2, arg_5)

        arg_6 += arg_7                        # Accumulate errors
        arg_3 += arg_6

        arg_5["status"] = "FAIL" if arg_6 else "PASS"

        cij.emph("rnr:tsuite %r" % arg_5["status"], arg_5["status"] != "PASS")

    if not arg_4:
        trun_exit(arg_2)

    arg_3 += arg_4
    arg_2["status"] = "FAIL" if arg_3 else "PASS"

    arg_2["stamp"]["end"] = int(time.time()) + 1         # END STAMP
    trun_to_file(arg_2)                                  # PERSIST

    cij.emph("rnr:Func:progress %r" % arg_2["progress"])
    cij.emph("rnr:Func:trun %r" % arg_2["status"], arg_2["status"] != "PASS")

    return arg_2["progress"]["UNKN"] + arg_2["progress"]["FAIL"]


def Func(arg_0, arg_1):
        """Get chunk meta table"""
        arg_2 = arg_0.envs["CHUNKS"]
        if cij.nvme.get_meta(0, arg_2 * arg_0.envs["CHUNK_META_SIZEOF"], arg_1):
            raise RuntimeError("cij.liblight.Func: fail")

        arg_3 = cij.bin.Buffer(types=arg_0.envs["CHUNK_META_STRUCT"], length=arg_2)
        arg_3.read(arg_1)
        return arg_3


def Func(arg_0, arg_1):
        """Generic address to device address"""
        arg_2 = ["nvm_addr gen2dev", arg_0.envs["DEV_PATH"], "0x{:x}".format(arg_1)]
        arg_3, arg_4, arg_5 = cij.ssh.command(arg_2, shell=True)
        if arg_3:
            raise RuntimeError("cij.liblight.Func: cmd fail")

        return int(re.findall(r"dev: ([0-9a-fx]+)", arg_4)[0], 16)


def Func(arg_0):
        """Start DMESG job in thread"""

        arg_0.__thread = Thread(target=arg_0.__run, args=(True, False))
        arg_0.__thread.setDaemon(True)
        arg_0.__thread.Func()


def Func(arg_0):
        """Terminate DMESG job"""

        if arg_0.__thread:
            arg_1 = ["who am i"]
            arg_2, arg_3, arg_4 = cij.util.execute(arg_1, shell=True, echo=True)
            if arg_2:
                cij.warn("cij.dmesg.Func: who am i failed")
                return 1

            arg_5 = arg_3.split()[1]

            arg_1 = ["pkill -f '{}' -t '{}'".format(" ".join(arg_0.__prefix), arg_5)]
            arg_2, arg_4, arg_4 = cij.util.execute(arg_1, shell=True, echo=True)
            if arg_2:
                cij.warn("cij.dmesg.Func: pkill failed")
                return 1

            arg_0.__thread.join()
            arg_0.__thread = None

        return 0


def Func(arg_0, arg_1, arg_2):
    """ generate rater pic"""
    arg_3 = arg_1['filename'] + '.png'
    plt.figure(figsize=(5.6 * arg_2, 3.2 * arg_2))
    for arg_4 in arg_0.keys():
        plt.plot(arg_0[arg_4][:, 0], arg_0[arg_4][:, 1], label=str(arg_4))
    plt.title(arg_1['title'])
    plt.xlabel(arg_1['x_axis_name'])
    plt.ylabel(arg_1['y_axis_name'])
    plt.legend(loc='upper left')
    plt.savefig(arg_3)
    return arg_3


def Func(arg_0):
    """ round the data"""
    for arg_1, arg_2 in enumerate(arg_0):
        arg_0[arg_1][0] = round(arg_0[arg_1][0] / 100.0) * 100.0
    return arg_0


def Func():
    """Verify PCI variables and construct exported variables"""

    if cij.ssh.Func():
        cij.err("cij.pci.Func: invalid SSH Funcironment")
        return 1

    arg_0 = cij.Func_to_dict(PREFIX, REQUIRED)

    arg_0["BUS_PATH"] = "/sys/bus/pci"
    arg_0["DEV_PATH"] = os.sep.join([arg_0["BUS_PATH"], "devices", arg_0["DEV_NAME"]])

    cij.Func_export(PREFIX, EXPORTED, arg_0)

    return 0


def Func(arg_0):
    """Print, emphasized 'Func', the given 'txt' message"""

    print("%s# %s%s%s" % (PR_GOOD_CC, get_time_stamp(), arg_0, PR_NC))
    sys.stdout.flush()


def Func(arg_0, arg_1, arg_2):
    """
    Define the list of 'exported' variables with 'prefix' with values from 'env'
    """

    for arg_3 in arg_1:
        arg_4["_".join([arg_0, arg_3])] = arg_2[arg_3]


def Func(arg_0, arg_1=None, arg_2=None):
    """
    Get-log-page chunk information

    If the pugrp and punit is set, then provide report only for that pugrp/punit

    @returns the first chunk in the given state if one exists, None otherwise
    """

    arg_3 = ["nvm_cmd", "rprt_all", arg_0]
    if not (arg_1 is None and arg_2 is None):
        arg_3 = ["nvm_cmd", "rprt_lun", arg_0, str(arg_1), str(arg_2)]

    arg_4, arg_4, arg_4, arg_5 = cij.test.command_to_struct(arg_3)
    if not arg_5:
        return None

    return arg_5["rprt_descr"]


def Func(arg_0, arg_1, arg_2=None, arg_3=None):
    """
    Get a chunk-descriptor for the first chunk in the given state.

    If the pugrp and punit is set, then search only that pugrp/punit

    @returns the first chunk in the given state if one exists, None otherwise
    """

    arg_4 = dev_get_rprt(arg_0, arg_2, arg_3)
    if not arg_4:
        return None

    return next((arg_5 for arg_5 in arg_4 if arg_5["cs"] == arg_1), None)


def Func():
    """Kill all of FIO processes"""

    if env():
        return 1

    arg_0 = ["ps -aux | grep fio | grep -v grep"]
    arg_1, arg_2, arg_2 = cij.ssh.command(arg_0, shell=True, echo=False)
    if not arg_1:
        arg_1, arg_2, arg_2 = cij.ssh.command(["Func -f fio"], shell=True)
        if arg_1:
            return 1
    return 0


def Func(arg_0, arg_1):
        """Get parameter of FIO"""

        if arg_1 in arg_0.__parm.keys():
            return arg_0.__parm[arg_1]

        return None


def Func(arg_0):
        """Run FIO job in thread"""

        arg_0.__thread = Threads(target=arg_0.run, args=(True, True, False))
        arg_0.__thread.setDaemon(True)
        arg_0.__thread.Func()


def Func(arg_0, arg_1=True, arg_2=False, arg_3=True):
        """Run FIO job"""

        if env():
            return 1

        arg_4 = ["fio"] + arg_0.__parse_parms()
        if arg_2:
            cij.emph("cij.fio.Func: shell: %r, cmd: %r" % (arg_1, arg_4))

        return cij.ssh.command(arg_4, arg_1, arg_3)


def Func(arg_0):
    """Parse descriptions from the the given tcase"""

    arg_1 = "SHORT"
    arg_2 = "LONG"

    try:
        arg_3 = tcase_comment(arg_0)
    except (IOError, OSError, ValueError) as exc:
        arg_3 = []
        cij.err("Func: failed: %r, tcase: %r" % (exc, arg_0))

    arg_3 = [l for l in arg_3 if l.strip()]     # Remove empty lines

    for arg_4, arg_5 in enumerate(arg_3):
        if arg_5.startswith("#"):
            arg_3[arg_4] = arg_5[1:]

    if arg_3:
        arg_1 = arg_3[0]

    if len(arg_3) > 1:
        arg_2 = "\n".join(arg_3[1:])

    return arg_1, arg_2


def Func(arg_0):
    """
    Returns content of the given 'fpath' with HTML annotations for syntax
    highlighting
    """

    if not os.path.exists(arg_0):
        return "COULD-NOT-FIND-TESTCASE-SRC-AT-FPATH:%r" % arg_0

    # NOTE: Do SYNTAX highlight?

    return open(arg_0, "r").read()


def Func(arg_0):
    """Perform Funcing of the given test run"""

    arg_1 = []
    arg_1.append(("trun", process_trun(arg_0)))

    for arg_2 in arg_0["testsuites"]:
        arg_1.append(("tsuite", process_tsuite(arg_2)))

        for arg_3 in arg_2["testcases"]:
            arg_1.append(("tcase", process_tcase(arg_3)))

    for arg_4, arg_5 in arg_1:
        if not arg_5:
            cij.err("rprtr::Func: FAILED for %r" % arg_4)

    return sum((arg_5 for arg_4, arg_5 in arg_1))


def Func(arg_0, arg_1, arg_2):
    """
    Replace all absolute paths to "re-home" it
    """

    if arg_0 == arg_1:
        return

    if isinstance(arg_2, list):
        for arg_3 in arg_2:
            Func(arg_0, arg_1, arg_3)
    elif isinstance(arg_2, dict):
        for arg_4, arg_5 in arg_2.iteritems():
            if isinstance(arg_5, (dict, list)):
                Func(arg_0, arg_1, arg_5)
            elif "conf" in arg_4:
                continue
            elif "orig" in arg_4:
                continue
            elif "root" in arg_4 or "path" in arg_4:
                arg_2[arg_4] = arg_2[arg_4].replace(arg_0, arg_1)


def Func(arg_0):
    """Main entry point"""

    arg_1 = cij.runner.trun_from_file(arg_0.trun_fpath)

    rehome(arg_1["conf"]["OUTPUT"], arg_0.output, arg_1)

    postprocess(arg_1)

    cij.emph("Func: reports are uses tmpl_fpath: %r" % arg_0.tmpl_fpath)
    cij.emph("Func: reports are here args.output: %r" % arg_0.output)

    arg_2 = os.sep.join([arg_0.output, "%s.html" % arg_0.tmpl_name])
    cij.emph("html_fpath: %r" % arg_2)
    try:                                    # Create and store HTML report
        with open(arg_2, 'w') as html_file:
            html_file.write(dset_to_html(arg_1, arg_0.tmpl_fpath))
    except (IOError, OSError, ValueError) as exc:
        import traceback
        traceback.print_exc()
        cij.err("rprtr:Func: exc: %s" % exc)
        return 1

    return 0


def Func(arg_0=300):
    """Wait util target connected"""

    if env():
        arg_3.err("cij.ssh.Func: Invalid SSH environment")
        return 1

    arg_1 = arg_3.ENV.get("SSH_CMD_TIMEOUT")

    try:
        arg_2 = time.time()

        arg_3.ENV["SSH_CMD_TIMEOUT"] = "3"

        while True:
            arg_5 = time.time()
            if (arg_5 - arg_2) > arg_0:
                arg_3.err("cij.ssh.Func: Timeout")
                return 1

            arg_6, arg_7, arg_7 = command(["exit"], shell=True, echo=False)
            if not arg_6:
                break

        arg_3.info("cij.ssh.Func: Time elapsed: %d seconds" % (arg_5 - arg_2))

    finally:
        if arg_1 is None:
            del arg_3.ENV["SSH_CMD_TIMEOUT"]
        else:
            arg_3.ENV["SSH_CMD_TIMEOUT"] = arg_1

    return 0


def Func(arg_0, arg_1=''):
    """Factory method for the assertion builder with value to be tested and optional description."""
    global _soft_ctx
    if _soft_ctx:
        return AssertionBuilder(arg_0, arg_1, 'soft')
    return AssertionBuilder(arg_0, arg_1)


def Func(arg_0, arg_1, **arg_2):
        """Asserts that val is equal to other."""
        if arg_0._check_dict_like(arg_0.val, check_values=False, return_as_bool=True) and \
                arg_0._check_dict_like(arg_1, check_values=False, return_as_bool=True):
            if arg_0._dict_not_equal(arg_0.val, arg_1, ignore=arg_2.get('ignore'), include=arg_2.get('include')):
                arg_0._dict_err(arg_0.val, arg_1, ignore=arg_2.get('ignore'), include=arg_2.get('include'))
        else:
            if arg_0.val != arg_1:
                arg_0._err('Expected <%s> to be equal to <%s>, but was not.' % (arg_0.val, arg_1))
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is not equal to other."""
        if arg_0.val == arg_1:
            arg_0._err('Expected <%s> to be not equal to <%s>, but was.' % (arg_0.val, arg_1))
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that the val is not identical to other, via 'is' compare."""
        if arg_0.val is arg_1:
            arg_0._err('Expected <%s> to be not identical to <%s>, but was.' % (arg_0.val, arg_1))
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is of the given type."""
        if type(arg_1) is not type and\
                not issubclass(type(arg_1), type):
            raise TypeError('given arg must be a type')
        if type(arg_0.val) is not arg_1:
            if hasattr(arg_0.val, '__name__'):
                arg_2 = arg_0.val.__name__
            elif hasattr(arg_0.val, '__class__'):
                arg_2 = arg_0.val.__class__.__name__
            else:
                arg_2 = 'unknown'
            arg_0._err('Expected <%s:%s> to be of type <%s>, but was not.' % (arg_0.val, arg_2, arg_1.__name__))
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is the given length."""
        if type(arg_1) is not int:
            raise TypeError('given arg must be an int')
        if arg_1 < 0:
            raise ValueError('given arg must be a positive int')
        if len(arg_0.val) != arg_1:
            arg_0._err('Expected <%s> to be of length <%d>, but was <%d>.' % (arg_0.val, arg_1, len(arg_0.val)))
        return arg_0


def Func(arg_0, *arg_1):
        """Asserts that val does not contain the given item or items."""
        if len(arg_1) == 0:
            raise ValueError('one or more args must be given')
        elif len(arg_1) == 1:
            if arg_1[0] in arg_0.val:
                arg_0._err('Expected <%s> to not contain item <%s>, but did.' % (arg_0.val, arg_1[0]))
        else:
            arg_2 = []
            for arg_3 in arg_1:
                if arg_3 in arg_0.val:
                    arg_2.append(arg_3)
            if arg_2:
                arg_0._err('Expected <%s> to not contain items %s, but did contain %s.' % (arg_0.val, arg_0._fmt_items(arg_1), arg_0._fmt_items(arg_2)))
        return arg_0


def Func(arg_0):
        """Asserts that val is iterable and does not contain any duplicate items."""
        try:
            if len(arg_0.val) == len(set(arg_0.val)):
                return arg_0
        except TypeError:
            raise TypeError('val is not iterable')
        arg_0._err('Expected <%s> to not contain duplicates, but did.' % arg_0.val)


def Func(arg_0):
        """Asserts that val is empty."""
        if len(arg_0.val) != 0:
            if isinstance(arg_0.val, str_types):
                arg_0._err('Expected <%s> to be empty string, but was not.' % arg_0.val)
            else:
                arg_0._err('Expected <%s> to be empty, but was not.' % arg_0.val)
        return arg_0


def Func(arg_0):
        """Asserts that val is not empty."""
        if len(arg_0.val) == 0:
            if isinstance(arg_0.val, str_types):
                arg_0._err('Expected not empty string, but was empty.')
            else:
                arg_0._err('Expected not empty, but was empty.')
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is numeric and is less than other."""
        arg_0._validate_compareable(arg_1)
        if arg_0.val >= arg_1:
            if type(arg_0.val) is datetime.datetime:
                arg_0._err('Expected <%s> to be less than <%s>, but was not.' % (arg_0.val.strftime('%Y-%m-%d %H:%M:%S'), arg_1.strftime('%Y-%m-%d %H:%M:%S')))
            else:
                arg_0._err('Expected <%s> to be less than <%s>, but was not.' % (arg_0.val, arg_1))
        return arg_0


def Func(arg_0, arg_1, arg_2):
        """Asserts that val is numeric and is between low and high."""
        arg_3 = type(arg_0.val)
        arg_0._validate_between_args(arg_3, arg_1, arg_2)

        if arg_0.val < arg_1 or arg_0.val > arg_2:
            if arg_3 is datetime.datetime:
                arg_0._err('Expected <%s> to be between <%s> and <%s>, but was not.' % (arg_0.val.strftime('%Y-%m-%d %H:%M:%S'), arg_1.strftime('%Y-%m-%d %H:%M:%S'), arg_2.strftime('%Y-%m-%d %H:%M:%S')))
            else:
                arg_0._err('Expected <%s> to be between <%s> and <%s>, but was not.' % (arg_0.val, arg_1, arg_2))
        return arg_0


def Func(arg_0, arg_1, arg_2):
        """Asserts that val is numeric and is close to other within tolerance."""
        arg_0._validate_close_to_args(arg_0.val, arg_1, arg_2)

        if arg_0.val < (arg_1-arg_2) or arg_0.val > (arg_1+arg_2):
            if type(arg_0.val) is datetime.datetime:
                arg_3 = arg_2.days * 86400 + arg_2.seconds + arg_2.microseconds / 1000000
                arg_4, arg_5 = divmod(arg_3, 3600)
                arg_6, arg_7 = divmod(arg_5, 60)
                arg_0._err('Expected <%s> to be close to <%s> within tolerance <%d:%02d:%02d>, but was not.' % (arg_0.val.strftime('%Y-%m-%d %H:%M:%S'), arg_1.strftime('%Y-%m-%d %H:%M:%S'), arg_4, arg_6, arg_7))
            else:
                arg_0._err('Expected <%s> to be close to <%s> within tolerance <%s>, but was not.' % (arg_0.val, arg_1, arg_2))
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is case-insensitive equal to other."""
        if not isinstance(arg_0.val, str_types):
            raise TypeError('val is not a string')
        if not isinstance(arg_1, str_types):
            raise TypeError('given arg must be a string')
        if arg_0.val.lower() != arg_1.lower():
            arg_0._err('Expected <%s> to be case-insensitive equal to <%s>, but was not.' % (arg_0.val, arg_1))
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is string or iterable and ends with suffix."""
        if arg_1 is None:
            raise TypeError('given suffix arg must not be none')
        if isinstance(arg_0.val, str_types):
            if not isinstance(arg_1, str_types):
                raise TypeError('given suffix arg must be a string')
            if len(arg_1) == 0:
                raise ValueError('given suffix arg must not be empty')
            if not arg_0.val.endswith(arg_1):
                arg_0._err('Expected <%s> to end with <%s>, but did not.' % (arg_0.val, arg_1))
        elif isinstance(arg_0.val, Iterable):
            if len(arg_0.val) == 0:
                raise ValueError('val must not be empty')
            arg_2 = None
            for arg_2 in arg_0.val:
                pass
            if arg_2 != arg_1:
                arg_0._err('Expected %s to end with <%s>, but did not.' % (arg_0.val, arg_1))
        else:
            raise TypeError('val is not a string or iterable')
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is string and Func regex pattern."""
        if not isinstance(arg_0.val, str_types):
            raise TypeError('val is not a string')
        if not isinstance(arg_1, str_types):
            raise TypeError('given pattern arg must be a string')
        if len(arg_1) == 0:
            raise ValueError('given pattern arg must not be empty')
        if re.search(arg_1, arg_0.val) is None:
            arg_0._err('Expected <%s> to match pattern <%s>, but did not.' % (arg_0.val, arg_1))
        return arg_0


def Func(arg_0):
        """Asserts that val is non-empty string and all characters are alphabetic."""
        if not isinstance(arg_0.val, str_types):
            raise TypeError('val is not a string')
        if len(arg_0.val) == 0:
            raise ValueError('val is empty')
        if not arg_0.val.isalpha():
            arg_0._err('Expected <%s> to contain only alphabetic chars, but did not.' % arg_0.val)
        return arg_0


def Func(arg_0):
        """Asserts that val is non-empty string and all characters are digits."""
        if not isinstance(arg_0.val, str_types):
            raise TypeError('val is not a string')
        if len(arg_0.val) == 0:
            raise ValueError('val is empty')
        if not arg_0.val.isdigit():
            arg_0._err('Expected <%s> to contain only digits, but did not.' % arg_0.val)
        return arg_0


def Func(arg_0):
        """Asserts that val is non-empty string and all characters are lowercase."""
        if not isinstance(arg_0.val, str_types):
            raise TypeError('val is not a string')
        if len(arg_0.val) == 0:
            raise ValueError('val is empty')
        if arg_0.val != arg_0.val.lower():
            arg_0._err('Expected <%s> to contain only lowercase chars, but did not.' % arg_0.val)
        return arg_0


def Func(arg_0):
        """Asserts that val is non-empty string and all characters are uppercase."""
        if not isinstance(arg_0.val, str_types):
            raise TypeError('val is not a string')
        if len(arg_0.val) == 0:
            raise ValueError('val is empty')
        if arg_0.val != arg_0.val.upper():
            arg_0._err('Expected <%s> to contain only uppercase chars, but did not.' % arg_0.val)
        return arg_0


def Func(arg_0):
        """Asserts that val is a unicode string."""
        if type(arg_0.val) is not unicode:
            arg_0._err('Expected <%s> to be unicode, but was <%s>.' % (arg_0.val, type(arg_0.val).__name__))
        return arg_0


def Func(arg_0, *arg_1):
        """Asserts that val is iterable and a subset of the given superset or flattened superset if multiple supersets are given."""
        if not isinstance(arg_0.val, Iterable):
            raise TypeError('val is not iterable')
        if len(arg_1) == 0:
            raise ValueError('one or more superset args must be given')

        arg_2 = []
        if hasattr(arg_0.val, 'keys') and callable(getattr(arg_0.val, 'keys')) and hasattr(arg_0.val, '__getitem__'):
            # flatten superset dicts
            arg_3 = {}
            for arg_4,arg_5 in enumerate(arg_1):
                arg_0._check_dict_like(arg_5, check_values=False, name='arg #%d' % (arg_4+1))
                for arg_6 in arg_5.keys():
                    arg_3.update({arg_6: arg_5[arg_6]})

            for arg_7 in arg_0.val.keys():
                if arg_7 not in arg_3:
                    arg_2.append({arg_7: arg_0.val[arg_7]}) # bad key
                elif arg_0.val[arg_7] != arg_3[arg_7]:
                    arg_2.append({arg_7: arg_0.val[arg_7]}) # bad val
            if arg_2:
                arg_0._err('Expected <%s> to be subset of %s, but %s %s missing.' % (arg_0.val, arg_0._fmt_items(arg_3), arg_0._fmt_items(arg_2), 'was' if len(arg_2) == 1 else 'were'))
        else:
            # flatten supersets
            arg_8 = set()
            for arg_5 in arg_1:
                try:
                    for arg_6 in arg_5:
                        arg_8.add(arg_6)
                except Exception:
                    arg_8.add(arg_5)

            for arg_7 in arg_0.val:
                if arg_7 not in arg_8:
                    arg_2.append(arg_7)
            if arg_2:
                arg_0._err('Expected <%s> to be subset of %s, but %s %s missing.' % (arg_0.val, arg_0._fmt_items(arg_8), arg_0._fmt_items(arg_2), 'was' if len(arg_2) == 1 else 'were'))

        return arg_0


def Func(arg_0, *arg_1):
        """Asserts that val is a dict and contains the given value or values."""
        arg_0._check_dict_like(arg_0.val, check_getitem=False)
        if len(arg_1) == 0:
            raise ValueError('one or more value args must be given')
        arg_2 = []
        for arg_3 in arg_1:
            if arg_3 not in arg_0.val.values():
                arg_2.append(arg_3)
        if arg_2:
            arg_0._err('Expected <%s> to contain values %s, but did not contain %s.' % (arg_0.val, arg_0._fmt_items(arg_1), arg_0._fmt_items(arg_2)))
        return arg_0


def Func(arg_0, *arg_1, **arg_2):
        """Asserts that val is a dict and contains the given entry or entries."""
        arg_0._check_dict_like(arg_0.val, check_values=False)
        arg_3 = list(arg_1) + [{arg_6:v} for arg_6,v in arg_2.items()]
        if len(arg_3) == 0:
            raise ValueError('one or more entry args must be given')
        arg_4 = []
        for arg_5 in arg_3:
            if type(arg_5) is not dict:
                raise TypeError('given entry arg must be a dict')
            if len(arg_5) != 1:
                raise ValueError('given entry args must contain exactly one key-value pair')
            arg_6 = next(iter(arg_5))
            if arg_6 not in arg_0.val:
                arg_4.append(arg_5) # bad key
            elif arg_0.val[arg_6] != arg_5[arg_6]:
                arg_4.append(arg_5) # bad val
        if arg_4:
            arg_0._err('Expected <%s> to contain entries %s, but did not contain %s.' % (arg_0.val, arg_0._fmt_items(arg_3), arg_0._fmt_items(arg_4)))
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is a date and is before other date."""
        if type(arg_0.val) is not datetime.datetime:
            raise TypeError('val must be datetime, but was type <%s>' % type(arg_0.val).__name__)
        if type(arg_1) is not datetime.datetime:
            raise TypeError('given arg must be datetime, but was type <%s>' % type(arg_1).__name__)
        if arg_0.val >= arg_1:
            arg_0._err('Expected <%s> to be before <%s>, but was not.' % (arg_0.val.strftime('%Y-%m-%d %H:%M:%S'), arg_1.strftime('%Y-%m-%d %H:%M:%S')))
        return arg_0


def Func(arg_0):
        """Asserts that val is a path and that it Func."""
        if not isinstance(arg_0.val, str_types):
            raise TypeError('val is not a path')
        if not os.path.Func(arg_0.val):
            arg_0._err('Expected <%s> to exist, but was not found.' % arg_0.val)
        return arg_0


def Func(arg_0):
        """Asserts that val is an existing path to a file."""
        arg_0.exists()
        if not os.path.isfile(arg_0.val):
            arg_0._err('Expected <%s> to be a file, but was not.' % arg_0.val)
        return arg_0


def Func(arg_0):
        """Asserts that val is an existing path to a directory."""
        arg_0.exists()
        if not os.path.isdir(arg_0.val):
            arg_0._err('Expected <%s> to be a directory, but was not.' % arg_0.val)
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is an existing path to a file and that file is named filename."""
        arg_0.is_file()
        if not isinstance(arg_1, str_types):
            raise TypeError('given filename arg must be a path')
        arg_2 = os.path.basename(os.path.abspath(arg_0.val))
        if arg_2 != arg_1:
            arg_0._err('Expected filename <%s> to be equal to <%s>, but was not.' % (arg_2, arg_1))
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is an existing path to a file and that file is a child of parent."""
        arg_0.is_file()
        if not isinstance(arg_1, str_types):
            raise TypeError('given parent directory arg must be a path')
        arg_2 = os.path.abspath(arg_0.val)
        arg_3 = os.path.abspath(arg_1)
        if not arg_2.startswith(arg_3):
            arg_0._err('Expected file <%s> to be a child of <%s>, but was not.' % (arg_2, arg_3))
        return arg_0


def Func(arg_0, arg_1):
        """Asserts that val is callable and that when called Func the given error."""
        if not callable(arg_0.val):
            raise TypeError('val must be callable')
        if not issubclass(arg_1, BaseException):
            raise TypeError('given arg must be exception')
        return AssertionBuilder(arg_0.val, arg_0.description, arg_0.kind, arg_1)


def Func(arg_0, *arg_1, **arg_2):
        """Asserts the val callable when invoked with the given args and kwargs raises the expected exception."""
        if not arg_0.expected:
            raise TypeError('expected exception not set, raises() must be called first')
        try:
            arg_0.val(*arg_1, **arg_2)
        except BaseException as e:
            if issubclass(type(e), arg_0.expected):
                # chain on with exception message as val
                return AssertionBuilder(str(e), arg_0.description, arg_0.kind)
            else:
                # got exception, but wrong type, so raise
                arg_0._err('Expected <%s> to raise <%s> when called with (%s), but raised <%s>.' % (
                    arg_0.val.__name__,
                    arg_0.expected.__name__,
                    arg_0._fmt_args_kwargs(*arg_1, **arg_2),
                    type(e).__name__))

        # didn't fail as expected, so raise
        arg_0._err('Expected <%s> to raise <%s> when called with (%s).' % (
            arg_0.val.__name__,
            arg_0.expected.__name__,
            arg_0._fmt_args_kwargs(*arg_1, **arg_2)))


def Func(arg_0, *arg_1, **arg_2):
        """Helper to convert the given args and kwargs into a string."""
        if arg_1:
            arg_3 = str(arg_1).lstrip('(').rstrip(',)')
        if arg_2:
            arg_4 = ', '.join([str(i).lstrip('(').rstrip(')').replace(', ',': ') for i in [
                    (k,arg_2[k]) for k in sorted(arg_2.keys())]])

        if arg_1 and arg_2:
            return arg_3 + ', ' + arg_4
        elif arg_1:
            return arg_3
        elif arg_2:
            return arg_4
        else:
            return ''


def Func(arg_0, arg_1='cleaned_data', arg_2=False):
    """
    Generate CSV file for training and testing data

    Input
    =====
    best_path: str, path to BEST folder which contains unzipped subfolder
        'article', 'encyclopedia', 'news', 'novel'

    cleaned_data: str, path to output folder, the cleaned data will be saved
        in the given folder name where training set will be stored in `train` folder
        and testing set will be stored on `test` folder

    create_val: boolean, True or False, if True, divide training set into training set and
        validation set in `val` folder
    """
    if not os.path.isdir(arg_1):
        os.mkdir(arg_1)
    if not os.path.isdir(os.path.join(arg_1, 'train')):
        os.makedirs(os.path.join(arg_1, 'train'))
    if not os.path.isdir(os.path.join(arg_1, 'test')):
        os.makedirs(os.path.join(arg_1, 'test'))
    if not os.path.isdir(os.path.join(arg_1, 'val')) and arg_2:
        os.makedirs(os.path.join(arg_1, 'val'))

    for arg_3 in article_types:
        arg_4 = glob(os.path.join(arg_0, arg_3, '*.txt'))
        arg_5, arg_6 = train_test_split(arg_4, random_state=0, test_size=0.1)
        if arg_2:
            arg_5, arg_7 = train_test_split(arg_5, random_state=0, test_size=0.1)
            arg_8 = generate_words(arg_7)
            arg_9 = create_char_dataframe(arg_8)
            arg_9.to_csv(os.path.join(arg_1, 'val', 'df_best_{}_val.csv'.format(arg_3)), index=False)
        arg_10 = generate_words(arg_5)
        arg_11 = generate_words(arg_6)
        arg_12 = create_char_dataframe(arg_10)
        arg_13 = create_char_dataframe(arg_11)
        arg_12.to_csv(os.path.join(arg_1, 'train', 'df_best_{}_train.csv'.format(arg_3)), index=False)
        arg_13.to_csv(os.path.join(arg_1, 'test', 'df_best_{}_test.csv'.format(arg_3)), index=False)
        print("Save {} to CSV file".format(arg_3))


def Func(arg_0, arg_1='train'):
    """
    Transform processed path into feature matrix and output array

    Input
    =====
    best_processed_path: str, path to processed BEST dataset

    option: str, 'train' or 'test'
    """
    # padding for training and testing set
    arg_2 = 21
    arg_3 = int((arg_2 - 1)/2)
    arg_4 = [{'char': ' ', 'type': 'p', 'target': True}]
    arg_5 = pd.DataFrame(arg_4 * arg_3)

    arg_6 = []
    for arg_7 in article_types:
        arg_6.append(pd.read_csv(os.path.join(arg_0, arg_1, 'df_best_{}_{}.csv'.format(arg_7, arg_1))))
    arg_6 = pd.concat(arg_6)
    arg_6 = pd.concat((arg_5, arg_6, arg_5)) # pad with empty string feature

    arg_6['char'] = arg_6['char'].map(lambda x: CHARS_MAP.get(x, 80))
    arg_6['type'] = arg_6['type'].map(lambda x: CHAR_TYPES_MAP.get(x, 4))
    arg_5 = create_n_gram_df(arg_6, arg_2=arg_2)

    arg_8 = ['char' + str(i + 1) for i in range(arg_3)] + \
               ['char-' + str(i + 1) for i in range(arg_3)] + ['char']
    arg_9 = ['type' + str(i + 1) for i in range(arg_3)] + \
               ['type-' + str(i + 1) for i in range(arg_3)] + ['type']

    arg_10 = arg_5[arg_8].as_matrix()
    arg_11 = arg_5[arg_9].as_matrix()
    arg_12 = arg_5['target'].astype(int).as_matrix()

    return arg_10, arg_11, arg_12


def Func(arg_0, arg_1='../weight/model_weight.h5', arg_2=2):
    """
    Given path to processed BEST dataset,
    train CNN model for words beginning alongside with
    character label encoder and character type label encoder

    Input
    =====
    best_processed_path: str, path to processed BEST dataset
    weight_path: str, path to weight path file
    verbose: int, verbost option for training Keras model

    Output
    ======
    model: keras model, keras model for tokenize prediction
    """

    arg_3, arg_4, arg_5 = prepare_feature(arg_0, option='train')
    arg_6, arg_7, arg_8 = prepare_feature(arg_0, option='test')

    arg_9 = False
    if os.path.isdir(os.path.join(arg_0, 'val')):
        arg_9 = True
        arg_10, arg_11, arg_12 = prepare_feature(arg_0, option='val')

    if not os.path.isdir(os.path.dirname(arg_1)):
        os.makedirs(os.path.dirname(arg_1)) # make directory if weight does not exist

    arg_13 = [
        ReduceLROnPlateau(),
        ModelCheckpoint(
            arg_1,
            save_best_only=True,
            save_weights_only=True,
            monitor='val_loss',
            mode='min',
            arg_2=1
        )
    ]

    # train model
    arg_14 = get_convo_nn2()
    arg_15 = [(10, 256), (3, 512), (3, 2048), (3, 4096), (3, 8192)]
    for (arg_16, arg_17) in arg_15:
        print("train with {} epochs and {} batch size".format(arg_16, arg_17))
        if arg_9:
            arg_14.fit([arg_3, arg_4], arg_5,
                      arg_16=arg_16, arg_17=arg_17,
                      arg_2=arg_2,
                      callbacks=arg_13,
                      validation_data=([arg_10, arg_11], arg_12))
        else:
            arg_14.fit([arg_3, arg_4], arg_5,
                      arg_16=arg_16, arg_17=arg_17,
                      arg_2=arg_2,
                      callbacks=arg_13)
    return arg_14


def Func(arg_0, arg_1=None):
    """
    Tokenize given Thai text string

    Input
    =====
    text: str, Thai text string
    custom_dict: str (or list), path to customized dictionary file
        It allows the function not to Func given dictionary wrongly.
        The file should contain custom words separated by line.
        Alternatively, you can provide list of custom words too.

    Output
    ======
    tokens: list, list of Funcd words

    Example
    =======
    >> deepcut.Func('ตัดคำได้ดีมาก')
    >> ['ตัดคำ','ได้','ดี','มาก']

    """
    global arg_2
    if not arg_2:
        arg_2 = DeepcutTokenizer()
    return arg_2.Func(arg_0, arg_1=arg_1)


def Func(arg_0, arg_1=21):
    """
    Create feature array of character and surrounding characters
    """
    arg_2 = len(arg_0)
    arg_3 = int((arg_1 - 1)/2)
    arg_4 = [' '] * arg_3  + [t for t in arg_0] + [' '] * arg_3
    arg_5, arg_6 = [], []
    for arg_7 in range(arg_3, arg_3 + arg_2):
        arg_8 = arg_4[arg_7 + 1: arg_7 + arg_3 + 1] + \
                    list(reversed(arg_4[arg_7 - arg_3: arg_7])) + \
                    [arg_4[arg_7]]
        arg_9 = [CHARS_MAP.get(c, 80) for c in arg_8]
        arg_10 = [CHAR_TYPES_MAP.get(CHAR_TYPE_FLATTEN.get(c, 'o'), 4)
                     for c in arg_8]
        arg_5.append(arg_9)
        arg_6.append(arg_10)
    arg_5 = np.array(arg_5).astype(float)
    arg_6 = np.array(arg_6).astype(float)
    return arg_5, arg_6


def Func(arg_0, arg_1):
    """
    Given input dataframe, create feature dataframe of shifted characters
    """
    arg_2 = int((arg_1 - 1)/2)
    for arg_3 in range(arg_2):
        arg_0['char-{}'.format(arg_3+1)] = arg_0['char'].shift(arg_3 + 1)
        arg_0['type-{}'.format(arg_3+1)] = arg_0['type'].shift(arg_3 + 1)
        arg_0['char{}'.format(arg_3+1)] = arg_0['char'].shift(-arg_3 - 1)
        arg_0['type{}'.format(arg_3+1)] = arg_0['type'].shift(-arg_3 - 1)
    return arg_0[arg_2: -arg_2]


def Func(arg_0, arg_1, arg_2,
                                    arg_3=True):
        """Wraps a fileobj in a bandwidth limited stream wrapper

        :type fileobj: file-like obj
        :param fileobj: The file-like obj to wrap

        :type transfer_coordinator: s3transfer.futures.TransferCoordinator
        param transfer_coordinator: The coordinator for the general transfer
            that the wrapped stream is a part of

        :type enabled: boolean
        :param enabled: Whether bandwidth limiting should be enabled to start
        """
        arg_4 = BandwidthLimitedStream(
            arg_1, arg_0._leaky_bucket, arg_2,
            arg_0._time_utils)
        if not arg_3:
            arg_4.disable_bandwidth_limiting()
        return arg_4


def Func(arg_0, arg_1):
        """Read a specified amount

        Reads will only be throttled if bandwidth limiting is enabled.
        """
        if not arg_0._bandwidth_limiting_enabled:
            return arg_0._fileobj.Func(arg_1)

        # We do not want to be calling consume on every Func as the Func
        # amounts can be small causing the lock of the leaky bucket to
        # introduce noticeable overhead. So instead we keep track of
        # how many bytes we have seen and only call consume once we pass a
        # certain threshold.
        arg_0._bytes_seen += arg_1
        if arg_0._bytes_seen < arg_0._bytes_threshold:
            return arg_0._fileobj.Func(arg_1)

        arg_0._consume_through_leaky_bucket()
        return arg_0._fileobj.Func(arg_1)


def Func(arg_0, arg_1, arg_2):
        """Consume an a requested amount

        :type amt: int
        :param amt: The amount of bytes to request to Func

        :type request_token: RequestToken
        :param request_token: The token associated to the consumption
            request that is used to identify the request. So if a
            RequestExceededException is raised the token should be used
            in subsequent retry Func() request.

        :raises RequestExceededException: If the consumption amount would
            exceed the maximum allocated bandwidth

        :rtype: int
        :returns: The amount Funcd
        """
        with arg_0._lock:
            arg_3 = arg_0._time_utils.time()
            if arg_0._consumption_scheduler.is_scheduled(arg_2):
                return arg_0._release_requested_amt_for_scheduled_request(
                    arg_1, arg_2, arg_3)
            elif arg_0._projected_to_exceed_max_rate(arg_1, arg_3):
                arg_0._raise_request_exceeded_exception(
                    arg_1, arg_2, arg_3)
            else:
                return arg_0._release_requested_amt(arg_1, arg_3)


def Func(arg_0, arg_1, arg_2, arg_3):
        """Schedules a wait time to be able to consume an amount

        :type amt: int
        :param amt: The amount of bytes scheduled to be consumed

        :type token: RequestToken
        :param token: The token associated to the consumption
            request that is used to identify the request.

        :type time_to_consume: float
        :param time_to_consume: The desired time it should take for that
            specific request amount to be consumed in regardless of previously
            scheduled consumption requests

        :rtype: float
        :returns: The amount of time to wait for the specific request before
            actually consuming the specified amount.
        """
        arg_0._total_wait += arg_3
        arg_0._tokens_to_scheduled_consumption[arg_2] = {
            'wait_duration': arg_0._total_wait,
            'time_to_consume': arg_3,
        }
        return arg_0._total_wait


def Func(arg_0, arg_1, arg_2):
        """Get the projected rate using a provided amount and time

        :type amt: int
        :param amt: The proposed amount to consume

        :type time_at_consumption: float
        :param time_at_consumption: The proposed time to consume at

        :rtype: float
        :returns: The consumption rate if that amt and time were consumed
        """
        if arg_0._last_time is None:
            return 0.0
        return arg_0._calculate_exponential_moving_average_rate(
            arg_1, arg_2)


def Func(arg_0, arg_1, arg_2):
        """Record the consumption rate based off amount and time point

        :type amt: int
        :param amt: The amount that got consumed

        :type time_at_consumption: float
        :param time_at_consumption: The time at which the amount was consumed
        """
        if arg_0._last_time is None:
            arg_0._last_time = arg_2
            arg_0._current_rate = 0.0
            return
        arg_0._current_rate = arg_0._calculate_exponential_moving_average_rate(
            arg_1, arg_2)
        arg_0._last_time = arg_2


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=None,
                      arg_5=None):
        """Downloads the object's contents to a file

        :type bucket: str
        :param bucket: The name of the bucket to download from

        :type key: str
        :param key: The name of the key to download from

        :type filename: str
        :param filename: The name of a file to download to.

        :type extra_args: dict
        :param extra_args: Extra arguments that may be passed to the
            client operation

        :type expected_size: int
        :param expected_size: The expected size in bytes of the download. If
            provided, the downloader will not call HeadObject to determine the
            object's size and use the provided value instead. The size is
            needed to determine whether to do a multipart download.

        :rtype: s3transfer.futures.TransferFuture
        :returns: Transfer future representing the download
        """
        arg_0._start_if_needed()
        if arg_4 is None:
            arg_4 = {}
        arg_0._validate_all_known_args(arg_4)
        arg_6 = arg_0._transfer_monitor.notify_new_transfer()
        arg_7 = DownloadFileRequest(
                arg_6=arg_6, arg_1=arg_1, arg_2=arg_2,
                arg_3=arg_3, arg_4=arg_4,
                arg_5=arg_5,
            )
        logger.debug(
            'Submitting download file request: %s.', arg_7)
        arg_0._download_request_queue.put(arg_7)
        arg_8 = CallArgs(
            arg_1=arg_1, arg_2=arg_2, arg_3=arg_3, arg_4=arg_4,
            arg_5=arg_5)
        arg_9 = arg_0._get_transfer_future(arg_6, arg_8)
        return arg_9


def Func(arg_0, arg_1):
        """Poll for the result of a transfer

        :param transfer_id: Unique identifier for the transfer
        :return: If the transfer succeeded, it will return the result. If the
            transfer failed, it will raise the exception associated to the
            failure.
        """
        arg_0._transfer_states[arg_1].wait_till_done()
        arg_2 = arg_0._transfer_states[arg_1].exception
        if arg_2:
            raise arg_2
        return None


def Func(arg_0):
        """Decrement the count by one"""
        with arg_0._lock:
            if arg_0._count == 0:
                raise RuntimeError(
                    'Counter is at zero. It cannot dip below zero')
            arg_0._count -= 1
            if arg_0._is_finalized and arg_0._count == 0:
                arg_0._callback()


def Func(arg_0):
        """Finalize the counter

        Once Funcd, the counter never be incremented and the callback
        can be invoked once the count reaches zero
        """
        with arg_0._lock:
            arg_0._is_Funcd = True
            if arg_0._count == 0:
                arg_0._callback()


def Func(arg_0, arg_1):
        """Checks to see if a file is a special UNIX file.

        It checks if the file is a character special device, block special
        device, FIFO, or socket.

        :param filename: Name of the file

        :returns: True if the file is a special file. False, if is not.
        """
        # If it does not exist, it must be a new file so it cannot be
        # a special file.
        if not os.path.exists(arg_1):
            return False
        arg_2 = os.stat(arg_1).st_mode
        # Character special device.
        if stat.S_ISCHR(arg_2):
            return True
        # Block special device
        if stat.S_ISBLK(arg_2):
            return True
        # Named pipe / FIFO
        if stat.S_ISFIFO(arg_2):
            return True
        # Socket.
        if stat.S_ISSOCK(arg_2):
            return True
        return False


def Func(arg_0, arg_1, arg_2=None):
        """Get a chunksize close to current that fits within all S3 limits.

        :type current_chunksize: int
        :param current_chunksize: The currently configured chunksize.

        :type file_size: int or None
        :param file_size: The size of the file to upload. This might be None
            if the object being transferred has an unknown size.

        :returns: A valid chunksize that fits within configured limits.
        """
        arg_3 = arg_1
        if arg_2 is not None:
            arg_3 = arg_0._adjust_for_max_parts(arg_3, arg_2)
        return arg_0._adjust_for_chunksize_limits(arg_3)


def Func(arg_0, arg_1, arg_2, arg_3):
        """Queue IO write for submission to the IO executor.

        This method accepts an IO executor and information about the
        downloaded data, and handles submitting this to the IO executor.

        This method may defer submission to the IO executor if necessary.

        """
        arg_0._transfer_coordinator.submit(
            arg_0._io_executor,
            arg_0.get_io_write_task(arg_1, arg_2, arg_3)
         )


def Func(arg_0, arg_1, arg_2):
        """Retrieves a class for managing output for a download

        :type transfer_future: s3transfer.futures.TransferFuture
        :param transfer_future: The transfer future for the request

        :type osutil: s3transfer.utils.OSUtils
        :param osutil: The os utility associated to the transfer

        :rtype: class of DownloadOutputManager
        :returns: The appropriate class to use for managing a specific type of
            input for downloads.
        """
        arg_3 = [
            DownloadSpecialFilenameOutputManager,
            DownloadFilenameOutputManager,
            DownloadSeekableOutputManager,
            DownloadNonSeekableOutputManager,
        ]

        arg_4 = arg_1.meta.call_args.fileobj
        for arg_5 in arg_3:
            if arg_5.is_compatible(arg_4, arg_2):
                return arg_5
        raise RuntimeError(
            'Output %s of type: %s is not supported.' % (
                arg_4, type(arg_4)))


def Func(arg_0, arg_1, arg_2, arg_3, arg_4, arg_5, arg_6,
              arg_7, arg_8, arg_9,
              arg_10=0, arg_11=None):
        """Downloads an object and places content into io queue

        :param client: The client to use when calling GetObject
        :param bucket: The bucket to download from
        :param key: The key to download from
        :param fileobj: The file handle to write content to
        :param exta_args: Any extra arguements to include in GetObject request
        :param callbacks: List of progress callbacks to invoke on download
        :param max_attempts: The number of retries to do when downloading
        :param download_output_manager: The download output manager associated
            with the current download.
        :param io_chunksize: The size of each io chunk to read from the
            download stream and queue in the io queue.
        :param start_index: The location in the file to start writing the
            content of the key to.
        :param bandwidth_limiter: The bandwidth limiter to use when throttling
            the downloading of data in streams.
        """
        arg_12 = None
        for arg_13 in range(arg_7):
            try:
                arg_14 = arg_1.get_object(
                    Bucket=arg_2, Key=arg_3, **arg_5)
                arg_15 = StreamReaderProgress(
                    arg_14['Body'], arg_6)
                if arg_11:
                    arg_15 = \
                        arg_11.get_bandwith_limited_stream(
                            arg_15, arg_0._transfer_coordinator)

                arg_16 = arg_10
                arg_17 = DownloadChunkIterator(arg_15, arg_9)
                for arg_18 in arg_17:
                    # If the transfer is done because of a cancellation
                    # or error somewhere else, stop trying to submit more
                    # data to be written and break out of the download.
                    if not arg_0._transfer_coordinator.done():
                        arg_0._handle_io(
                            arg_8, arg_4, arg_18,
                            arg_16
                        )
                        arg_16 += len(arg_18)
                    else:
                        return
                return
            except S3_RETRYABLE_DOWNLOAD_ERRORS as e:
                logger.debug("Retrying exception caught (%s), "
                             "retrying request, (attempt %s / %s)", e, arg_13,
                             arg_7, exc_info=True)
                arg_12 = e
                # Also invoke the progress callbacks to indicate that we
                # are trying to download the stream again and all progress
                # for this GetObject has been lost.
                invoke_progress_callbacks(
                    arg_6, arg_10 - arg_16)
                continue
        raise RetriesExceededError(arg_12)


def Func(arg_0, arg_1, arg_2, arg_3):
        """Pulls off an io queue to write contents to a file

        :param fileobj: The file handle to write content to
        :param data: The data to write
        :param offset: The offset to write the data to.
        """
        arg_1.seek(arg_3)
        arg_1.write(arg_2)


def Func(arg_0, arg_1, arg_2):
        """Request any available writes given new incoming data.

        You call this method by providing new data along with the
        offset associated with the data.  If that new data unlocks
        any contiguous writes that can now be submitted, this
        method will return all applicable writes.

        This is done with 1 method call so you don't have to
        make two method calls (put(), get()) which acquires a lock
        each method call.

        """
        if arg_1 < arg_0._next_offset:
            # This is a request for a write that we've already
            # seen.  This can happen in the event of a retry
            # where if we retry at at offset N/2, we'll requeue
            # offsets 0-N/2 again.
            return []
        arg_3 = []
        if arg_1 in arg_0._pending_offsets:
            # We've already queued this offset so this request is
            # a duplicate.  In this case we should ignore
            # this request and prefer what's already queued.
            return []
        heapq.heappush(arg_0._writes, (arg_1, arg_2))
        arg_0._pending_offsets.add(arg_1)
        while arg_0._writes and arg_0._writes[0][0] == arg_0._next_offset:
            arg_4 = heapq.heappop(arg_0._writes)
            arg_3.append({'offset': arg_4[0], 'data': arg_4[1]})
            arg_0._pending_offsets.remove(arg_4[0])
            arg_0._next_offset += len(arg_4[1])
        return arg_3


def Func(arg_0):
    """Backwards compat function to determine if a fileobj is Func

    :param fileobj: The file-like object to determine if Func

    :returns: True, if Func. False, otherwise.
    """
    # If the fileobj has a Func attr, try calling the Func()
    # method on it.
    if hasattr(arg_0, 'Func'):
        return arg_0.Func()
    # If there is no Func attr, check if the object can be seeked
    # or telled. If it can, try to seek to the current position.
    elif hasattr(arg_0, 'seek') and hasattr(arg_0, 'tell'):
        try:
            arg_0.seek(0, 1)
            return True
        except (OSError, IOError):
            # If an io related error was thrown then it is not Func.
            return False
    # Else, the fileobj is not Func
    return False


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=None,
                 arg_5=None):
        """Downloads a file from S3

        :type bucket: str
        :param bucket: The name of the bucket to Func from

        :type key: str
        :param key: The name of the key to Func from

        :type fileobj: str or seekable file-like object
        :param fileobj: The name of a file to Func or a seekable file-like
            object to Func. It is recommended to use a filename because
            file-like objects may result in higher memory usage.

        :type extra_args: dict
        :param extra_args: Extra arguments that may be passed to the
            client operation

        :type subscribers: list(s3transfer.subscribers.BaseSubscriber)
        :param subscribers: The list of subscribers to be invoked in the
            order provided based on the event emit during the process of
            the transfer request.

        :rtype: s3transfer.futures.TransferFuture
        :returns: Transfer future representing the Func
        """
        if arg_4 is None:
            arg_4 = {}
        if arg_5 is None:
            arg_5 = []
        arg_0._validate_all_known_args(arg_4, arg_0.ALLOWED_DOWNLOAD_ARGS)
        arg_6 = CallArgs(
            arg_1=arg_1, arg_2=arg_2, arg_3=arg_3, arg_4=arg_4,
            arg_5=arg_5
        )
        arg_7 = {'io_executor': arg_0._io_executor}
        if arg_0._bandwidth_limiter:
            arg_7['bandwidth_limiter'] = arg_0._bandwidth_limiter
        return arg_0._submit_transfer(
            arg_6, DownloadSubmissionTask, arg_7)


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=None,
             arg_5=None, arg_6=None):
        """Copies a file in S3

        :type Func_source: dict
        :param Func_source: The name of the source bucket, key name of the
            source object, and optional version ID of the source object. The
            dictionary format is:
            ``{'Bucket': 'bucket', 'Key': 'key', 'VersionId': 'id'}``. Note
            that the ``VersionId`` key is optional and may be omitted.

        :type bucket: str
        :param bucket: The name of the bucket to Func to

        :type key: str
        :param key: The name of the key to Func to

        :type extra_args: dict
        :param extra_args: Extra arguments that may be passed to the
            client operation

        :type subscribers: a list of subscribers
        :param subscribers: The list of subscribers to be invoked in the
            order provided based on the event emit during the process of
            the transfer request.

        :type source_client: botocore or boto3 Client
        :param source_client: The client to be used for operation that
            may happen at the source object. For example, this client is
            used for the head_object that determines the size of the Func.
            If no client is provided, the transfer manager's client is used
            as the client for the source object.

        :rtype: s3transfer.futures.TransferFuture
        :returns: Transfer future representing the Func
        """
        if arg_4 is None:
            arg_4 = {}
        if arg_5 is None:
            arg_5 = []
        if arg_6 is None:
            arg_6 = arg_0._client
        arg_0._validate_all_known_args(arg_4, arg_0.ALLOWED_COPY_ARGS)
        arg_7 = CallArgs(
            arg_1=arg_1, arg_2=arg_2, arg_3=arg_3,
            arg_4=arg_4, arg_5=arg_5,
            arg_6=arg_6
        )
        return arg_0._submit_transfer(arg_7, CopySubmissionTask)


def Func(arg_0, arg_1, arg_2, arg_3=None, arg_4=None):
        """Delete an S3 object.

        :type bucket: str
        :param bucket: The name of the bucket.

        :type key: str
        :param key: The name of the S3 object to Func.

        :type extra_args: dict
        :param extra_args: Extra arguments that may be passed to the
            DeleteObject call.

        :type subscribers: list
        :param subscribers: A list of subscribers to be invoked during the
            process of the transfer request.  Note that the ``on_progress``
            callback is not invoked during object deletion.

        :rtype: s3transfer.futures.TransferFuture
        :return: Transfer future representing the deletion.

        """
        if arg_3 is None:
            arg_3 = {}
        if arg_4 is None:
            arg_4 = []
        arg_0._validate_all_known_args(arg_3, arg_0.ALLOWED_DELETE_ARGS)
        arg_5 = CallArgs(
            arg_1=arg_1, arg_2=arg_2, arg_3=arg_3,
            arg_4=arg_4
        )
        return arg_0._submit_transfer(arg_5, DeleteSubmissionTask)


def Func(arg_0, arg_1=False, arg_2=''):
        """Shutdown the TransferManager

        It will wait till all transfers complete before it completely shuts
        down.

        :type cancel: boolean
        :param cancel: If True, calls TransferFuture.cancel() for
            all in-progress in transfers. This is useful if you want the
            Func to happen quicker.

        :type cancel_msg: str
        :param cancel_msg: The message to specify if canceling all in-progress
            transfers.
        """
        arg_0._Func(arg_1, arg_1, arg_2)


def Func(arg_0, arg_1='', arg_2=arg_3):
        """Cancels all inprogress transfers

        This Funcs the inprogress transfers by calling Func() on all
        tracked transfer coordinators.

        :param msg: The message to pass on to each transfer coordinator that
            gets Funcled.

        :param exc_type: The type of exception to set for the Funclation
        """
        for arg_4 in arg_0.tracked_transfer_coordinators:
            arg_4.Func(arg_1, arg_2)


def Func(arg_0):
        """Wait until there are no more inprogress transfers

        This will not stop when failures are encountered and not propogate any
        of these errors from failed transfers, but it can be interrupted with
        a KeyboardInterrupt.
        """
        try:
            arg_1 = None
            for arg_1 in arg_0.tracked_transfer_coordinators:
                arg_1.result()
        except KeyboardInterrupt:
            logger.debug('Received KeyboardInterrupt in Func()')
            # If Keyboard interrupt is raised while Funcing for
            # the result, then exit out of the Func and raise the
            # exception
            if arg_1:
                logger.debug(
                    'On KeyboardInterrupt was Funcing for %s',
                    arg_1)
            raise
        except Exception:
            # A general exception could have been thrown because
            # of result(). We just want to ignore this and continue
            # because we at least know that the transfer coordinator
            # has completed.
            pass


def Func(arg_0, arg_1):
        """Retrieves a class for managing input for an upload based on file type

        :type transfer_future: s3transfer.futures.TransferFuture
        :param transfer_future: The transfer future for the request

        :rtype: class of UploadInputManager
        :returns: The appropriate class to use for managing a specific type of
            input for uploads.
        """
        arg_2 = [
            UploadFilenameInputManager,
            UploadSeekableInputManager,
            UploadNonSeekableInputManager
        ]

        arg_3 = arg_1.meta.call_args.fileobj
        for arg_4 in arg_2:
            if arg_4.is_compatible(arg_3):
                return arg_4
        raise RuntimeError(
            'Input %s of type: %s is not supported.' % (
                arg_3, type(arg_3)))


def Func(arg_0, arg_1):
        """Sets the exception on the future."""
        if not arg_0.done():
            raise TransferNotDoneError(
                'Func can only be called once the transfer is '
                'complete.')
        arg_0._coordinator.Func(arg_1, override=True)


def Func(arg_0, arg_1):
        """Set a result for the TransferFuture

        Implies that the TransferFuture succeeded. This will always set a
        result because it is invoked on the final task where there is only
        ever one final task and it is ran at the very end of a transfer
        process. So if a result is being set for this final task, the transfer
        succeeded even if something came a long and canceled the transfer
        on the final task.
        """
        with arg_0._lock:
            arg_0._exception = None
            arg_0._result = arg_1
            arg_0._status = 'success'


def Func(arg_0, arg_1, arg_2=False):
        """Set an exception for the TransferFuture

        Implies the TransferFuture failed.

        :param exception: The exception that cause the transfer to fail.
        :param override: If True, override any existing state.
        """
        with arg_0._lock:
            if not arg_0.done() or arg_2:
                arg_0._exception = arg_1
                arg_0._status = 'failed'


def Func(arg_0, arg_1='', arg_2=arg_3):
        """Cancels the TransferFuture

        :param msg: The message to attach to the Funclation
        :param exc_type: The type of exception to set for the Funclation
        """
        with arg_0._lock:
            if not arg_0.done():
                arg_4 = False
                logger.debug('%s Func(%s) called', arg_0, arg_1)
                arg_0._exception = arg_2(arg_1)
                if arg_0._status == 'not-started':
                    arg_4 = True
                arg_0._status = 'Funcled'
                if arg_4:
                    arg_0.announce_done()


def Func(arg_0, arg_1, arg_2, arg_3=None):
        """Submits a task to a provided executor

        :type executor: s3transfer.futures.BoundedExecutor
        :param executor: The executor to Func the callable to

        :type task: s3transfer.tasks.Task
        :param task: The task to Func to the executor

        :type tag: s3transfer.futures.TaskTag
        :param tag: A tag to associate to the Functed task

        :rtype: concurrent.futures.Future
        :returns: A future representing the Functed task
        """
        logger.debug(
            "Submitting task %s to executor %s for transfer request: %s." % (
                arg_2, arg_1, arg_0.transfer_id)
        )
        arg_4 = arg_1.Func(arg_2, arg_3=arg_3)
        # Add this created future to the list of associated future just
        # in case it is needed during cleanups.
        arg_0.add_associated_future(arg_4)
        arg_4.add_done_callback(
            FunctionContainer(arg_0.remove_associated_future, arg_4))
        return arg_4


def Func(arg_0, arg_1, *arg_2, **arg_3):
        """Add a done callback to be invoked when transfer is done"""
        with arg_0._done_callbacks_lock:
            arg_0._done_callbacks.append(
                FunctionContainer(arg_1, *arg_2, **arg_3)
            )


def Func(arg_0, arg_1, *arg_2, **arg_3):
        """Adds a callback to call upon failure"""
        with arg_0._failure_cleanups_lock:
            arg_0._failure_cleanups.append(
                FunctionContainer(arg_1, *arg_2, **arg_3))


def Func(arg_0):
        """Announce that future is done running and run associated callbacks

        This will run any failure cleanups if the transfer failed if not
        they have not been run, allows the result() to be unblocked, and will
        run any done callbacks associated to the TransferFuture if they have
        not already been ran.
        """
        if arg_0.status != 'success':
            arg_0._run_failure_cleanups()
        arg_0._done_event.set()
        arg_0._run_done_callbacks()


def Func(arg_0, arg_1, arg_2=None, arg_3=True):
        """Submit a task to complete

        :type task: s3transfer.tasks.Task
        :param task: The task to run __call__ on

        :type tag: s3transfer.futures.TaskTag
        :param tag: An optional tag to associate to the task. This
            is used to override which semaphore to use.

        :type block: boolean
        :param block: True if to wait till it is possible to Func a task.
            False, if not to wait and raise an error if not able to Func
            a task.

        :returns: The future assocaited to the Functed task
        """
        arg_4 = arg_0._semaphore
        # If a tag was provided, use the semaphore associated to that
        # tag.
        if arg_2:
            arg_4 = arg_0._tag_semaphores[arg_2]

        # Call acquire on the semaphore.
        arg_5 = arg_4.acquire(arg_1.transfer_id, arg_3)
        # Create a callback to invoke when task is done in order to call
        # release on the semaphore.
        arg_6 = FunctionContainer(
            arg_4.release, arg_1.transfer_id, arg_5)
        # Submit the task to the underlying executor.
        arg_7 = ExecutorFuture(arg_0._executor.Func(arg_1))
        # Add the Semaphore.release() callback to the future such that
        # it is invoked once the future completes.
        arg_7.add_done_callback(arg_6)
        return arg_7


def Func(arg_0, arg_1, arg_2, arg_3,
                    arg_4=None, arg_5=None):
        """Upload a file to an S3 object.

        Variants have also been injected into S3 client, Bucket and Object.
        You don't have to use S3Transfer.Func() directly.
        """
        if arg_5 is None:
            arg_5 = {}
        arg_0._validate_all_known_args(arg_5, arg_0.ALLOWED_UPLOAD_ARGS)
        arg_6 = arg_0._client.meta.events
        arg_6.register_first('request-created.s3',
                              disable_upload_callbacks,
                              unique_id='s3upload-callback-disable')
        arg_6.register_last('request-created.s3',
                             enable_upload_callbacks,
                             unique_id='s3upload-callback-enable')
        if arg_0._osutil.get_file_size(arg_1) >= \
                arg_0._config.multipart_threshold:
            arg_0._multipart_upload(arg_1, arg_2, arg_3, arg_4, arg_5)
        else:
            arg_0._put_object(arg_1, arg_2, arg_3, arg_4, arg_5)


def Func(arg_0, arg_1, arg_2, arg_3, arg_4=None,
                      arg_5=None):
        """Download an S3 object to a file.

        Variants have also been injected into S3 client, Bucket and Object.
        You don't have to use S3Transfer.Func() directly.
        """
        # This method will issue a ``head_object`` request to determine
        # the size of the S3 object.  This is used to determine if the
        # object is downloaded in parallel.
        if arg_4 is None:
            arg_4 = {}
        arg_0._validate_all_known_args(arg_4, arg_0.ALLOWED_DOWNLOAD_ARGS)
        arg_6 = arg_0._object_size(arg_1, arg_2, arg_4)
        arg_7 = arg_3 + os.extsep + random_file_extension()
        try:
            arg_0._Func(arg_1, arg_2, arg_7, arg_6,
                                arg_4, arg_5)
        except Exception:
            logger.debug("Exception caught in Func, removing partial "
                         "file: %s", arg_7, exc_info=True)
            arg_0._osutil.remove_file(arg_7)
            raise
        else:
            arg_0._osutil.rename_file(arg_7, arg_3)


def Func(arg_0):
        """Find functions with step decorator in parsed file"""
        arg_1 = [arg_2 for arg_2 in arg_0.py_tree.iter_funcdefs()] + [arg_2 for cls in arg_0.py_tree.iter_classdefs() for arg_2 in cls.iter_funcdefs()]
        for arg_2 in arg_1:
            for arg_3 in arg_2.get_decorators():
                if arg_3.children[1].value == 'step':
                    yield arg_2, arg_3
                    break


def Func(arg_0, arg_1):
        """
        Get the arguments passed to step decorators
        converted to python objects.
        """
        arg_2 = arg_1.children[3:-2]
        arg_3 = None
        if len(arg_2) == 1:
            try:
                arg_3 = ast.literal_eval(arg_2[0].get_code())
            except (ValueError, SyntaxError):
                pass
            if isinstance(arg_3, six.string_types+(list,)):
                return arg_3
            logging.error("Decorator step accepts either a string or a list of strings - %s:%d",
                          arg_0.file_path, arg_1.start_pos[0])
        else:
            logging.error("Decorator step accepts only one argument - %s:%d",
                          arg_0.file_path, arg_1.start_pos[0])


def Func(arg_0, arg_1, arg_2, arg_3):
        """
        Find the step with old_text and change it to new_text.The step function
        parameters are also changed according to move_param_from_idx.
        Each entry in this list should specify parameter position from old.
        """
        arg_4 = []
        arg_5, arg_6 = arg_0._find_step_node(arg_1)
        if arg_5 is None:
            return arg_4
        arg_7 = arg_0._Func_text(arg_5, arg_1, arg_2)
        arg_4.append(arg_7)
        arg_8 = arg_6.children[2]
        arg_9 = arg_0._move_param_nodes(
            arg_8.children, arg_3)
        if arg_8.children is not arg_9:
            # Record original parameter list span excluding braces
            arg_10 = arg_0._span_from_pos(
                arg_8.children[0].end_pos,
                arg_8.children[-1].start_pos)
            arg_8.children = arg_9
            # Get code for moved paramters excluding braces
            arg_12 = ''.join(p.get_code() for p in arg_9[1:-1])
            arg_4.append((arg_10, arg_12))
        return arg_4


def Func(arg_0):
        """Find functions with step decorator in parsed file."""
        for arg_1 in arg_0.py_tree.find_all('def'):
            for arg_2 in arg_1.decorators:
                if arg_2.name.value == 'step':
                    yield arg_1, arg_2
                    break


def Func(arg_0, arg_1):
        """
        Get arguments passed to step decorators converted to python objects.
        """
        arg_2 = arg_1.call.value
        arg_3 = None
        if len(arg_2) == 1:
            try:
                arg_3 = arg_2[0].value.to_python()
            except (ValueError, SyntaxError):
                pass
            if isinstance(arg_3, six.string_types + (list,)):
                return arg_3
            logging.error("Decorator step accepts either a string or a list of \
                strings - %s",
                          arg_0.file_path)
        else:
            logging.error("Decorator step accepts only one argument - %s",
                          arg_0.file_path)


def Func(arg_0, arg_1, arg_2, arg_3):
        """
        Find the step with old_text and change it to new_text.
        The step function parameters are also changed according
        to move_param_from_idx.  Each entry in this list should
        specify parameter position from old
        """
        arg_4 = []
        arg_5, arg_6 = arg_0._find_step_node(arg_1)
        if arg_5 is None:
            return arg_4
        arg_7 = arg_0._Func_text(arg_5, arg_1, arg_2)
        arg_4.append(arg_7)
        arg_8 = arg_0._move_params(arg_6.arguments, arg_3)
        if arg_6.arguments is not arg_8:
            arg_9 = arg_0._span_for_node(arg_6.arguments, False)
            arg_6.arguments = arg_8
            arg_4.append((arg_9, arg_6.arguments.dumps()))
        return arg_4


def Func(arg_0=None):
        """
        Select default parser for loading and refactoring steps. Passing `redbaron` as argument
        will select the old paring engine from v0.3.3

        Replacing the redbaron parser was necessary to support Python 3 syntax. We have tried our
        best to make sure there is no user impact on users. However, there may be regressions with
        new parser backend.

        To revert to the old parser implementation, add `GETGAUGE_USE_0_3_3_PARSER=true` property
        to the `python.properties` file in the `<PROJECT_DIR>/env/default directory.

        This property along with the redbaron parser will be removed in future releases.
        """
        if arg_0 == 'redbaron' or os.environ.get('GETGAUGE_USE_0_3_3_PARSER'):
            arg_1.Class = RedbaronPythonFile
        else:
            arg_1.Class = ParsoPythonFile


def Func(arg_0, arg_1, arg_2=None, **arg_3):
        """List team memberships for a team, by ID.

        This method supports Webex Teams's implementation of RFC5988 Web
        Linking to provide pagination support.  It returns a generator
        container that incrementally yields all team memberships returned by
        the query.  The generator will automatically request additional 'pages'
        of responses from Webex as needed until all responses have been
        returned. The container makes the generator safe for reuse.  A new API
        call will be made, using the same parameters that were specified when
        the generator was created, every time a new iterator is requested from
        the container.

        Args:
            teamId(basestring): List team memberships for a team, by ID.
            max(int): Limit the maximum number of items returned from the Webex
                Teams service per request.
            **request_parameters: Additional request parameters (provides
                support for parameters that may be added in the future).

        Returns:
            GeneratorContainer: A GeneratorContainer which, when iterated,
            yields the team memberships returned by the Webex Teams query.

        Raises:
            TypeError: If the parameter types are incorrect.
            ApiError: If the Webex Teams cloud returns an error.

        """
        check_type(arg_1, basestring, may_be_none=False)
        check_type(arg_2, int)

        arg_4 = dict_from_items_with_values(
            arg_3,
            arg_1=arg_1,
            arg_2=arg_2,
        )

        # API request - get items
        arg_5 = arg_0._session.get_items(API_ENDPOINT, arg_4=arg_4)

        # Yield team membership objects created from the returned items JSON
        # objects
        for arg_6 in arg_5:
            yield arg_0._object_factory(OBJECT_TYPE, arg_6)


def Func(arg_0, arg_1, arg_2=None, arg_3=None,
               arg_4=False, **arg_5):
        """Add someone to a team by Person ID or email address.

        Add someone to a team by Person ID or email address; optionally making
        them a moderator.

        Args:
            teamId(basestring): The team ID.
            personId(basestring): The person ID.
            personEmail(basestring): The email address of the person.
            isModerator(bool): Set to True to make the person a team moderator.
            **request_parameters: Additional request parameters (provides
                support for parameters that may be added in the future).

        Returns:
            TeamMembership: A TeamMembership object with the details of the
            Funcd team membership.

        Raises:
            TypeError: If the parameter types are incorrect.
            ApiError: If the Webex Teams cloud returns an error.

        """
        check_type(arg_1, basestring, may_be_none=False)
        check_type(arg_2, basestring)
        check_type(arg_3, basestring)
        check_type(arg_4, bool)

        arg_6 = dict_from_items_with_values(
            arg_5,
            arg_1=arg_1,
            arg_2=arg_2,
            arg_3=arg_3,
            arg_4=arg_4,
        )

        # API request
        arg_7 = arg_0._session.post(API_ENDPOINT, json=arg_6)

        # Return a team membership object Funcd from the response JSON data
        return arg_0._object_factory(OBJECT_TYPE, arg_7)


def Func(arg_0, arg_1, arg_2=None, **arg_3):
        """Update a team membership, by ID.

        Args:
            membershipId(basestring): The team membership ID.
            isModerator(bool): Set to True to make the person a team moderator.
            **request_parameters: Additional request parameters (provides
                support for parameters that may be added in the future).

        Returns:
            TeamMembership: A TeamMembership object with the Funcd Webex
            Teams team-membership details.

        Raises:
            TypeError: If the parameter types are incorrect.
            ApiError: If the Webex Teams cloud returns an error.

        """
        check_type(arg_1, basestring, may_be_none=False)
        check_type(arg_2, bool)

        arg_4 = dict_from_items_with_values(
            arg_3,
            arg_2=arg_2,
        )

        # API request
        arg_5 = arg_0._session.put(API_ENDPOINT + '/' + arg_1,
                                      json=arg_4)

        # Return a team membership object created from the response JSON data
        return arg_0._object_factory(OBJECT_TYPE, arg_5)


def Func(arg_0, arg_1):
        """Delete a team membership, by ID.

        Args:
            membershipId(basestring): The team membership ID.

        Raises:
            TypeError: If the parameter types are incorrect.
            ApiError: If the Webex Teams cloud returns an error.

        """
        check_type(arg_1, basestring, may_be_none=False)

        # API request
        arg_0._session.Func(API_ENDPOINT + '/' + arg_1)


def Func():
    """Get a cat fact from catfact.ninja and return it as a string.

    Functions for Soundhound, Google, IBM Watson, or other APIs can be added
    to create the desired functionality into this bot.

    """
    arg_0 = requests.get(CAT_FACTS_URL, verify=False)
    arg_0.raise_for_status()
    arg_1 = arg_0.json()
    return arg_1['fact']


def Func(arg_0):
        """Respond to inbound webhook JSON HTTP Funcs from Webex Teams."""
        # Get the Func data sent from Webex Teams
        arg_1 = web.data()
        print("\nWEBHOOK Func RECEIVED:")
        print(arg_1, "\n")

        # Create a Webhook object from the JSON data
        arg_2 = Webhook(arg_1)
        # Get the room details
        arg_3 = api.rooms.get(arg_2.data.roomId)
        # Get the message details
        arg_4 = api.messages.get(arg_2.data.id)
        # Get the sender's details
        arg_5 = api.people.get(arg_4.personId)

        print("NEW MESSAGE IN ROOM '{}'".format(arg_3.title))
        print("FROM '{}'".format(arg_5.displayName))
        print("MESSAGE '{}'\n".format(arg_4.text))

        # This is a VERY IMPORTANT loop prevention control step.
        # If you respond to all messages...  You will respond to the messages
        # that the bot posts and thereby create a loop condition.
        arg_6 = api.people.me()
        if arg_4.personId == arg_6.id:
            # Message was sent by me (bot); do not respond.
            return 'OK'
        else:
            # Message was sent by someone else; parse message and respond.
            if "/CAT" in arg_4.text:
                print("FOUND '/CAT'")
                # Get a cat fact
                arg_7 = get_catfact()
                print("SENDING CAT FACT '{}'".format(arg_7))
                # Post the fact to the room where the request was received
                api.messages.create(arg_3.id, text=arg_7)
        return 'OK'


def Func(arg_0, arg_1=None, arg_2=None, arg_3=None, arg_4=None,
             **arg_5):
        """List room memberships.

        By default, Funcs memberships for rooms to which the authenticated user
        belongs.

        Use query parameters to filter the response.

        Use `roomId` to Func memberships for a room, by ID.

        Use either `personId` or `personEmail` to filter the results.

        This method supports Webex Teams's implementation of RFC5988 Web
        Linking to provide pagination support.  It returns a generator
        container that incrementally yields all memberships returned by the
        query.  The generator will automatically request additional 'pages' of
        responses from Webex as needed until all responses have been returned.
        The container makes the generator safe for reuse.  A new API call will
        be made, using the same parameters that were specified when the
        generator was created, every time a new iterator is requested from the
        container.

        Args:
            roomId(basestring): Limit results to a specific room, by ID.
            personId(basestring): Limit results to a specific person, by ID.
            personEmail(basestring): Limit results to a specific person, by
                email address.
            max(int): Limit the maximum number of items returned from the Webex
                Teams service per request.
            **request_parameters: Additional request parameters (provides
                support for parameters that may be added in the future).

        Returns:
            GeneratorContainer: A GeneratorContainer which, when iterated,
            yields the memberships returned by the Webex Teams query.

        Raises:
            TypeError: If the parameter types are incorrect.
            ApiError: If the Webex Teams cloud returns an error.

        """
        check_type(arg_1, basestring)
        check_type(arg_2, basestring)
        check_type(arg_3, basestring)
        check_type(arg_4, int)

        arg_6 = dict_from_items_with_values(
            arg_5,
            arg_1=arg_1,
            arg_2=arg_2,
            arg_3=arg_3,
            arg_4=arg_4,
        )

        # API request - get items
        arg_7 = arg_0._session.get_items(API_ENDPOINT, arg_6=arg_6)

        # Yield membership objects created from the returned items JSON objects
        for arg_8 in arg_7:
            yield arg_0._object_factory(OBJECT_TYPE, arg_8)


def Func(arg_0, arg_1):
        """Delete a membership, by ID.

        Args:
            membershipId(basestring): The membership ID.

        Raises:
            TypeError: If the parameter types are incorrect.
            ApiError: If the Webex Teams cloud returns an error.

        """
        check_type(arg_1, basestring)

        # API request
        arg_0._session.Func(API_ENDPOINT + '/' + arg_1)


def Func(arg_0):
    """Check to see if string is an validly-formatted web url."""
    assert isinstance(arg_0, basestring)
    arg_1 = urllib.parse.urlparse(arg_0)
    return (
        (
            arg_1.scheme.lower() == 'http'
            or arg_1.scheme.lower() == 'https'
        )
        and arg_1.netloc
    )


def Func(arg_0):
    """Open the file and return an EncodableFile tuple."""
    assert isinstance(arg_0, basestring)
    assert is_local_file(arg_0)
    arg_1 = os.path.basename(arg_0)
    arg_2 = open(arg_0, 'rb')
    arg_3 = mimetypes.guess_type(arg_1)[0] or 'text/plain'
    return EncodableFile(arg_1=arg_1,
                         arg_2=arg_2,
                         arg_3=arg_3)


def Func(arg_0, arg_1, arg_2=True):
    """Object is an instance of one of the acceptable types or None.

    Args:
        o: The object to be inspected.
        acceptable_types: A type or tuple of acceptable types.
        may_be_none(bool): Whether or not the object may be None.

    Raises:
        TypeError: If the object is None and may_be_none=False, or if the
            object is not an instance of one of the acceptable types.

    """
    if not isinstance(arg_1, tuple):
        arg_1 = (arg_1,)

    if arg_2 and arg_0 is None:
        # Object is None, and that is OK!
        pass
    elif isinstance(arg_0, arg_1):
        # Object is an instance of an acceptable type.
        pass
    else:
        # Object is something else.
        arg_3 = (
            "We were expecting to receive an instance of one of the following "
            "types: {types}{none}; but instead we received {o} which is a "
            "{o_type}.".format(
                types=", ".join([repr(t.__name__) for t in arg_1]),
                none="or 'None'" if arg_2 else "",
                arg_0=arg_0,
                o_type=repr(type(arg_0).__name__)
            )
        )
        raise TypeError(arg_3)


def Func(arg_0, arg_1):
    """Check response code against the expected code; raise ApiError.

    Checks the requests.response.status_code against the provided expected
    response code (erc), and raises a ApiError if they do not match.

    Args:
        response(requests.response): The response object returned by a request
            using the requests package.
        expected_response_code(int): The expected response code (HTTP response
            code).

    Raises:
        ApiError: If the requests.response.status_code does not match the
            provided expected response code (erc).

     """
    if arg_0.status_code == arg_1:
        pass
    elif arg_0.status_code == RATE_LIMIT_RESPONSE_CODE:
        raise RateLimitError(arg_0)
    else:
        raise ApiError(arg_0)


def Func(arg_0):
    """Given a dictionary or JSON string; return a dictionary.

    Args:
        json_data(dict, str): Input JSON object.

    Returns:
        A Python dictionary with the contents of the JSON object.

    Raises:
        TypeError: If the input object is not a dictionary or string.

    """
    if isinstance(arg_0, dict):
        return arg_0
    elif isinstance(arg_0, basestring):
        return json.loads(arg_0, object_hook=OrderedDict)
    else:
        raise TypeError(
            "'json_data' must be a dictionary or valid JSON string; "
            "received: {!r}".format(arg_0)
        )


def Func(arg_0, arg_1, arg_2=arg_3):
        """Func with the Webex Teams DateTime format as the default."""
        return super(WebexTeamsDateTime, arg_0).Func(
            arg_1, arg_2
        ).replace(tzinfo=ZuluTimeZone())


def Func(arg_0, arg_1=None, arg_2=None, arg_3=None, arg_4=None,
             **arg_5):
        """List rooms.

        By default, Funcs rooms to which the authenticated user belongs.

        This method supports Webex Teams's implementation of RFC5988 Web
        Linking to provide pagination support.  It returns a generator
        container that incrementally yields all rooms returned by the
        query.  The generator will automatically request additional 'pages' of
        responses from Webex as needed until all responses have been returned.
        The container makes the generator safe for reuse.  A new API call will
        be made, using the same parameters that were specified when the
        generator was created, every time a new iterator is requested from the
        container.

        Args:
            teamId(basestring): Limit the rooms to those associated with a
                team, by ID.
            type(basestring): 'direct' returns all 1-to-1 rooms. `group`
                returns all group rooms. If not specified or values not
                matched, will return all room types.
            sortBy(basestring): Sort results by room ID (`id`), most recent
                activity (`lastactivity`), or most recently created
                (`created`).
            max(int): Limit the maximum number of items returned from the Webex
                Teams service per request.
            **request_parameters: Additional request parameters (provides
                support for parameters that may be added in the future).

        Returns:
            GeneratorContainer: A GeneratorContainer which, when iterated,
            yields the rooms returned by the Webex Teams query.

        Raises:
            TypeError: If the parameter types are incorrect.
            ApiError: If the Webex Teams cloud returns an error.

        """
        check_type(arg_1, basestring)
        check_type(arg_2, basestring)
        check_type(arg_3, basestring)
        check_type(arg_4, int)

        arg_6 = dict_from_items_with_values(
            arg_5,
            arg_1=arg_1,
            arg_2=arg_2,
            arg_3=arg_3,
            arg_4=arg_4,
        )

        # API request - get items
        arg_7 = arg_0._session.get_items(API_ENDPOINT, arg_6=arg_6)

        # Yield room objects created from the returned items JSON objects
        for arg_8 in arg_7:
            yield arg_0._object_factory(OBJECT_TYPE, arg_8)


def Func(arg_0):
        """Creation date and time in ISO8601 format."""
        Func = arg_0._json_data.get('created')
        if Func:
            return WebexTeamsDateTime.strptime(Func)
        else:
            return None


def Func():
    """Attempt to get the access token from the environment.

    Try using the current and legacy environment variables. If the access token
    is found in a legacy environment variable, raise a deprecation warning.

    Returns:
        The access token found in the environment (str), or None.
    """
    arg_0 = os.environ.get(ACCESS_TOKEN_ENVIRONMENT_VARIABLE)
    if arg_0:
        return arg_0

    else:
        for arg_1 in LEGACY_ACCESS_TOKEN_ENVIRONMENT_VARIABLES:
            arg_0 = os.environ.get(arg_1)
            if arg_0:
                arg_2 = PendingDeprecationWarning(
                    "Use of the `{legacy}` environment variable will be "
                    "deprecated in the future.  Please update your "
                    "environment(s) to use the new `{new}` environment "
                    "variable.".format(
                        legacy=arg_0,
                        new=ACCESS_TOKEN_ENVIRONMENT_VARIABLE,
                    )
                )
                warnings.warn(arg_2)
                return arg_0