#! /usr/bin/env python3

# Copyright 2019 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Heart Evaluation GUI Client for use in submitting data to worker.
"""

import os
import sys
import random
import json
import argparse
import logging
import secrets

# Tkinter imports
import tkinter as tk
import tkinter.messagebox as messagebox
import tkinter.font as font
from PIL import ImageTk, Image

# Avalon imports
import crypto_utils.crypto_utility as utility
import avalon_sdk.worker.worker_details as worker
from avalon_sdk.worker.worker_details import WorkerType
from avalon_sdk.work_order.work_order_params import WorkOrderParams
from avalon_sdk.direct.avalon_direct_client import AvalonDirectClient
import config.config as pconfig
import utility.logger as plogger
import crypto_utils.crypto.crypto as crypto
from error_code.error_status import WorkOrderStatus, ReceiptCreateStatus
import crypto_utils.signature as signature
from error_code.error_status import SignatureStatus
from avalon_sdk.work_order_receipt.work_order_receipt \
     import WorkOrderReceiptRequest

# Remove duplicate loggers
for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)
logger = logging.getLogger(__name__)
# Default TCFHOME assumes PWD is examples/apps/heart_disease_eval/client :
TCFHOME = os.environ.get("TCF_HOME", "../../../../")

# GUI color scheme
BACKGROUND = "light sky blue"
ENTRY_COLOR = "light grey"
BUTTON_COLOR = "deep sky blue"
RESULT_BACKGROUND = "pale goldenrod"

# -----------------------------------------------------------------
def _generate_random_or_normal_number(normal, percent_normal, low, high):
    """Generate number "normal" for "percent_normal" % of the time.
       Otherwise, generate a random number in the interval ["low", "high"].
    """
    if percent_normal >= random.randint(0, 100):
        return normal
    return random.randint(low, high)

def _generate_random_data():
    """Generate a random data string for input as evaluation data.
       For example:    "35 0 1 67 102 125 1 95 0 10 1 1 3 1"
    """

    age = _generate_random_or_normal_number(35, 67, 18, 100)
    sex = _generate_random_or_normal_number(0, 50, 1, 1)
    cp = _generate_random_or_normal_number(4, 67, 1, 3)
    trestbps = _generate_random_or_normal_number(67, 67, 108, 218)
    chol = _generate_random_or_normal_number(102, 67, 126, 309)
    fbs = _generate_random_or_normal_number(125, 67, 98, 248)
    restecg = _generate_random_or_normal_number(0, 67, 1, 2)
    thalach = _generate_random_or_normal_number(95, 67, 61, 198)
    exang = _generate_random_or_normal_number(0, 67, 1, 1)
    oldpeak = _generate_random_or_normal_number(10, 67, 0, 100)
    slop = _generate_random_or_normal_number(0, 67, 1, 2)
    ca = _generate_random_or_normal_number(0, 67, 1, 3)
    thaldur = _generate_random_or_normal_number(3, 67, 6, 7)
    num = _generate_random_or_normal_number(0, 67, 1, 1)

    return "{} {} {} {} {} {} {} {} {} {} {} {} {} {}".format(
        age, sex, cp, trestbps, chol, fbs, restecg, thalach,
        exang, oldpeak, slop, ca, thaldur, num)

def _int_validate(text):
    """Validates that input is a non-negative integer."""

    if str.isdigit(text) or text == "":
        return True
    else:
        return False

def _float_validate(text):
    """Validates that input is a non-negative, non-special float."""

    if text == "":
        return True
    try:
        float(text)
        if float(text) < 0.0 or float(text) == float("NaN") \
                or float(text) == float("INF") \
                or float(text) == float("-INF"):
            return False
        return True
    except ValueError:
        return False

class intEntry:
    """User entry for non-negative integer."""

    def __init__(self, master, name):
        global cur_row
        label = tk.Label(master, text=name, background=BACKGROUND)
        label.grid(row=cur_row, column=0, sticky="e", pady=(5, 0))
        validate = (master.register(_int_validate))
        self.entry = tk.Entry(
            master, validate="all",
            validatecommand=(validate, "%P"), width=5,
            background=ENTRY_COLOR)
        self.entry.grid(
            row=cur_row, column=1, padx=(10, 0), pady=(5, 0), sticky="w")
        cur_row += 1

    def get(self):
        # Fails if empty field
        try:
            return int(self.entry.get())
        except ValueError:
            return None

    def enable(self):
        self.entry.config(state=tk.NORMAL)

    def disable(self):
        self.entry.config(state=tk.DISABLED)

class floatEntry:
    """User entry for non-negative, non-special floating point number."""

    def __init__(self, master, name):
        global cur_row
        label = tk.Label(master, text=name, background=BACKGROUND)
        label.grid(row=cur_row, column=0, sticky="e", pady=(5,))
        validate = (master.register(_float_validate))
        self.entry = tk.Entry(
            master, validate="all",
            validatecommand=(validate, "%P"), width=10,
            background=ENTRY_COLOR)
        self.entry.grid(row=cur_row, column=1, padx=(10, 0), pady=(5,),
                        sticky="w")
        cur_row += 1

    def get(self):
        try:
            return float(self.entry.get())
        except ValueError:
            return None

    def enable(self):
        self.entry.config(state=tk.NORMAL)

    def disable(self):
        self.entry.config(state=tk.DISABLED)

class radio:
    """User entry for a radio button."""

    # Options is a list of text-value pairs
    def __init__(self, master, name, options):
        global cur_row
        if not all(len(tup) == 2 for tup in options):
            print("ERROR: Mismatched text-value pairs")
            exit(1)

        self.var = tk.IntVar()
        self.var.set(None)
        label = tk.Label(master, text=name, background=BACKGROUND)
        label.grid(row=cur_row, column=0, pady=(5, 0), sticky="e")

        self.button_list = []
        for i in range(len(options)):
            button = tk.Radiobutton(
                master, text=options[i][0],
                variable=self.var, value=options[i][1],
                background=BACKGROUND)
            self.button_list.append(button)
            if i == 0:
                button.grid(row=cur_row, column=1, pady=(5, 0),
                            sticky="w")
            else:
                button.grid(row=cur_row, column=1, sticky="w")
            cur_row += 1

    def get(self):
        try:
            return self.var.get()
        except tk.TclError:
            return None

    def enable(self):
        for button in self.button_list:
            button.config(state=tk.NORMAL)

    def disable(self):
        for button in self.button_list:
            button.config(state=tk.DISABLED)

class resultWindow(tk.Toplevel):
    """Create result window that appears after clicking "Evaluate"."""

    def __init__(self, parent, message):
        tk.Toplevel.__init__(self, parent)
        self.config(background=RESULT_BACKGROUND)
        self.parent = parent
        # Lock main window
        self.transient(parent)
        self.grab_set()
        self.initial_focus = self
        self.initial_focus.focus_set()
        self.title("Evaluation Result")
        self.protocol("WM_DELETE_WINDOW", self.close)

        # Main content
        self.main_frame = tk.Frame(self, background=RESULT_BACKGROUND)
        self.main_frame.pack()

        self.frame1 = tk.Frame(self.main_frame)
        self.frame1.pack(side=tk.LEFT)
        self.result_text = tk.StringVar()
        self.label = tk.Label(
            self.frame1, textvariable=self.result_text, width=45,
            background=RESULT_BACKGROUND)
        default_font = font.Font(font="TkDefaultFont")
        new_font = default_font
        new_font.config(weight=font.BOLD)
        self.label.config(font=new_font)
        self.label.pack()

        # JSON window display sidebar buttons
        self.frame2 = tk.Frame(self.main_frame, background=RESULT_BACKGROUND)
        self.frame2.pack(side=tk.LEFT)

        self.frame2 = tk.Frame(
            self.frame2, background=RESULT_BACKGROUND)
        self.frame2.pack(side=tk.LEFT)

        self.request_button = tk.Button(
            self.frame2, text="View Request", command=self.request,
            background=BUTTON_COLOR)
        self.request_button.pack(fill=tk.X, padx=(0, 10), pady=(10, 0))

        self.result_button = tk.Button(
            self.frame2, text="View Result", command=self.result,
            background=BUTTON_COLOR)
        self.result_button.pack(fill=tk.X, padx=(0, 10), pady=(10, 0))

        self.receipt_button = tk.Button(
            self.frame2, text="View Receipt",
            command=self.receipt, background=BUTTON_COLOR)
        self.receipt_button.pack(fill=tk.X, padx=(0, 10), pady=(10, 0))

        # Close button
        self.close_button = tk.Button(
            self, text="Close",
            command=self.close, background=BUTTON_COLOR)
        self.close_button.pack(pady=(0, 5))

        self.evaluate(message)

    def evaluate(self, message):
        """Create and submit workorder and wait for result."""

        self.result_text.set("Waiting for evaluation result...")
        self.update()

        # Create, sign, and submit workorder.
        # Convert workloadId to hex.
        workload_id = "heart-disease-eval"
        workload_id = workload_id.encode("UTF-8").hex()
        session_iv = utility.generate_iv()
        session_key = utility.generate_key()
        requester_nonce = secrets.token_hex(16)
        work_order_id = secrets.token_hex(32)
        requester_id = secrets.token_hex(32)
        wo_params = WorkOrderParams(
            work_order_id, worker_id, workload_id, requester_id,
            session_key, session_iv, requester_nonce,
            result_uri=" ", notify_uri=" ",
            worker_encryption_key=worker_obj.encryption_key,
            data_encryption_algorithm="AES-GCM-256"
        )
        wo_params.add_in_data(message)

        wo_params.add_encrypted_request_hash()

        private_key = utility.generate_signing_keys()
        if requester_signature:
            # Add requester signature and requester verifying_key
            if wo_params.add_requester_signature(private_key) is False:
                logger.info("Work order request signing failed")
                exit(1)

        # Set text for JSON sidebar
        req_id = 51
        self.request_json = wo_params.to_jrpc_string(req_id)

        work_order_instance = direct_jrpc.get_work_order_instance()
        response = work_order_instance.work_order_submit(
            wo_params.get_work_order_id(),
            wo_params.get_worker_id(),
            wo_params.get_requester_id(),
            wo_params.to_string(),
            id=req_id
        )
        logger.info("Work order submit response : {}\n ".format(
            json.dumps(response, indent=4)
        ))
        if "error" in response and response["error"]["code"] != \
                WorkOrderStatus.PENDING:
            sys.exit(1)
        # Create work order receipt
        req_id += 1
        wo_receipt_instance = direct_jrpc.get_work_order_receipt_instance()
        wo_request = json.loads(self.request_json)
        wo_receipt_obj = WorkOrderReceiptRequest()
        wo_create_receipt = wo_receipt_obj.create_receipt(
            wo_request,
            ReceiptCreateStatus.PENDING.value,
            private_key
        )
        logger.info("Work order create receipt request : {} \n \n ".format(
            json.dumps(wo_create_receipt, indent=4)
        ))
        # Submit work order create receipt jrpc request
        wo_receipt_resp = wo_receipt_instance.work_order_receipt_create(
            wo_create_receipt["workOrderId"],
            wo_create_receipt["workerServiceId"],
            wo_create_receipt["workerId"],
            wo_create_receipt["requesterId"],
            wo_create_receipt["receiptCreateStatus"],
            wo_create_receipt["workOrderRequestHash"],
            wo_create_receipt["requesterGeneratedNonce"],
            wo_create_receipt["requesterSignature"],
            wo_create_receipt["signatureRules"],
            wo_create_receipt["receiptVerificationKey"],
            req_id
        )

        logger.info("Work order create receipt response : {} \n \n ".format(
            wo_receipt_resp
        ))

        # Retrieve result and set GUI result text
        res = work_order_instance.work_order_get_result(
            work_order_id,
            req_id
        )
        self.result_json = json.dumps(res, indent=4)
        if "result" in res:
            sig_obj = signature.ClientSignature()
            status = sig_obj.verify_signature(
                res, worker_obj.verification_key)
            try:
                if status == SignatureStatus.PASSED:
                    logger.info("Signature verification Successful")
                    decrypted_res = utility. \
                        decrypted_response(res, session_key, session_iv)
                    logger.info("\n" +
                                "Decrypted response:\n {}".
                                format(decrypted_res))
                else:
                    logger.info("Signature verification Failed")
                    sys.exit(1)
            except Exception as err:
                logger.info("ERROR: Failed to decrypt response: %s", str(err))
                sys.exit(1)
        else:
            logger.info("\n Work order get result failed {}\n".format(res))
            sys.exit(1)

        # Set text for JSON sidebar
        self.result_text.set(
            decrypted_res[0]["data"])

        # Retrieve receipt
        # Set text for JSON sidebar
        req_id += 1
        self.receipt_json = json.dumps(
            wo_receipt_instance.work_order_receipt_retrieve(
                work_order_id,
                req_id
            ),
            indent=4
        )

    def request(self):
        jsonWindow(self, self.request_json, "Request JSON")

    def result(self):
        jsonWindow(self, self.result_json, "Result JSON")

    def receipt(self):
        jsonWindow(self, self.receipt_json, "Receipt JSON")

    def close(self):
        self.parent.focus_set()
        self.destroy()

class jsonWindow(tk.Toplevel):
    """Template for JSON display
       (from clicking View Request/Result/Receipt buttons).
    """

    def __init__(self, parent, json, title):
        tk.Toplevel.__init__(self, parent)
        self.title(title)
        self.scrollbar = tk.Scrollbar(self)
        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        self.text = tk.Text(self, yscrollcommand=self.scrollbar.set)
        self.text.insert(tk.END, json)
        self.text.config(state=tk.DISABLED)
        self.text.pack(expand=True, fill="both")

        self.scrollbar.config(command=self.text.yview)

def gui_main():
    """Create main Tkinter window and "Evaluate" event handler."""

    root = tk.Tk()
    root.title("Heart Disease Evaluation")
    root.config(background=BACKGROUND)

    # Display image
    imageFile = TCFHOME + \
        "/examples/apps/heart_disease_eval/images/ecg.jpg"
    img = ImageTk.PhotoImage(Image.open(imageFile))
    canvas = tk.Canvas(root, width=290, height=220, background=BACKGROUND)
    canvas.pack()
    canvas.create_image(20, 20, anchor=tk.NW, image=img)

    # Setup left and right frames for data entry
    var_root = tk.Frame(root, background=BACKGROUND)
    var_root.pack(pady=(10, 0))
    v_frame1 = tk.Frame(var_root, background=BACKGROUND)
    v_frame1.pack(fill=tk.Y, side=tk.LEFT, padx=(10, 0))
    v_frame2 = tk.Frame(var_root, background=BACKGROUND)
    v_frame2.pack(fill=tk.Y, side=tk.LEFT, padx=(0, 10))
    # Organizes parameter grid
    global cur_row
    cur_row = 0

    # Parameter grid
    age = intEntry(v_frame1, "Age")
    sex = radio(v_frame1, "Sex", [("Male", 1), ("Female", 0)])
    cp = radio(v_frame1, "Chest pain type", [("Typical angina", 1),
               ("Atypical angina", 2), ("Non-anginal pain", 3),
               ("Asymptomatic", 4)])
    trestbps = intEntry(v_frame1, "Resting blood pressure\n (mm Hg)")
    chol = intEntry(v_frame1, "Serum cholesterol (mg/dl)")
    fbs = intEntry(v_frame1, "Fasting blood sugar (mg/dl)")
    restecg = radio(v_frame1, "Electrocardiographic\n resting results",
                    [("Normal", 0), ("ST-T wave abnormality", 1),
                     ("Showing hypertrophy", 2)])
    thalach = intEntry(v_frame1, "Maximum heart rate")
    exang = radio(v_frame2, "Exercise induced angina",
                  [("Yes", 1), ("No", 0)])
    oldpeak = floatEntry(
        v_frame2, "ST depression induced by\n exercise relative to rest")
    slope = radio(v_frame2, "Slope of the peak\n exercise ST segment",
                  [("Upsloping", 0), ("Flat", 1), ("Downsloping", 2)])
    ca = radio(v_frame2, "Major vessels colored\n by flouroscopy",
               [("0", 0), ("1", 1), ("2", 2), ("3", 3)])
    thal = radio(
        v_frame2,
        "Thallium stress test",
        [("Normal", 3), ("Fixed defect", 6), ("Reversible defect", 7)])
    num = radio(v_frame2, "Heart disease diagnosis",
                [("<50% diameter narrowing", 0),
                 (">50% diameter narrowing", 1)])
    var_list = [age, sex, cp, trestbps, chol, fbs, restecg, thalach,
                exang, oldpeak, slope, ca, thal, num]

    def string_toggle():
        """Disable/enable other variable entries/buttons based on
           whether string input option is selected.
        """

        if string_use.get() == 1 or random_use.get() == 1:
            for var in var_list:
                var.disable()
            string_entry.config(state=tk.NORMAL)
        else:
            for var in var_list:
                var.enable()
            string_entry.config(state=tk.DISABLED)

    # Input vars as string option with a check button to enable
    random_frame = tk.Frame(root, background=ENTRY_COLOR)
    random_frame.pack()

    # Option to generate random data entry
    random_use = tk.IntVar()
    random_check = tk.Checkbutton(
        random_frame, command=string_toggle, variable=random_use,
        background=BACKGROUND)
    random_check.pack(side=tk.LEFT)
    random_label = tk.Label(
        random_frame,
        text="Generate random data ",
        background=BACKGROUND)
    random_label.pack(side=tk.LEFT)

    # Option to enter data as space-separated string entries
    string_frame = tk.Frame(root, background=ENTRY_COLOR)
    string_frame.pack()
    string_use = tk.IntVar()
    string_check = tk.Checkbutton(
        string_frame, command=string_toggle, variable=string_use,
        background=BACKGROUND)
    string_check.pack(side=tk.LEFT)
    string_label = tk.Label(
        string_frame,
        text="Input variables as a string",
        background=BACKGROUND)
    string_label.pack(side=tk.LEFT)
    string_entry = tk.Entry(
        string_frame, state=tk.DISABLED, width=50,
        background=ENTRY_COLOR)
    string_entry.pack(side=tk.LEFT)

    def evaluate():
        """Open window that will submit work order and retrieve
           an evaluation result.
        """

        message = "Heart disease evaluation data: "
        if string_use.get() == 1:  # input is space-separated numbers
            input_data = string_entry.get()
            if input_data is None or len(input_data) == 0:
                messagebox.showwarning(
                    "Error", "Must input space-separated variables")
                return
            message = message + input_data

        elif random_use.get() == 1:
            input_data = _generate_random_data()
            if input_data is None or len(input_data) == 0:
                messagebox.showwarning(
                    "Error", "Random variable generation error")
                return
            message = message + input_data
        else:
            for var in var_list:
                if var.get() is None:
                    messagebox.showwarning("Error", "Must input all variables")
                    return
                message = message + str(var.get()) + " "
        root.wait_window(resultWindow(root, message))

    def aggregate():
        """Open window that will submit work order to retrieve
           an aggregate result.
        """

        message = "Heart disease aggregate data: "
        root.wait_window(resultWindow(root, message))

    # "Evaluate" button
    eval_text = tk.StringVar()
    eval_label = tk.Label(root, textvariable=eval_text,
                          background=BACKGROUND)
    eval_label.pack()
    eval_button = tk.Button(root, text="Evaluate", command=evaluate,
                            background=BUTTON_COLOR)
    eval_button.pack()

    # "Aggregate" button
    aggr_text = tk.StringVar()
    aggr_label = tk.Label(root, textvariable=aggr_text, background=BACKGROUND)
    aggr_label.pack()
    aggr_button = tk.Button(root, text="Aggregate all data",
                            command=aggregate, background=BUTTON_COLOR)
    aggr_button.pack(pady=(0, 10))

    root.mainloop()

def parse_command_line(args):
    """Setup and parse command line arguments and help information."""

    global worker_obj
    global worker_id
    global verbose
    global config
    global off_chain
    global requester_signature

    parser = argparse.ArgumentParser()
    use_service = parser.add_mutually_exclusive_group()
    parser.add_argument(
        "-c", "--config",
        help="the config file containing the" +
        " Ethereum contract information", type=str)
    use_service.add_argument(
        "-r", "--registry-list",
        help="the Ethereum address of the registry list",
        type=str)
    use_service.add_argument(
        "-s", "--service-uri",
        help="skip URI lookup and send to specified URI",
        type=str)
    use_service.add_argument(
        "-o", "--off-chain",
        help="skip URI lookup and use the registry in the config file",
        action="store_true")
    parser.add_argument(
        "-w", "--worker-id",
        help="skip worker lookup and retrieve specified worker",
        type=str)
    parser.add_argument(
        "-v", "--verbose",
        help="increase output verbosity",
        action="store_true")
    parser.add_argument(
        "-rs", "--requester_signature",
        help="Enable requester signature for work order requests",
        action="store_true")

    options = parser.parse_args(args)

    if options.config:
        conf_files = [options.config]
    else:
        conf_files = [TCFHOME +
                      "/sdk/avalon_sdk/tcf_connector.toml"]
    conf_paths = ["."]

    try:
        config = pconfig.parse_configuration_files(conf_files, conf_paths)
        json.dumps(config, indent=4)
    except pconfig.ConfigurationException as e:
        logger.error(str(e))
        sys.exit(-1)

    global direct_jrpc
    direct_jrpc = AvalonDirectClient(conf_files[0])

    # Whether or not to connect to the registry list on the blockchain
    off_chain = False

    if options.registry_list:
        config["ethereum"]["direct_registry_contract_address"] = \
            options.registry_list

    if options.service_uri:
        service_uri = options.service_uri
        off_chain = True

    if options.off_chain:
        service_uri = config["tcf"].get("json_rpc_uri")
        off_chain = True

    requester_signature = options.requester_signature

    verbose = options.verbose
    worker_id = options.worker_id

    # Initializing Worker Object
    worker_obj = worker.SGXWorkerDetails()

def initialize_logging(config):
    """Initialize logging."""

    if verbose:
        config["Logging"] = {
            "LogFile": "__screen__",
            "LogLevel": "INFO"
        }
    else:
        config["Logging"] = {
            "LogFile": "__screen__",
            "LogLevel": "WARN"
        }
    plogger.setup_loggers(config.get("Logging", {}))
    sys.stdout = plogger.stream_to_logger(
        logging.getLogger("STDOUT"), logging.DEBUG)
    sys.stderr = plogger.stream_to_logger(
        logging.getLogger("STDERR"), logging.WARN)

def initialize_tcf(config):
    """Initialize Avalon: get Avalon worker instance."""

    logger.info("***************** Avalon *****************")

    # Retrieve Worker Registry
    if not off_chain:
        registry_list_instance = direct_jrpc. \
            get_worker_registry_list_instance()
        registry_count, lookup_tag, registry_list = \
            registry_list_instance.registry_lookup()
        logger.info("\n Registry lookup response : registry count {}\
            lookup tag {} registry list {}\n".format(
            registry_count, lookup_tag, registry_list
        ))
        if (registry_count == 0):
            logger.warn("No registries found")
            sys.exit(1)
        registry_retrieve_result = \
            registry_list_instance.registry_retrieve(
                registry_list[0])
        logger.info("\n Registry retrieve response : {}\n".format(
            registry_retrieve_result
        ))
        config["tcf"]["json_rpc_uri"] = registry_retrieve_result[0]

    # Prepare worker

    global worker_id
    if not worker_id:
        worker_registry_instance = direct_jrpc.get_worker_registry_instance()
        req_id = 31
        worker_lookup_result = worker_registry_instance.worker_lookup(
            worker_type=WorkerType.TEE_SGX,
            id=req_id
        )
        logger.info("\n Worker lookup response : {} \n".format(
            json.dumps(worker_lookup_result, indent=4)
        ))
        if "result" in worker_lookup_result and \
                "ids" in worker_lookup_result["result"].keys():
            if worker_lookup_result["result"]["totalCount"] != 0:
                worker_id = \
                    worker_lookup_result["result"]["ids"][0]
            else:
                logger.error("ERROR: No workers found")
                sys.exit(1)
        else:
            logger.error("ERROR: Failed to lookup worker")
            sys.exit(1)
    req_id += 1
    worker = worker_registry_instance.worker_retrieve(
        worker_id,
        req_id
    )
    logger.info("\n Worker retrieve response : {}\n".format(
        json.dumps(worker, indent=4)
    ))
    worker_obj.load_worker(
        worker
    )
    logger.info("**********Worker details Updated with Worker ID" +
                "*********\n%s\n", worker_id)

def main(args=None):
    """Entry point function."""

    parse_command_line(args)

    initialize_logging(config)

    initialize_tcf(config)

    # Open GUI
    gui_main()

# -----------------------------------------------------------------------------
main()


#!/usr/bin/env python
# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myoauth.settings")

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)


import numpy as np
import collections
import numbers
import torch
import os
from . import joint_network
from .summary import LamanClassificationSummary
from .. import corruption_dataset, model as mo
from .representation import graph_to_rep, combine_graph_reps, encode_action, LamanRep, get_action_offsets
from ..molecule_models import _train_utils, _train_harness
from ._utils import cast_numpy_rec

def _transform(graph, act):
    graph_rep = graph_to_rep(graph)
    act_encoded = encode_action(act, graph)
    act_coarse = act.action_type
    offset = torch.from_numpy(get_action_offsets(graph)).int()

    return {
        'graph': graph_rep,
        'label': act_encoded,
        'label_coarse': act_coarse,
        'label_offset': offset
    }

def _collate(batch):
    graph = combine_graph_reps([b['graph'] for b in batch])
    graph = cast_numpy_rec(graph)
    label_fine = torch.LongTensor([b['label'] for b in batch])
    label_coarse = torch.LongTensor([b['label_coarse'] for b in batch])
    offsets = torch.stack([b['label_offset'] for b in batch])

    return {'graph': graph, 'label': label_fine, 'label_coarse': label_coarse, 'label_offset': offsets}

def make_dataloader(dataset, batch_size=128, num_workers=2):
    return torch.utils.data.DataLoader(
        dataset, batch_size, shuffle=True, collate_fn=_collate,
        pin_memory=True, num_workers=num_workers)

class LamanJointHarness(_train_harness.TrainingHarness):
    _keys = ['label', 'label_offset']

    def __init__(self, model, optimizer, summary, task='train', profile=False):
        super(LamanJointHarness, self).__init__(model, optimizer, summary, task=task, profile=profile)

    def get_model_input(self, batch):
        graph = LamanRep.from_sequence(batch['graph'])
        return graph,

    def get_loss(self, model_output, batch):
        loss, summary_info = mo.classification.multi_classification_coarse_to_fine_loss(
            model_output, batch['label_coarse'], batch['label'], summary_info=True)

        self.summary.record_marginal_probability(
            torch.nn.functional.softmax(summary_info['coarse_logit'].detach(), dim=1).mean(dim=0))

        return loss

    def record_step_summary(self, batch, model_output):
        logits_and_scopes = model_output
        prediction, label, label_offset = _train_harness.compute_and_aggregate_predictions(
            logits_and_scopes, batch, self._keys)

        if self.summary:
            self.summary.record_statistics(prediction, label, label_offset)

def main(parameters=None):
    if parameters is None:
        parameters = {}

    task = parameters.get('task', 'train')
    batch_size = parameters.get('batch_size', 256)

    dataset_path = parameters.get('dataset_path')
    if dataset_path is None:
        dataset_path = '../data/laman/low_decomp_dataset_sample.pkl'

    dataset = corruption_dataset.LamanCorruptionDataset(dataset_path, transform=_transform)

    dataloader = make_dataloader(dataset, batch_size, num_workers=parameters.get('num_workers', 2))

    config = joint_network.JointClassificationNetworkConfig(
        5, message_size=256)
    model = joint_network.JointClassificationNetwork(config)

    if 'model_path' in parameters and parameters['model_path'] is not None:
        model.load_state_dict(torch.load(parameters['model_path'], map_location='cpu'))

    model = model.cuda()

    if task != 'train':
        model = model.eval()

    if task == 'train':
        optimizer, schedulers = _train_utils.init_optimizer(model, parameters)
    else:
        optimizer = None
        schedulers = []

    summary = LamanClassificationSummary()

    harness = LamanJointHarness(model, optimizer, summary, task)
    harness.hooks.extend([
        _train_harness.LogLossTimeHook(batch_size),
        _train_harness.PrintAccuracyHook(summary, None)
    ])

    savedir = _train_utils.get_save_dir(parameters)

    for epoch in range(30):
        dataset.set_epoch(epoch)
        harness.set_epoch(epoch)

        if task == 'train':
            for scheduler in schedulers:
                scheduler.step()

        harness.train_epoch(dataloader)

        if task == 'train':
            torch.save(
                model.state_dict(),
                os.path.join(savedir, 'laman_joint_ep_{0}.pth'.format(epoch)))

if __name__ == '__main__':
    args = _train_utils.parse_arguments()
    main(vars(args))


from celery import Celery

def make_celery(app):
    celery = Celery(
        app.import_name,
        broker=app.config.get('CELERY_BROKER_URL', 'redis://localhost:6379')
    )
    celery.conf.update(app.config)
    TaskBase = celery.Task

    class ContextTask(TaskBase):
        abstract = True

        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)

    celery.Task = ContextTask
    return celery


import numpy as np
import matplotlib.pyplot as plt
from sympy import solve, Eq, symbols
import sys
import pandas
import math
import os

def degradeCOP(Tevap, Tcond, Qall, S):
    degraded = ((Tevap * Tcond)/(Tcond - Tevap)) * (S/Qall)
    return degraded

# This function calculates the reversible COP of a ES refrigerator based on thermal reservoirs
def reversibleCOP(Tevap, Tcond, Tgen):
    revCOP = (((Tgen - Tcond)/(Tgen))/((Tcond-Tevap)/Tevap))
    return revCOP

# This function solves the system of equations to calculate the mass flowrates of
# the combined absorber-evaporator system
def massabsorberevaporator(m6, m4, xa4, ya3, xa6):
    m3, m5= symbols(['m3', 'm5'])
    system = [
    #Eq((xa4*m4)+ (ya3 * m3) - (0 * m5) - (xa6 * m6), 0),
    Eq(m5 - (1-ya3)*m3,0),
    Eq(m4 + m3 - m5 - m6, 0),
    #Eq((1-ya3)*m3-m5, 0)
    #Eq(m4 - (ya3*m3) - (m5) + (ya3 * m6), 0)
    ]
    soln = solve(system, [m4, m3, m5, m6])

    return float(m4), float(soln[m3]), float(soln[m5]), float(m6)

# This is an interpolate helper function to be used in other functions.
# targetcomp refers to ammonia composition. All CSV files are in ammonia composition.
def interpolateAW(targetcomp, T, var):
    # must use the entropy-ammonia-water csv, entropy-ammonia-butane csv, or enthalpy-ammonia-water csv

    script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
    rel_path = 'data/mixed/'
    abs_file_path = os.path.join(script_dir, rel_path)

    colnames = ['pressure', 'ammoniacomp', 'prop']
    propertyname = ''
    if var is 1:
        propertyname = 'enthalpy'
    else:
        propertyname = 'entropy'

    filename = propertyname + '-kjmol-' + str(T) + 'K-ammoniawater'

    data = pandas.read_csv(str(abs_file_path) + '%s.csv' %filename, names=colnames)

    ammoniacomp = data.ammoniacomp.tolist()
    prop = data.prop.tolist()

    lower = prop[int(math.floor(targetcomp /0.05))]
    higher = prop[(int((math.floor(targetcomp /0.05))+1))]

    theta = (targetcomp - int(math.floor(targetcomp /0.05))*0.05 ) / ((int((math.floor(targetcomp /0.05))+1))*0.05 - int(math.floor(targetcomp /0.05))*0.05 )
    return (theta * higher) + (1-theta)*lower

def interpolateAB(targetcomp, T, var):
    # must use the entropy-ammonia-water csv, entropy-ammonia-butane csv, or enthalpy-ammonia-water csv

    script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
    rel_path = 'data/mixed/'
    abs_file_path = os.path.join(script_dir, rel_path)

    colnames = ['pressure', 'ammoniacomp', 'prop']
    propertyname = ''
    if var is 1:
        propertyname = 'enthalpy'
    else:
        propertyname = 'entropy'

    filename = propertyname + '-kjmol-' + str(T) + 'K-ammoniabutane'

    data = pandas.read_csv(str(abs_file_path) + '%s.csv' %filename, names=colnames)

    ammoniacomp = data.ammoniacomp.tolist()
    prop = data.prop.tolist()

    lower = prop[int(math.floor(targetcomp /0.05))]
    higher = prop[(int((math.floor(targetcomp /0.05))+1))]

    theta = (targetcomp - int(math.floor(targetcomp /0.05))*0.05 ) / ((int((math.floor(targetcomp /0.05))+1))*0.05 - int(math.floor(targetcomp /0.05))*0.05 )
    return (theta * higher) + (1-theta)*lower
# This calculates the two mass flowrates and the compositions coming out of the flash drum
# given a mass flowrate and composition of ammonia coming in
# inputcomp is the ammonia composition
# temp is the temperature that the flash drum flashes at
def leverrule(inputflow, temp, inputcomp):
    #t-xy of ammonia-water
    #input composition of ammonia
    script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
    rel_path = "data/txy/"
    abs_file_path = os.path.join(script_dir, rel_path)
    colnames = ['pressure', 'ammoniacomp', 'temperature', 'vaporwater', 'vaporammonia', 'liquidwater', 'liquidammonia']
    filename = 'txy-ammonia-4bar'
    data = pandas.read_csv( str(abs_file_path) + '%s.csv' %filename, names = colnames)

    ammoniacomp = data.ammoniacomp.tolist()
    temperature = data.temperature.tolist()
    vaporammonia = data.vaporammonia.tolist()
    liquidammonia = data.liquidammonia.tolist()

    index, valuetemp =  min(enumerate(temperature), key=lambda x: abs(x[1]-temp))

    liquiddistance = inputcomp - liquidammonia[index]
    vapordistance = vaporammonia[index] - inputcomp

    vaporflow = symbols('vaporflow')
    system = [
    Eq((vapordistance * vaporflow) + (-1.0*liquiddistance*(float(inputflow) - vaporflow)), 0)
    ]

    soln = solve(system, [vaporflow])

    # the order is: vapor flow, liquid flow, liquid ammonia composition. vapor ammonia composition
    return soln[vaporflow], (inputflow - soln[vaporflow]) ,liquidammonia[index], vaporammonia[index]

# This calculates the Q of the generator
# compin is the ammonia composition
def Qgenerator(massin, compin, Tgen):
    massout = massin

    enthalpyin = interpolateAW(compin, 325, 1 )

    enthalpyout = interpolateAW(compin, Tgen, 1)

    Qgen = -1*(massin*enthalpyin - massout*enthalpyout)

    return Qgen
# This calculates the S of the flash
# compin is the ammonia flash
def Sgenerator(massin, compin, Qgen, Tgen):
    massout = massin

    entropyin = interpolateAW(compin, 325, 2)
    #RAHUL fixed Line 95 - wrong entropy values read in
    entropyout = interpolateAW(compin, Tgen, 2)

    Sgen = symbols('Sgen')
    system = Eq((-1 * massin * entropyin ) + (massout*entropyout) + (Qgen/Tgen) - Sgen, 0)

    soln = solve([system], Sgen)

    return soln[Sgen]

def Qflash(massin, massvapor, massliquid, compin, vaporammonia, liquidammonia, Tgen):

    enthalpyin = interpolateAW( compin, Tgen, 1)

    enthalpyoutvapor = interpolateAW(vaporammonia, Tgen, 1)

    enthalpyoutliquid = interpolateAW( liquidammonia, Tgen, 1)

    Qflash = symbols('Qflash')
    system = Eq(( massin* enthalpyin ) + (-1* massvapor*enthalpyoutvapor) + (-1* massliquid*enthalpyoutliquid) + Qflash, 0)

    soln = solve([system], [Qflash])

    return soln[Qflash]
# This calculates the S of the flash
# compin is the ammonia flash
def Sflash(massin, massvapor, massliquid, compin, vaporammonia, liquidammonia, Qflash, Tgen):

    entropyin = interpolateAW( compin, Tgen, 2)

    entropyoutvapor = interpolateAW(vaporammonia, Tgen, 2)

    entropyoutliquid = interpolateAW(liquidammonia, Tgen, 2)

    Sflash = symbols('Sflash')
    system = Eq(( massin* entropyin ) + (-1* massvapor*entropyoutvapor) + (-1* massliquid*entropyoutliquid) + (Sflash/Tgen) - Qflash, 0)

    soln = solve([system], Sflash)

    return soln[Sflash]
def Qevaporator(m2, m3, m5, ya3, ya2, xa5, Tgen):

    enthalpym2 = interpolateAW(ya2, Tgen, 1)

    enthalpym3 = interpolateAB( ya3, 266, 1)
    #print(enthalpym3)
    enthalpym5 = interpolateAB( xa5, 325, 1)
    #print(enthalpym5)

   # print(enthalpym2 + enthalpym3 + enthalpym5)
    Qevap = symbols('Qevap')
    system = Eq(( m2 * enthalpym2 ) + (-1* m3*enthalpym3) + (m5*enthalpym5) + Qevap, 0)
    soln = solve([system], Qevap)

    #print(type(soln))
    return soln[Qevap]

def Sevaporator(m2, m3, m5, ya3, ya2, xa5, Qevap, Tgen):

    entropym2 = interpolateAW(ya2, Tgen, 2)

    entropym3 = interpolateAB( ya3, 266, 2)

    entropym5 = interpolateAB( xa5, 325, 2)

    Sevap = symbols('Sevap')
    system = Eq(( m2 * entropym2 ) + (-1* m3*entropym3) + (m5*entropym5) + (Qevap/266) - Sevap, 0)

    soln = solve([system], Sevap)

    return soln[Sevap]

def Qabsorber(m3, m4, m5, m6, ya3, xa4, xa5, xa6, Tgen):

    enthalpym3 = interpolateAB( ya3, 266, 1)

    enthalpym4 = interpolateAW( xa4, Tgen, 1)

    enthalpym5 = interpolateAB(xa5, 325, 1)

    enthalpym6 = interpolateAW( xa6, 325, 1)

    Qabs = symbols('Qabs')
    system =  (m3 * enthalpym3 ) + (m4 * enthalpym4) + (-1*m5 * enthalpym5) + (-1 * m6 * enthalpym6) + Qabs

    soln = solve([system], Qabs)

    return soln[Qabs]

def Sabsorber(m3, m4, m5, m6, ya3, xa4, xa5, xa6, Qabs, Tgen):

    entropym3 = interpolateAB( ya3, 266, 2)

    entropym4 = interpolateAW( xa4, Tgen, 2)

    entropym5 = interpolateAB( xa5, 325, 2)

    entropym6 = interpolateAW(xa6, 325, 2)

    Sabs = symbols('Sabs')
    system =  Eq((m3*entropym3) + (m4 * entropym4) + (-1*m5 * entropym5) + (-1*m6*entropym6) + (Qabs/325)- Sabs, 0)

    soln = solve([system], Sabs)

    return soln[Sabs]


from setuptools import setup, find_packages
import versioneer

setup(
    name="pylammpsmpi",
    version=versioneer.get_version(),
    description="Parallel Lammps Python interface",
    url='https://github.com/pyiron/pylammpsmpi',
    author='Jan Janssen',
    author_email='janssen@mpie.de',
    license='BSD',

    classifiers=['Development Status :: 5 - Production/Stable',
                 'Topic :: Scientific/Engineering :: Physics',
                 'License :: OSI Approved :: BSD License',
                 'Intended Audience :: Science/Research',
                 'Operating System :: OS Independent',
                 'Programming Language :: Python :: 3.6',
                 'Programming Language :: Python :: 3.7',
                 'Programming Language :: Python :: 3.8',
                 'Programming Language :: Python :: 3.9'
                ],

    keywords='lammps, mpi4py',
    packages=find_packages(exclude=["*tests*"]),
    install_requires=[
        'mpi4py==3.1.3'
    ],
    cmdclass=versioneer.get_cmdclass(),
)


# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# Author: Alberto Solino (@agsolino)
#
# Description:
#   [MS-VDS]: Virtual Disk Service (VDS) Protocol
#             This was used as a way to test the DCOM runtime. Further
#             testing is needed to verify it is working as expected
#
#   Best way to learn how to use these calls is to grab the protocol standard
#   so you understand what the call does, and then read the test case located
#   at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC
#
#   Since DCOM is like an OO RPC, instead of helper functions you will see the
#   classes described in the standards developed.
#   There are test cases for them too.
#

from impacket.dcerpc.v5.ndr import NDRSTRUCT, NDRUniConformantVaryingArray, NDRENUM
from impacket.dcerpc.v5.dcomrt import DCOMCALL, DCOMANSWER, IRemUnknown2, PMInterfacePointer, INTERFACE
from impacket.dcerpc.v5.dtypes import LPWSTR, ULONG, DWORD, SHORT, GUID
from impacket.dcerpc.v5.rpcrt import DCERPCException
from impacket.dcerpc.v5.enum import Enum
from impacket import hresult_errors
from impacket.uuid import string_to_bin

class DCERPCSessionError(DCERPCException):
    def __init__(self, error_string=None, error_code=None, packet=None):
        DCERPCException.__init__(self, error_string, error_code, packet)

    def __str__( self ):
        if self.error_code in hresult_errors.ERROR_MESSAGES:
            error_msg_short = hresult_errors.ERROR_MESSAGES[self.error_code][0]
            error_msg_verbose = hresult_errors.ERROR_MESSAGES[self.error_code][1]
            return 'VDS SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
        else:
            return 'VDS SessionError: unknown error code: 0x%x' % (self.error_code)

################################################################################
# CONSTANTS
################################################################################
# 1.9 Standards Assignments
CLSID_VirtualDiskService = string_to_bin('7D1933CB-86F6-4A98-8628-01BE94C9A575')
IID_IEnumVdsObject = string_to_bin('118610B7-8D94-4030-B5B8-500889788E4E')
IID_IVdsAdviseSink = string_to_bin('8326CD1D-CF59-4936-B786-5EFC08798E25')
IID_IVdsAsync = string_to_bin('D5D23B6D-5A55-4492-9889-397A3C2D2DBC')
IID_IVdsServiceInitialization = string_to_bin('4AFC3636-DB01-4052-80C3-03BBCB8D3C69')
IID_IVdsService = string_to_bin('0818A8EF-9BA9-40D8-A6F9-E22833CC771E')
IID_IVdsSwProvider = string_to_bin('9AA58360-CE33-4F92-B658-ED24B14425B8')
IID_IVdsProvider = string_to_bin('10C5E575-7984-4E81-A56B-431F5F92AE42')

error_status_t = ULONG

# 2.2.1.1.3 VDS_OBJECT_ID
VDS_OBJECT_ID = GUID

################################################################################
# STRUCTURES
################################################################################
# 2.2.2.1.3.1 VDS_SERVICE_PROP
class VDS_SERVICE_PROP(NDRSTRUCT):
    structure = (
        ('pwszVersion',LPWSTR),
        ('ulFlags',ULONG),
    )

class OBJECT_ARRAY(NDRUniConformantVaryingArray):
    item = PMInterfacePointer

# 2.2.2.7.1.1 VDS_PROVIDER_TYPE
class VDS_PROVIDER_TYPE(NDRENUM):
    class enumItems(Enum):
        VDS_PT_UNKNOWN     = 0
        VDS_PT_SOFTWARE    = 1
        VDS_PT_HARDWARE    = 2
        VDS_PT_VIRTUALDISK = 3
        VDS_PT_MAX         = 4

# 2.2.2.7.2.1 VDS_PROVIDER_PROP
class VDS_PROVIDER_PROP(NDRSTRUCT):
    structure = (
        ('id',VDS_OBJECT_ID),
        ('pwszName',LPWSTR),
        ('guidVersionId',GUID),
        ('pwszVersion',LPWSTR),
        ('type',VDS_PROVIDER_TYPE),
        ('ulFlags',ULONG),
        ('ulStripeSizeFlags',ULONG),
        ('sRebuildPriority',SHORT),
    )

################################################################################
# RPC CALLS
################################################################################

# 3.4.5.2.5.1 IVdsServiceInitialization::Initialize (Opnum 3)
class IVdsServiceInitialization_Initialize(DCOMCALL):
    opnum = 3
    structure = (
       ('pwszMachineName', LPWSTR),
    )

class IVdsServiceInitialization_InitializeResponse(DCOMANSWER):
    structure = (
       ('ErrorCode', error_status_t),
    )

# 3.4.5.2.4.1 IVdsService::IsServiceReady (Opnum 3)
class IVdsService_IsServiceReady(DCOMCALL):
    opnum = 3
    structure = (
    )

class IVdsService_IsServiceReadyResponse(DCOMANSWER):
    structure = (
       ('ErrorCode', error_status_t),
    )

# 3.4.5.2.4.2 IVdsService::WaitForServiceReady (Opnum 4)
class IVdsService_WaitForServiceReady(DCOMCALL):
    opnum = 4
    structure = (
    )

class IVdsService_WaitForServiceReadyResponse(DCOMANSWER):
    structure = (
       ('ErrorCode', error_status_t),
    )

# 3.4.5.2.4.3 IVdsService::GetProperties (Opnum 5)
class IVdsService_GetProperties(DCOMCALL):
    opnum = 5
    structure = (
    )

class IVdsService_GetPropertiesResponse(DCOMANSWER):
    structure = (
       ('pServiceProp', VDS_SERVICE_PROP),
       ('ErrorCode', error_status_t),
    )

# 3.4.5.2.4.4 IVdsService::QueryProviders (Opnum 6)
class IVdsService_QueryProviders(DCOMCALL):
    opnum = 6
    structure = (
        ('masks', DWORD),
    )

class IVdsService_QueryProvidersResponse(DCOMANSWER):
    structure = (
       ('ppEnum', PMInterfacePointer),
       ('ErrorCode', error_status_t),
    )

# 3.1.1.1 IEnumVdsObject Interface
# 3.4.5.2.1.1 IEnumVdsObject::Next (Opnum 3)
class IEnumVdsObject_Next(DCOMCALL):
    opnum = 3
    structure = (
       ('celt', ULONG),
    )

class IEnumVdsObject_NextResponse(DCOMANSWER):
    structure = (
       ('ppObjectArray', OBJECT_ARRAY),
       ('pcFetched', ULONG),
       ('ErrorCode', error_status_t),
    )
# 3.4.5.2.14.1 IVdsProvider::GetProperties (Opnum 3)
class IVdsProvider_GetProperties(DCOMCALL):
    opnum = 3
    structure = (
    )

class IVdsProvider_GetPropertiesResponse(DCOMANSWER):
    structure = (
       ('pProviderProp', VDS_PROVIDER_PROP),
       ('ErrorCode', error_status_t),
    )

################################################################################
# OPNUMs and their corresponding structures
################################################################################
OPNUMS = {
}

################################################################################
# HELPER FUNCTIONS AND INTERFACES
################################################################################
class IEnumVdsObject(IRemUnknown2):
    def Next(self, celt=0xffff):
        request = IEnumVdsObject_Next()
        request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
        request['ORPCthis']['flags'] = 0
        request['celt'] = celt
        try:
            resp = self.request(request, uuid = self.get_iPid())
        except Exception as e:
            resp = e.get_packet()
            # If it is S_FALSE(1) means less items were returned
            if resp['ErrorCode'] != 1:
                raise
        interfaces = list()
        for interface in resp['ppObjectArray']:
            interfaces.append(IRemUnknown2(INTERFACE(self.get_cinstance(), ''.join(interface['abData']), self.get_ipidRemUnknown(), target = self.get_target())))
        return interfaces

class IVdsProvider(IRemUnknown2):
    def GetProperties(self):
        request = IVdsProvider_GetProperties()
        request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
        request['ORPCthis']['flags'] = 0
        resp = self.request(request, uuid = self.get_iPid())
        return resp

class IVdsServiceInitialization(IRemUnknown2):
    def __init__(self, interface):
        IRemUnknown2.__init__(self, interface)

    def Initialize(self):
        request = IVdsServiceInitialization_Initialize()
        request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
        request['ORPCthis']['flags'] = 0
        request['pwszMachineName'] = '\x00'
        resp = self.request(request, uuid = self.get_iPid())
        return resp

class IVdsService(IRemUnknown2):
    def __init__(self, interface):
        IRemUnknown2.__init__(self, interface)

    def IsServiceReady(self):
        request = IVdsService_IsServiceReady()
        request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
        request['ORPCthis']['flags'] = 0
        try:
            resp = self.request(request, uuid = self.get_iPid())
        except Exception as e:
            resp = e.get_packet()
        return resp

    def WaitForServiceReady(self):
        request = IVdsService_WaitForServiceReady()
        request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
        request['ORPCthis']['flags'] = 0
        resp = self.request(request, uuid = self.get_iPid())
        return resp

    def GetProperties(self):
        request = IVdsService_GetProperties()
        request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
        request['ORPCthis']['flags'] = 0
        resp = self.request(request, uuid = self.get_iPid())
        return resp

    def QueryProviders(self, masks):
        request = IVdsService_QueryProviders()
        request['ORPCthis'] = self.get_cinstance().get_ORPCthis()
        request['ORPCthis']['flags'] = 0
        request['masks'] = masks
        resp = self.request(request, uuid = self.get_iPid())
        return IEnumVdsObject(INTERFACE(self.get_cinstance(), ''.join(resp['ppEnum']['abData']), self.get_ipidRemUnknown(), target = self.get_target()))


"""
This module contains a dynamic programming algorithm for solving the subset sum
problem. See section 6.4 of Algorithm Design by Kleinberg and Tardos.

An instance of the subset sum problem is defined by a weight capacity and a
collection of items, where each item has a weight. A solution is any subset of
items for which the total weight does not exceed the capacity. An optimal
solution is a solution with maximum total weight.
"""

def compute_opt(c, ws):
    """
    Computes the maximum total weight for subproblems of the given instance of
    the subset sum problem with weight capacity c and item weights ws.

    TODO document recurrence relation
    """
    memo = [[0] * (c + 1)] * len(ws)
    for i in range(len(ws)):
        for j in range(1, c + 1):
            w1 = ws[i] if i > 0 else 0
            if j < ws[i]:
                memo[i][j] = w1
            else:
                w2 = ws[i] + (memo[i - 1][j - ws[i]] if i > 0 else 0)
                memo[i][j] = max(w1, w2)
    return memo

def find_sol(c, ws, memo):
    """
    Finds an optimal solution for the given instance of the subset sum problem
    with weight capacity c and item weights ws, provided maximum total weights
    for subproblems are memoized in memo.
    """
    sol = []
    for n in reversed(range(len(ws))):
        if c >= ws[n] and memo[n][c] == ws[n] + memo[n - 1][c - ws[n]]:
            sol.append(n)
            c -= ws[n]
    return sol

# Self-test
if __name__ == '__main__':
    # Pretty print optimal value and solution
    def pretty(c, ws):
        memo = compute_opt(c, ws)
        sol  = find_sol(c, ws, memo)
        print('optimal value   : ' + str(memo[-1][c]))
        print('optimal solution: ' + str(sol))

    c  = 11
    ws = [1, 2, 5, 6, 7]

    pretty(c, ws)


import os
from unittest import TestCase

from configservice import Config, MissingEnviron, ErrorFlagTrue

class TestCore(TestCase):

    def test__load_env(self):
        # set an env to work with.

        os.environ['TEST_ME_X'] = '1'

        c = Config()

        # Test simple recall.
        res = c.get_env('TEST_ME_X')
        self.assertEqual('1', res)

        # Test default value
        res = c.get_env('THIS_DOESNT_EXIST',
                        default_value='A')
        self.assertEqual('A', res)

        # Test default value where the key does exist (should take the key instead)
        res = c.get_env('TEST_ME_X',
                        default_value='A')
        self.assertEqual('1', res)

        # Test test mode responses section.
        ######### TEST MODES ############
        c._test_mode = True
        # Test simple recall.
        res = c.get_env('TEST_ME_X', test_response='test_res')
        self.assertEqual('test_res', res)

        # Test assigned value where no value assigned
        res = c.get_env('TEST_ME_X',
                        default_value=24,
                        test_response='test_res')
        self.assertEqual('1', res)
        c._test_mode = False
        ######### End Test Mode Section ############

        ######## Check error states. ############

        with self.assertRaises(MissingEnviron) as e:
            res = c.get_env('THIS_DOESNT_EXIST', error_flag=True)

        with self.assertRaises(ErrorFlagTrue) as e:
            res = c.get_env('THIS_DOESNT_EXIST', error_flag=True, default_value='1')

        ###### Check data conversion ###########
        # Test integer
        os.environ['TEST_ME_X'] = '1'
        res = c.get_env('TEST_ME_X', data_type_convert='int')
        self.assertEqual(1, res)

        # Test float
        os.environ['TEST_ME_X'] = '1.11'
        res = c.get_env('TEST_ME_X', data_type_convert='float')
        self.assertEqual(1.11, res)

        # Test Bool
        os.environ['TEST_ME_X'] = '1'
        res = c.get_env('TEST_ME_X', data_type_convert='bool')
        self.assertTrue(res)

        os.environ['TEST_ME_X'] = 'True'
        res = c.get_env('TEST_ME_X', data_type_convert='bool')
        self.assertTrue(res)

        os.environ['TEST_ME_X'] = '0'
        res = c.get_env('TEST_ME_X', data_type_convert='bool')
        self.assertFalse(res)

        os.environ['TEST_ME_X'] = 'false'
        res = c.get_env('TEST_ME_X', data_type_convert='bool')
        self.assertFalse(res)

        # Test list
        os.environ['TEST_ME_X'] = 'a,b,c,d'
        res = c.get_env('TEST_ME_X', data_type_convert='list')
        golden = ['a', 'b', 'c', 'd']
        self.assertListEqual(golden, res)

        # Test list int
        os.environ['TEST_ME_X'] = '1,2,3,4,5'
        res = c.get_env('TEST_ME_X', data_type_convert='list_int')
        golden = [1, 2, 3, 4, 5]
        self.assertListEqual(golden, res)

        # Test list float
        os.environ['TEST_ME_X'] = '1.2,2,3.6,4.6,5'
        res = c.get_env('TEST_ME_X', data_type_convert='list_float')
        golden = [1.2, 2, 3.6, 4.6, 5]
        self.assertListEqual(golden, res)

        # Test default value int

        res = c.get_env('TEST_ME_NO', default_value='3', data_type_convert='int')
        self.assertEqual(3, res)

        # Test default value int
        c._test_mode = True
        res = c.get_env('TEST_ME_NO', test_response='2', default_value='3', data_type_convert='int')
        self.assertEqual(3, res)

        # Test default value int
        c._test_mode = True
        res = c.get_env('TEST_ME_NO', test_response='2', data_type_convert='int')
        self.assertEqual(2, res)


#Задача №10, Вариант 6
#Разработайте игру "Крестики-нолики". (см. М.Доусон Программируем на Python гл. 6)

#Данилов Д.А.
#23.05.2016
def display_instruct():
	print("""
		Добро пожаловать на ринг грандиознейших интеллектуальных состязаний всех времён.
		Твой мозг и мой процессор сойдутся в схватке за доской игры "Крестики-нолики".
		Чтобы сделать ход, введи число от 0 до 8. Числа однозначно соответствуют полям
		доски - так, как показано ниже:
		0 | 1 | 2
		---------
		3 | 4 | 5
		---------
		6 | 7 | 8
		""")
X="X"
O="O"
EMPTY=" "
TIE="Ничья"
NUM_SQUARES=9
def ask_yes_no(question):
	response=None
	while response not in ("y","n"):
		response=input(question).lower()
	return response
def ask_number(question, low, high):
	response=None
	while response not in range(low, high):
		response=int(input(question))
	return response
def pieces():
	go_first=ask_yes_no("Хочешь оставить за собой первый ход? (y/n): ")
	if go_first=="y":
		print("\nНу что ж, даю тебе фору: играй крестиками.")
		human=X
		computer=O
	else:
		print("\nТвоя удаль тебя погубит... Буду начинать я.")
		computer=X
		human=O
	return computer, human
def new_board():
	board=[]
	for square in range(NUM_SQUARES):
		board.append(EMPTY)
	return board
def display_board(board):
	print("\n\t", board[0], "|", board[1], "|", board[2])
	print("\t", "---------")
	print("\t", board[3], "|", board[4], "|", board[5])
	print("\t", "---------")
	print("\t", board[6], "|", board[7], "|", board[8])
def legal_moves(board):
	moves = []
	for square in range(NUM_SQUARES):
		if board[square]==EMPTY:
			moves.append(square)
	return moves
def winner(board):
	WAYS_TO_WIN=((0, 1, 2),
				(3, 4, 5),
				(6, 7, 8),
				(0, 3, 6),
				(1, 4, 7),
				(2, 5, 8),
				(0, 4, 8),
				(2, 4, 6))
	for row in WAYS_TO_WIN:
		if board[row[0]]==board[row[1]]==board[row[2]]!=EMPTY:
			winner=board[row[0]]
			return winner
		if EMPTY not in board:
			return TIE
	return None
def human_move(board, human):
	legal=legal_moves(board)
	move=None
	while move not in legal:
		move=ask_number("Твой ход. Выбери одно из полей (0-8):", 0, NUM_SQUARES)
		if move not in legal:
			print("\nСмешной человек! Это поле уже занято. Выбери другое.\n")
	print("Ладно...")
	return move
def computer_move(board, computer, human):
	board=board[:]
	BEST_MOVES=(4, 0, 2, 6, 8, 1, 3, 5, 7)
	print("Я выберу поле номер", end=" ")
	for move in legal_moves(board):
		board[move]=computer
		if winner(board)==computer:
			print(move)
			return move
		board[move] = EMPTY
	for move in legal_moves(board):
		board[move]=human
		if winner(board)==human:
			print(move)
			return move
		board[move]=EMPTY
	for move in BEST_MOVES:
		if move in legal_moves(board):
			print(move)
			return move
def next_turn(turn):
	if turn==X:
		return O
	else:
		return X
def congrat_winner(the_winner, computer, human):
	if the_winner !=TIE:
		print("Три", the_winner, "в ряд!\n")
	else:
		print("Ничья!\n")
	if the_winner==computer:
		print("Kaк я и предсказывал. победа в очередной раз осталась за мной.\nВот еще один довод в пользу того. что компьютеры превосходят людей решительно во всем.")
	elif the_winner==human:
		print("О нет, этого не может быть! Неужели ты как-то сумел перехитрить меня, белковый?\nКлянусь: я, компьютер, не допущу этого больше никогда!")
	elif the_winner==TIE:
		print("Тебе несказанно повезло, дружок: ты сумел свести игру вничью.\nРадуйся же сегодняшнему успеху! Завтра уже не суждено его повторить.")
def main():
	display_instruct()
	computer, human=pieces()
	turn=X
	board=new_board()
	display_board(board)
	while  not winner(board):
		if turn==human:
			move=human_move(board, human)
			board[move]=human
		else:
			move=computer_move(board, computer, human)
			board[move]=computer
		display_board(board)
		turn=next_turn(turn)
	the_winner=winner(board)
	congrat_winner(the_winner, computer, human)
main()
input("\n\nНажмите Enter, чтобы выйти.")


#!/usr/bin/python3
# -*- coding: utf-8 -*-

str = """ACS3004 湖南新永利交通科工贸有限公司
ACS3005 三一帕尔菲格特种车装备有限公司
ACS3006 湖南新永利交通科工贸有限公司"""

print(str)

items = str.split(sep='\n')
for i, e in enumerate(items, 1):
    print(i, '. ', e.split(sep=' ')[0])

for i in range(1):
    print(i)


"""
Contains abstract functionality for learning locally linear sparse model.
"""
import numpy as np
import scipy as sp
from sklearn.linear_model import Ridge, lars_path
from sklearn.utils import check_random_state

class LimeBase(object):
    """Class for learning a locally linear sparse model from perturbed data"""
    def __init__(self,
                 kernel_fn,
                 verbose=False,
                 random_state=None):
        """Init function

        Args:
            kernel_fn: function that transforms an array of distances into an
                        array of proximity values (floats).
            verbose: if true, print local prediction values from linear model.
            random_state: an integer or numpy.RandomState that will be used to
                generate random numbers. If None, the random state will be
                initialized using the internal numpy seed.
        """
        self.kernel_fn = kernel_fn
        self.verbose = verbose
        self.random_state = check_random_state(random_state)

    @staticmethod
    def generate_lars_path(weighted_data, weighted_labels):
        """Generates the lars path for weighted data.

        Args:
            weighted_data: data that has been weighted by kernel
            weighted_label: labels, weighted by kernel

        Returns:
            (alphas, coefs), both are arrays corresponding to the
            regularization parameter and coefficients, respectively
        """
        x_vector = weighted_data
        alphas, _, coefs = lars_path(x_vector,
                                     weighted_labels,
                                     method='lasso',
                                     verbose=False)
        return alphas, coefs

    def forward_selection(self, data, labels, weights, num_features):
        """Iteratively adds features to the model"""
        clf = Ridge(alpha=0, fit_intercept=True, random_state=self.random_state)
        used_features = []
        for _ in range(min(num_features, data.shape[1])):
            max_ = -100000000
            best = 0
            for feature in range(data.shape[1]):
                if feature in used_features:
                    continue
                clf.fit(data[:, used_features + [feature]], labels,
                        sample_weight=weights)
                score = clf.score(data[:, used_features + [feature]],
                                  labels,
                                  sample_weight=weights)
                if score > max_:
                    best = feature
                    max_ = score
            used_features.append(best)
        return np.array(used_features)

    def feature_selection(self, data, labels, weights, num_features, method):
        """Selects features for the model. see explain_instance_with_data to
           understand the parameters."""
        if method == 'none':
            return np.array(range(data.shape[1]))
        elif method == 'forward_selection':
            return self.forward_selection(data, labels, weights, num_features)
        elif method == 'highest_weights':
            clf = Ridge(alpha=0.01, fit_intercept=True,
                        random_state=self.random_state)
            clf.fit(data, labels, sample_weight=weights)

            coef = clf.coef_
            if sp.sparse.issparse(data):
                coef = sp.sparse.csr_matrix(clf.coef_)
                weighted_data = coef.multiply(data[0])
                # Note: most efficient to slice the data before reversing
                sdata = len(weighted_data.data)
                argsort_data = np.abs(weighted_data.data).argsort()
                # Edge case where data is more sparse than requested number of feature importances
                # In that case, we just pad with zero-valued features
                if sdata < num_features:
                    nnz_indexes = argsort_data[::-1]
                    indices = weighted_data.indices[nnz_indexes]
                    num_to_pad = num_features - sdata
                    indices = np.concatenate((indices, np.zeros(num_to_pad, dtype=indices.dtype)))
                    indices_set = set(indices)
                    pad_counter = 0
                    for i in range(data.shape[1]):
                        if i not in indices_set:
                            indices[pad_counter + sdata] = i
                            pad_counter += 1
                            if pad_counter >= num_to_pad:
                                break
                else:
                    nnz_indexes = argsort_data[sdata - num_features:sdata][::-1]
                    indices = weighted_data.indices[nnz_indexes]
                return indices
            else:
                weighted_data = coef * data[0]
                feature_weights = sorted(
                    zip(range(data.shape[1]), weighted_data),
                    key=lambda x: np.abs(x[1]),
                    reverse=True)
                return np.array([x[0] for x in feature_weights[:num_features]])
        elif method == 'lasso_path':
            weighted_data = ((data - np.average(data, axis=0, weights=weights))
                             * np.sqrt(weights[:, np.newaxis]))
            weighted_labels = ((labels - np.average(labels, weights=weights))
                               * np.sqrt(weights))
            nonzero = range(weighted_data.shape[1])
            _, coefs = self.generate_lars_path(weighted_data,
                                               weighted_labels)
            for i in range(len(coefs.T) - 1, 0, -1):
                nonzero = coefs.T[i].nonzero()[0]
                if len(nonzero) <= num_features:
                    break
            used_features = nonzero
            return used_features
        elif method == 'auto':
            if num_features <= 6:
                n_method = 'forward_selection'
            else:
                n_method = 'highest_weights'
            return self.feature_selection(data, labels, weights,
                                          num_features, n_method)

    def explain_instance_with_data(self,
                                   neighborhood_data,
                                   neighborhood_labels,
                                   distances,
                                   label,
                                   num_features,
                                   feature_selection='auto',
                                   model_regressor=None):
        """Takes perturbed data, labels and distances, returns explanation.

        Args:
            neighborhood_data: perturbed data, 2d array. first element is
                               assumed to be the original data point.
            neighborhood_labels: corresponding perturbed labels. should have as
                                 many columns as the number of possible labels.
            distances: distances to original data point.
            label: label for which we want an explanation
            num_features: maximum number of features in explanation
            feature_selection: how to select num_features. options are:
                'forward_selection': iteratively add features to the model.
                    This is costly when num_features is high
                'highest_weights': selects the features that have the highest
                    product of absolute weight * original data point when
                    learning with all the features
                'lasso_path': chooses features based on the lasso
                    regularization path
                'none': uses all features, ignores num_features
                'auto': uses forward_selection if num_features <= 6, and
                    'highest_weights' otherwise.
            model_regressor: sklearn regressor to use in explanation.
                Defaults to Ridge regression if None. Must have
                model_regressor.coef_ and 'sample_weight' as a parameter
                to model_regressor.fit()

        Returns:
            (intercept, exp, score, local_pred):
            intercept is a float.
            exp is a sorted list of tuples, where each tuple (x,y) corresponds
            to the feature id (x) and the local weight (y). The list is sorted
            by decreasing absolute value of y.
            score is the R^2 value of the returned explanation
            local_pred is the prediction of the explanation model on the original instance
        """

        weights = self.kernel_fn(distances)
        labels_column = neighborhood_labels[:, label]
        used_features = self.feature_selection(neighborhood_data,
                                               labels_column,
                                               weights,
                                               num_features,
                                               feature_selection)
        if model_regressor is None:
            model_regressor = Ridge(alpha=1, fit_intercept=True,
                                    random_state=self.random_state)
        easy_model = model_regressor
        easy_model.fit(neighborhood_data[:, used_features],
                       labels_column, sample_weight=weights)
        prediction_score = easy_model.score(
            neighborhood_data[:, used_features],
            labels_column, sample_weight=weights)

        local_pred = easy_model.predict(neighborhood_data[0, used_features].reshape(1, -1))

        if self.verbose:
            print('Intercept', easy_model.intercept_)
            print('Prediction_local', local_pred,)
            print('Right:', neighborhood_labels[0, label])
        return (easy_model.intercept_,
                sorted(zip(used_features, easy_model.coef_),
                       key=lambda x: np.abs(x[1]), reverse=True),
                prediction_score, local_pred), easy_model


# Attempts to verify the solutions of discrete mathematics CW1

import random

def listUpTo(num):
    """
    Returns a lists of integers from 1 up to num
    """
    return list(range(1, num + 1))

def countMultiples(dividendList, divisor):
    """
    Returns the total number of multiples of the divisor in dividendList
    """
    multNum = 0

    for dividend in dividendList:
        if dividend % divisor == 0:
            multNum += 1

    return multNum

def solveQ1(myList, divisor, selectAmount, n):
    """
    Let X denote the number of successful trails in a given n trails.

    Selects a 'selectAmount' random elements from 'myList', checks whether it
    is a multiple of 'divisor', performs this for 'n' trails, then returns a
    probability point of X from it's binomial distribution.
    """

    X = 0

    for _ in range(n):
        random.shuffle(myList)

        for i, selected in enumerate(myList, start=1):

            if i == selectAmount:
                break
            else:
                if selected % divisor == 0:
                    X += 1

    p = X / (len(myList) * n * selectAmount)
    print(p)

if __name__ == "__main__":

    list40 = listUpTo(40)
    # print(list40)
    # print(countMultiples(list40, 4))
    # print()

    solveQ1(list40, 4, 2, 10000)


#!/usr/bin/env python3

# Hydrus is released under WTFPL
# You just DO WHAT THE FUCK YOU WANT TO.
# https://github.com/sirkris/WTFPL/blob/master/WTFPL.md

import locale

try: locale.setlocale( locale.LC_ALL, '' )
except: pass

try:

    import os
    import argparse
    import sys

    from hydrus.core import HydrusBoot

    HydrusBoot.AddBaseDirToEnvPath()

    # initialise Qt here, important it is done early
    from hydrus.client.gui import QtPorting as QP

    from hydrus.core import HydrusConstants as HC
    from hydrus.core import HydrusData
    from hydrus.core import HydrusGlobals as HG
    from hydrus.core import HydrusLogger
    from hydrus.core import HydrusPaths
    from hydrus.core import HydrusTemp

    argparser = argparse.ArgumentParser( description = 'hydrus network client' )

    argparser.add_argument( '-d', '--db_dir', help = 'set an external db location' )
    argparser.add_argument( '--temp_dir', help = 'override the program\'s temporary directory' )
    argparser.add_argument( '--db_journal_mode', default = 'WAL', choices = [ 'WAL', 'TRUNCATE', 'PERSIST', 'MEMORY' ], help = 'change db journal mode (default=WAL)' )
    argparser.add_argument( '--db_cache_size', type = int, help = 'override SQLite cache_size per db file, in MB (default=256)' )
    argparser.add_argument( '--db_transaction_commit_period', type = int, help = 'override how often (in seconds) database changes are saved to disk (default=30,min=10)' )
    argparser.add_argument( '--db_synchronous_override', type = int, choices = range(4), help = 'override SQLite Synchronous PRAGMA (default=2)' )
    argparser.add_argument( '--no_db_temp_files', action='store_true', help = 'run db temp operations entirely in memory' )
    argparser.add_argument( '--boot_debug', action='store_true', help = 'print additional bootup information to the log' )
    argparser.add_argument( '--no_wal', action='store_true', help = 'OBSOLETE: run using TRUNCATE db journaling' )
    argparser.add_argument( '--db_memory_journaling', action='store_true', help = 'OBSOLETE: run using MEMORY db journaling (DANGEROUS)' )

    result = argparser.parse_args()

    if result.db_dir is None:

        db_dir = HC.DEFAULT_DB_DIR

        if not HydrusPaths.DirectoryIsWriteable( db_dir ) or HC.RUNNING_FROM_MACOS_APP:

            if HC.USERPATH_DB_DIR is None:

                raise Exception( 'The default db path "{}" was not writeable, and the userpath could not be determined!'.format( HC.DEFAULT_DB_DIR ) )

            db_dir = HC.USERPATH_DB_DIR

    else:

        db_dir = result.db_dir

    db_dir = HydrusPaths.ConvertPortablePathToAbsPath( db_dir, HC.BASE_DIR )

    if not HydrusPaths.DirectoryIsWriteable( db_dir ):

        raise Exception( 'The given db path "{}" is not a writeable-to!'.format( db_dir ) )

    try:

        HydrusPaths.MakeSureDirectoryExists( db_dir )

    except:

        raise Exception( 'Could not ensure db path "{}" exists! Check the location is correct and that you have permission to write to it!'.format( db_dir ) )

    if not os.path.isdir( db_dir ):

        raise Exception( 'The given db path "{}" is not a directory!'.format( db_dir ) )

    HG.db_journal_mode = result.db_journal_mode

    if result.no_wal:

        HG.db_journal_mode = 'TRUNCATE'

    if result.db_memory_journaling:

        HG.db_journal_mode = 'MEMORY'

    if result.db_cache_size is not None:

        HG.db_cache_size = result.db_cache_size

    else:

        HG.db_cache_size = 256

    if result.db_transaction_commit_period is not None:

        HG.db_transaction_commit_period = max( 10, result.db_transaction_commit_period )

    else:

        HG.db_transaction_commit_period = 30

    if result.db_synchronous_override is not None:

        HG.db_synchronous = int( result.db_synchronous_override )

    else:

        if HG.db_journal_mode == 'WAL':

            HG.db_synchronous = 1

        else:

            HG.db_synchronous = 2

    HG.no_db_temp_files = result.no_db_temp_files

    HG.boot_debug = result.boot_debug

    try:

        from twisted.internet import reactor

    except:

        HG.twisted_is_broke = True

except Exception as e:

    try:

        HydrusData.DebugPrint( 'Critical boot error occurred! Details written to crash.log!' )
        HydrusData.PrintException( e )

    except:

        pass

    import traceback

    error_trace = traceback.format_exc()

    print( error_trace )

    if 'db_dir' in locals() and os.path.exists( db_dir ):

        emergency_dir = db_dir

    else:

        emergency_dir = os.path.expanduser( '~' )

        possible_desktop = os.path.join( emergency_dir, 'Desktop' )

        if os.path.exists( possible_desktop ) and os.path.isdir( possible_desktop ):

            emergency_dir = possible_desktop

    dest_path = os.path.join( emergency_dir, 'hydrus_crash.log' )

    with open( dest_path, 'w', encoding = 'utf-8' ) as f:

        f.write( error_trace )

    print( 'Critical boot error occurred! Details written to hydrus_crash.log in either db dir or user dir!' )

    sys.exit( 1 )

def boot():

    if result.temp_dir is not None:

        HydrusTemp.SetEnvTempDir( result.temp_dir )

    controller = None

    with HydrusLogger.HydrusLogger( db_dir, 'client' ) as logger:

        try:

            HydrusData.Print( 'hydrus client started' )

            if not HG.twisted_is_broke:

                import threading

                threading.Thread( target = reactor.run, name = 'twisted', kwargs = { 'installSignalHandlers' : 0 } ).start()

            from hydrus.client import ClientController

            controller = ClientController.Controller( db_dir )

            controller.Run()

        except:

            HydrusData.Print( 'hydrus client failed' )

            import traceback

            HydrusData.Print( traceback.format_exc() )

        finally:

            HG.started_shutdown = True
            HG.view_shutdown = True
            HG.model_shutdown = True

            if controller is not None:

                controller.pubimmediate( 'wake_daemons' )

            if not HG.twisted_is_broke:

                reactor.callFromThread( reactor.stop )

            HydrusData.Print( 'hydrus client shut down' )

    HG.shutdown_complete = True

    if HG.restart:

        HydrusData.RestartProcess()


"""
Created on Oct 2, 2012

@author: Georgiana Dinu, Pham The Nghia
"""
from composes.similarity.similarity import Similarity

class EuclideanSimilarity(Similarity):
    """
    Computes the euclidean similarity of two vectors as the inverse of their
    euclidean distance.

    :math:`sim(\\vec{u},\\vec{v}) = \\frac{1}{||\\vec{u}-\\vec{v}|| + 1}`
    """

    def _sim(self, v1, v2):
        return 1 / (1 + (v1 - v2).norm())


print('-*-' * 15)
print('SISTEMA CAIXA ELETRONICO')
print('-*-' * 15)

valor = float(input('Qual será o valor sacado? '))
cedula = 100
qtd = 0
total = valor

if valor < 1:
    print('Saque somente acima de R$1! ')

while True:
    if valor >= cedula:
        valor = valor - cedula
        qtd += 1
    else:
        if qtd > 0:
            print(F'Total de {qtd} de cedulas de R${cedula}')
        if cedula == 100:
            cedula = 50
        elif cedula == 50:
            cedula = 20
        elif cedula == 20:
            cedula = 10
        elif cedula == 10:
            cedula = 5
        elif cedula == 5:
            cedula = 2
        elif cedula == 2:
            cedula = 1
        qtd = 0
        if total == 0:
            break


# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

"""
Base tests that all storage providers should implement in their own tests.
They handle the storage-based assertions, internally.

All tests return true if assertions pass to indicate that the code ran to completion, passing internal assertions.
Therefore, all tests using theses static tests should strictly check that the method returns true.

Note: Python cannot have dicts with properties with a None value like other SDKs can have properties with null values.
      Because of this, StoreItem tests have "e_tag: *" where the tests in the other SDKs do not.
      This has also caused us to comment out some parts of these tests where we assert that "e_tag"
      is None for the same reason. A null e_tag should work just like a * e_tag when writing,
      as far as the storage adapters are concerened, so this shouldn't cause issues.

:Example:
    async def test_handle_null_keys_when_reading(self):
        await reset()

        test_ran = await StorageBaseTests.handle_null_keys_when_reading(get_storage())

        assert test_ran
"""
import pytest
from botbuilder.azure import CosmosDbStorage
from botbuilder.core import (
    ConversationState,
    TurnContext,
    MessageFactory,
    MemoryStorage,
)
from botbuilder.core.adapters import TestAdapter
from botbuilder.dialogs import (
    DialogSet,
    DialogTurnStatus,
    TextPrompt,
    PromptValidatorContext,
    WaterfallStepContext,
    Dialog,
    WaterfallDialog,
    PromptOptions,
)

class StorageBaseTests:
    # pylint: disable=pointless-string-statement
    @staticmethod
    async def return_empty_object_when_reading_unknown_key(storage) -> bool:
        result = await storage.read(["unknown"])

        assert result is not None
        assert len(result) == 0

        return True

    @staticmethod
    async def handle_null_keys_when_reading(storage) -> bool:
        if isinstance(storage, (CosmosDbStorage, MemoryStorage)):
            result = await storage.read(None)
            assert len(result.keys()) == 0
        # Catch-all
        else:
            with pytest.raises(Exception) as err:
                await storage.read(None)
            assert err.value.args[0] == "Keys are required when reading"

        return True

    @staticmethod
    async def handle_null_keys_when_writing(storage) -> bool:
        with pytest.raises(Exception) as err:
            await storage.write(None)
        assert err.value.args[0] == "Changes are required when writing"

        return True

    @staticmethod
    async def does_not_raise_when_writing_no_items(storage) -> bool:
        # noinspection PyBroadException
        try:
            await storage.write([])
        except:
            pytest.fail("Should not raise")

        return True

    @staticmethod
    async def create_object(storage) -> bool:
        store_items = {
            "createPoco": {"id": 1},
            "createPocoStoreItem": {"id": 2, "e_tag": "*"},
        }

        await storage.write(store_items)

        read_store_items = await storage.read(store_items.keys())

        assert store_items["createPoco"]["id"] == read_store_items["createPoco"]["id"]
        assert (
            store_items["createPocoStoreItem"]["id"]
            == read_store_items["createPocoStoreItem"]["id"]
        )

        # If decided to validate e_tag integrity again, uncomment this code
        # assert read_store_items["createPoco"]["e_tag"] is not None
        assert read_store_items["createPocoStoreItem"]["e_tag"] is not None

        return True

    @staticmethod
    async def handle_crazy_keys(storage) -> bool:
        key = '!@#$%^&*()_+??><":QASD~`'
        store_item = {"id": 1}
        store_items = {key: store_item}

        await storage.write(store_items)

        read_store_items = await storage.read(store_items.keys())

        assert read_store_items[key] is not None
        assert read_store_items[key]["id"] == 1

        return True

    @staticmethod
    async def update_object(storage) -> bool:
        original_store_items = {
            "pocoItem": {"id": 1, "count": 1},
            "pocoStoreItem": {"id": 1, "count": 1, "e_tag": "*"},
        }

        # 1st write should work
        await storage.write(original_store_items)

        loaded_store_items = await storage.read(["pocoItem", "pocoStoreItem"])

        update_poco_item = loaded_store_items["pocoItem"]
        update_poco_item["e_tag"] = None
        update_poco_store_item = loaded_store_items["pocoStoreItem"]
        assert update_poco_store_item["e_tag"] is not None

        # 2nd write should work
        update_poco_item["count"] += 1
        update_poco_store_item["count"] += 1

        await storage.write(loaded_store_items)

        reloaded_store_items = await storage.read(loaded_store_items.keys())

        reloaded_update_poco_item = reloaded_store_items["pocoItem"]
        reloaded_update_poco_store_item = reloaded_store_items["pocoStoreItem"]

        assert reloaded_update_poco_item["count"] == 2
        assert reloaded_update_poco_store_item["count"] == 2

        # Write with old e_tag should succeed for non-storeItem
        update_poco_item["count"] = 123
        await storage.write({"pocoItem": update_poco_item})

        # Write with old eTag should FAIL for storeItem
        update_poco_store_item["count"] = 123

        """
        This assert exists in the other SDKs but can't in python, currently
        due to using "e_tag: *" above (see comment near the top of this file for details).

        with pytest.raises(Exception) as err:
            await storage.write({"pocoStoreItem": update_poco_store_item})
        assert err.value is not None
        """

        reloaded_store_items2 = await storage.read(["pocoItem", "pocoStoreItem"])

        reloaded_poco_item2 = reloaded_store_items2["pocoItem"]
        reloaded_poco_item2["e_tag"] = None
        reloaded_poco_store_item2 = reloaded_store_items2["pocoStoreItem"]

        assert reloaded_poco_item2["count"] == 123
        assert reloaded_poco_store_item2["count"] == 2

        # write with wildcard etag should work
        reloaded_poco_item2["count"] = 100
        reloaded_poco_store_item2["count"] = 100
        reloaded_poco_store_item2["e_tag"] = "*"

        wildcard_etag_dict = {
            "pocoItem": reloaded_poco_item2,
            "pocoStoreItem": reloaded_poco_store_item2,
        }

        await storage.write(wildcard_etag_dict)

        reloaded_store_items3 = await storage.read(["pocoItem", "pocoStoreItem"])

        assert reloaded_store_items3["pocoItem"]["count"] == 100
        assert reloaded_store_items3["pocoStoreItem"]["count"] == 100

        # Write with empty etag should not work
        reloaded_store_items4 = await storage.read(["pocoStoreItem"])
        reloaded_store_item4 = reloaded_store_items4["pocoStoreItem"]

        assert reloaded_store_item4 is not None

        reloaded_store_item4["e_tag"] = ""
        dict2 = {"pocoStoreItem": reloaded_store_item4}

        with pytest.raises(Exception) as err:
            await storage.write(dict2)
        assert err.value is not None

        final_store_items = await storage.read(["pocoItem", "pocoStoreItem"])
        assert final_store_items["pocoItem"]["count"] == 100
        assert final_store_items["pocoStoreItem"]["count"] == 100

        return True

    @staticmethod
    async def delete_object(storage) -> bool:
        store_items = {"delete1": {"id": 1, "count": 1, "e_tag": "*"}}

        await storage.write(store_items)

        read_store_items = await storage.read(["delete1"])

        assert read_store_items["delete1"]["e_tag"]
        assert read_store_items["delete1"]["count"] == 1

        await storage.delete(["delete1"])

        reloaded_store_items = await storage.read(["delete1"])

        assert reloaded_store_items.get("delete1", None) is None

        return True

    @staticmethod
    async def delete_unknown_object(storage) -> bool:
        # noinspection PyBroadException
        try:
            await storage.delete(["unknown_key"])
        except:
            pytest.fail("Should not raise")

        return True

    @staticmethod
    async def perform_batch_operations(storage) -> bool:
        await storage.write(
            {"batch1": {"count": 10}, "batch2": {"count": 20}, "batch3": {"count": 30},}
        )

        result = await storage.read(["batch1", "batch2", "batch3"])

        assert result.get("batch1", None) is not None
        assert result.get("batch2", None) is not None
        assert result.get("batch3", None) is not None
        assert result["batch1"]["count"] == 10
        assert result["batch2"]["count"] == 20
        assert result["batch3"]["count"] == 30
        """
        If decided to validate e_tag integrity aagain, uncomment this code
        assert result["batch1"].get("e_tag", None) is not None
        assert result["batch2"].get("e_tag", None) is not None
        assert result["batch3"].get("e_tag", None) is not None
        """

        await storage.delete(["batch1", "batch2", "batch3"])

        result = await storage.read(["batch1", "batch2", "batch3"])

        assert result.get("batch1", None) is None
        assert result.get("batch2", None) is None
        assert result.get("batch3", None) is None

        return True

    @staticmethod
    async def proceeds_through_waterfall(storage) -> bool:
        convo_state = ConversationState(storage)

        dialog_state = convo_state.create_property("dialogState")
        dialogs = DialogSet(dialog_state)

        async def exec_test(turn_context: TurnContext) -> None:
            dialog_context = await dialogs.create_context(turn_context)

            await dialog_context.continue_dialog()
            if not turn_context.responded:
                await dialog_context.begin_dialog(WaterfallDialog.__name__)
            await convo_state.save_changes(turn_context)

        adapter = TestAdapter(exec_test)

        async def prompt_validator(prompt_context: PromptValidatorContext):
            result = prompt_context.recognized.value
            if len(result) > 3:
                succeeded_message = MessageFactory.text(
                    f"You got it at the {prompt_context.options.number_of_attempts}rd try!"
                )
                await prompt_context.context.send_activity(succeeded_message)
                return True

            reply = MessageFactory.text(
                f"Please send a name that is longer than 3 characters. {prompt_context.options.number_of_attempts}"
            )
            await prompt_context.context.send_activity(reply)
            return False

        async def step_1(step_context: WaterfallStepContext) -> DialogTurnStatus:
            assert isinstance(step_context.active_dialog.state["stepIndex"], int)
            await step_context.context.send_activity("step1")
            return Dialog.end_of_turn

        async def step_2(step_context: WaterfallStepContext) -> None:
            assert isinstance(step_context.active_dialog.state["stepIndex"], int)
            await step_context.prompt(
                TextPrompt.__name__,
                PromptOptions(prompt=MessageFactory.text("Please type your name")),
            )

        async def step_3(step_context: WaterfallStepContext) -> DialogTurnStatus:
            assert isinstance(step_context.active_dialog.state["stepIndex"], int)
            await step_context.context.send_activity("step3")
            return Dialog.end_of_turn

        steps = [step_1, step_2, step_3]

        dialogs.add(WaterfallDialog(WaterfallDialog.__name__, steps))

        dialogs.add(TextPrompt(TextPrompt.__name__, prompt_validator))

        step1 = await adapter.send("hello")
        step2 = await step1.assert_reply("step1")
        step3 = await step2.send("hello")
        step4 = await step3.assert_reply("Please type your name")  # None
        step5 = await step4.send("hi")
        step6 = await step5.assert_reply(
            "Please send a name that is longer than 3 characters. 0"
        )
        step7 = await step6.send("hi")
        step8 = await step7.assert_reply(
            "Please send a name that is longer than 3 characters. 1"
        )
        step9 = await step8.send("hi")
        step10 = await step9.assert_reply(
            "Please send a name that is longer than 3 characters. 2"
        )
        step11 = await step10.send("Kyle")
        step12 = await step11.assert_reply("You got it at the 3rd try!")
        await step12.assert_reply("step3")

        return True


import numpy as np
from manimlib.mobject.mobject import Mobject

class ValueTracker(Mobject):
    """
    Note meant to be displayed.  Instead the position encodes some
    number, often one which another animation or continual_animation
    uses for its update function, and by treating it as a mobject it can
    still be animated and manipulated just like anything else.
    """

    def __init__(self, value=0, **kwargs):
        Mobject.__init__(self, **kwargs)
        self.points = np.zeros((1, 3))
        self.set_value(value)

    def get_value(self):
        return self.points[0, 0]

    def set_value(self, value):
        self.points[0, 0] = value
        return self

    def increment_value(self, d_value):
        self.set_value(self.get_value() + d_value)

class ExponentialValueTracker(ValueTracker):
    """
    Operates just like ValueTracker, except it encodes the value as the
    exponential of a position coordinate, which changes how interpolation
    behaves
    """

    def get_value(self):
        return np.exp(ValueTracker.get_value(self))

    def set_value(self, value):
        return ValueTracker.set_value(self, np.log(value))

class ComplexValueTracker(ValueTracker):
    def get_value(self):
        return complex(*self.points[0, :2])

    def set_value(self, z):
        z = complex(z)
        self.points[0, :2] = (z.real, z.imag)
        return self