#!/usr/bin/env python
#-*- coding:utf-8 -*-
#Created on 2017-6-10 by Author:GuoLikai

import docker
import socket
import time

from shipman.curl import Curl
from shipman.model.node import NodeInfo

class Myswarm(object):
    def ping_port(self, ip, port):
        cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        cs.settimeout(0.2)
        address = (str(ip), int(port))
        try:
            cs.connect((address))
        except socket.error as e:
            print(e)
            return 1
        cs.close()
        return 0

    def delete_con_usage(self, container_id):
        if not container_id:
            return
        else:
            NodeInfo.delete_con_usage(container_id)

    def _container_detail(self, node_ip, node_port, containers_id):
        url = ('http://' + node_ip + ":" + node_port + "/containers/" + containers_id + "/json")
        container_more_url = Curl(url)
        ret_json = container_more_url.get_value()
        return ret_json

    def container_list(self, node_ip, node_port):
        #print(node_ip)
        #print(node_port)
        url = 'http://' + node_ip + ":" + node_port + "/containers/json?all=1"
        container_url = Curl(url)
        ret_json = container_url.get_value()

        con_data = {}
        container_id = []
        if ret_json:
            for i in ret_json:
                container_id.append(i['Id'][0:12])
        else:
            return con_data

        if len(container_id) < 1:
            return con_data
        else:
            con_data = {}
            con_num = 1
            for con_id in container_id:
                tmp_dict = {}
                ret_json = self._container_detail(node_ip, node_port, con_id)
                if len(ret_json) < 1:
                    return con_data
                con_state = ""
                if ('Running' in ret_json['State'].keys()) and (
                    'Status' not in ret_json['State'].keys()):  # for docker 1.7
                    con_state = str(ret_json['State']['Running'])
                elif 'Status' in ret_json['State'].keys():  # for docker 1.9 and higher
                    con_state = str(ret_json['State']['Status'])
                else:  # for else
                    con_state = "Exited"
                tmp_dict['id_num'] = ret_json['Id'][0:12]
                tmp_dict['con_ip'] = ret_json['NetworkSettings']['IPAddress']
                tmp_dict['con_name'] = ret_json['Name'].replace('/','')
                tmp_dict['cpuperiod'] = ret_json['HostConfig']['CpuPeriod']
                tmp_dict['cpuquota'] = ret_json['HostConfig']['CpuQuota']
                tmp_dict['memory'] = ret_json['HostConfig']['Memory']
                tmp_dict['state'] = con_state
                tmp_dict['cmd'] = str(ret_json['Config']['Cmd'])
                tmp_dict['created'] = ret_json['State']['StartedAt']
                con_data[con_num] = tmp_dict
                con_num += 1
        return con_data

    def images_list(self, node_ip, node_port):
        client_ins = docker.Client(base_url='tcp://' + node_ip + ':' + node_port, version='1.20', timeout=5)
        ret_json = client_ins.images()
        images_list = []
        for one in ret_json:
            images_list.append(one['RepoTags'])
        return images_list

    def create_container(self, node_ip, node_port, conf):
        client_ins = docker.Client(base_url='tcp://' + node_ip + ":" + node_port, version='1.20', timeout=5)
        print("      Create the container......")
        container_ret = client_ins.create_container(image=conf['Image'],
                                                    stdin_open=conf['OpenStdin'],
                                                    tty=conf['Tty'],
                                                    command=conf['Cmd'],
                                                    name=conf['Name'],
                                                    hostname=conf['Hostname'],
                                                    host_config=conf['HostConfig'])
        if container_ret:
            time.sleep(0.3)
            return (container_ret['Id'])
        else:
            print("Can not create container")
            return

    def start_container(self,node_ip,node_port,container_id):
        if len(container_id) > 0:
            container_ip = ""
            client_ins = docker.Client(base_url='tcp://' + node_ip + ":" + node_port, version='1.20', timeout=5)
            client_ins.start(container_id)
            time.sleep(0.5)
            con_info = self._container_detail(node_ip, node_port,container_id)
            ret = NodeInfo.get_con_usage_info(container_id,node_ip)
            print(ret)
            if len(ret) == 0:
                NodeInfo.insert_con_usage(container_id[0:12],con_info['NetworkSettings']['IPAddress'],con_info['Name'].replace('/',''),node_ip)
            else:
                #print('update_con_usage')
                #print(con_info['NetworkSettings']['IPAddress'], con_info['Name'].replace('/', ''), node_ip, container_id[0:12])
                NodeInfo.update_con_usage(container_id[0:12],con_info['NetworkSettings']['IPAddress'],con_info['Name'].replace('/',''),node_ip)
            return 0
        else:
            print("Please enter the Container ID")
            return

    def container_info(self, node_ip, node_port, container_id):
        con_data = {}
        tmp_dict = {}
        ip_ret = ""
        ret_json = self._container_detail(node_ip, node_port, container_id)
        if len(ret_json) < 1:
            return con_data

        con_state = ""
        if ('Running' in ret_json['State'].keys()) and ('Status' not in ret_json['State'].keys()):  # for docker 1.7
            con_state = str(ret_json['State']['Running'])
        elif 'Status' in ret_json['State'].keys():  # for docker 1.9 and higher
            con_state = str(ret_json['State']['Status'])
        else:  # for else
            con_state = "Exited"
        tmp_dict['id_num'] = ret_json['Id'][0:12]
        tmp_dict['node_ip'] = node_ip
        tmp_dict['con_ip'] = ret_json['NetworkSettings']['IPAddress']
        tmp_dict['name'] = ret_json['Name'].replace('/','')
        tmp_dict['image'] = ret_json['Image']
        tmp_dict['created'] = ret_json['State']['StartedAt']
        tmp_dict['state'] = con_state
        tmp_dict['memory'] = ret_json['HostConfig']['Memory']
        tmp_dict['cpuperiod'] = ret_json['HostConfig']['CpuPeriod']
        tmp_dict['cpuquota'] = ret_json['HostConfig']['CpuQuota']
        tmp_dict['hostname'] = str(ret_json['Config']['Hostname'])
        tmp_dict['cmd'] = str(ret_json['Config']['Cmd'])
        con_data[1] = tmp_dict
        return con_data

    def stop_container(self, node_ip, node_port, container_id):
        if len(container_id) > 0:
            print("      Stop the container %s ........" % container_id)
            client_ins = docker.Client(base_url='tcp://' + node_ip + ":"
                                                + node_port, version='1.20', timeout=5)
            client_ins.stop(container_id)
        else:
            print("Please enter the Container ID")
            return

    def destroy_container(self, node_ip, node_port, container_id):
        if len(container_id) > 0:
            print("      Destroy the container %s ....... " % container_id)
            client_ins = docker.Client(base_url='tcp://' + node_ip + ':'
                                                + node_port, version='1.20', timeout=5)
            try:
                client_ins.stop(container_id)
                time.sleep(0.3)
                client_ins.remove_container(container_id)
                time.sleep(0.3)
            except docker.errors.NotFound:
                print("      NO Such container id")
            self.delete_con_usage(container_id)
        else:
            print("Please enter the Container ID")
            return 1

    def node_info(self,node_ip, node_port):
        url = ('http://' + node_ip + ":" + node_port + "/info")
        node_more_url = Curl(url)
        ret_json = node_more_url.get_value()
        return ret_json

def main_node_info():
    myswarm = Myswarm()
    #for image in myswarm.images_list("172.16.1.101","2375"):
    #    print(image)
    node_info = myswarm.node_info("172.16.1.101","2375")
    print(node_info["Name"])
    #print(node_ip)
    #print(port)
    print(node_info["NCPU"])
    print(node_info["MemTotal"])
    print(node_info["Images"])
    #print(node_info["state"])
    #print(node_group)
    print(node_info["Containers"])
    print(node_info["OperatingSystem"])
    print(node_info["PkgVersion"])
    print(node_info["KernelVersion"])

def main_con_info():
    myswarm = Myswarm()
    node_ip = "172.16.1.101"
    port = "2375"
    con_data = myswarm.container_list(node_ip,port)
    for con in con_data:
        print(con_data[con]["id_num"],con_data[con]["con_ip"],con_data[con]["con_name"],node_ip)

if __name__ == '__main__':
    main_con_info()


def xclist(*args):
    configs = ""
    for arg in args:
        configs = configs + " %s" % arg
    return configs

_configs = {
    # Plist
    "DEVELOPMENT_TEAM" : 'SDSLU2QT5X',
    "BUNDLE_PREFIX" : 'com.muiz.idn',
    "PRODUCT_BUNDLE_IDENTIFIER" : 'com.muiz.idn.todo.ios',
    "PRODUCT_NAME" : 'TodoApp',
    "KEYCHAIN_GROUP" : 'SDSLU2QT5X.com.muiz.idn.todo.ios',
    "APP_BUILD_VERSION" : '1.0',
    "APP_BUILD_NUMBER" : '1',
    # Buck
    "INFOPLIST_FILE": "Sources/Todo/Info.plist",
    # Xcode Configs
    "IPHONEOS_DEPLOYMENT_TARGET": "%s" % native.read_config("apple", "iphoneos_target_sdk_version"),
    "SDKROOT": "iphoneos",
    "GCC_OPTIMIZATION_LEVEL": "0",
    "SWIFT_WHOLE_MODULE_OPTIMIZATION": "YES",
    "ONLY_ACTIVE_ARCH": "YES",
    "LD_RUNPATH_SEARCH_PATHS": "@executable_path/Frameworks",
    "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES": "YES",
    "DEVELOPMENT_LANGUAGE": "en",
    "SWIFT_OPTIMIZATION_LEVEL": "-Onone",
    "OTHER_LDFLAGS": "$(inherited) -all_load",
    "OTHER_SWIFT_FLAGS": xclist("$(inherited)"),
    "EXECUTABLE_NAME": "TodoApp"
}

def config(key):
    return _configs[key]

def get(key, *strings):
    return { key : _configs[key] + xclist(*strings) }

# https://stackoverflow.com/a/26853961
def merge(*dict_args):
    """
    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in latter dicts.
    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result

def project_configs():
    debug = merge(
        get("PRODUCT_BUNDLE_IDENTIFIER"),
        get("SDKROOT"),
        get("IPHONEOS_DEPLOYMENT_TARGET"),
        get("APP_BUILD_VERSION"),
        get("APP_BUILD_NUMBER"),
        get("OTHER_SWIFT_FLAGS", "-DDEBUG"),
    )
    profile = merge(
        # get("PRODUCT_BUNDLE_IDENTIFIER"),
        # get("SDKROOT"),
        # get("IPHONEOS_DEPLOYMENT_TARGET"),
        # get("APP_BUILD_VERSION"),
        # get("APP_BUILD_NUMBER"),
        # get("OTHER_SWIFT_FLAGS", "-DDEBUG"),
    )
    release = merge(
    )
    final_configs = {
        "Debug": debug,
        "Profile": profile,
        "Release": release
    }
    return final_configs

def project_info_plist_substitutions():
    return merge(
        get("DEVELOPMENT_LANGUAGE"),
        get("PRODUCT_BUNDLE_IDENTIFIER"),
        get("APP_BUILD_VERSION"),
        get("APP_BUILD_NUMBER"),
        get("KEYCHAIN_GROUP"),
    )


import ply.lex as lex
import ply.yacc as yacc
syntax_correct = True
tokens = [
    'CASE',
    'WHEN',
    'END',
    'IDENTIFIER',
    'COLON',
    'NUMBER',
    'PLUS',
    'MINUS',
    'TIMES',
    'DIVIDE',
    'LPAREN',
    'RPAREN',
    'EQ',
    'NEQ',
    'LT',
    'LE',
    'GT',
    'GE',
    'ASSIGN'
]
t_IDENTIFIER = r'[a-zA-Z_"][a-zA-Z0-9_"]*'  # Updated regular expression
t_COLON = r':'
t_NUMBER = r'\d+'
t_PLUS = r'\+'
t_MINUS = r'-'
t_TIMES = r'\*'
t_DIVIDE = r'/'
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_EQ = r'=='
t_NEQ = r'!='
t_LT = r'<'
t_LE = r'<='
t_GT = r'>'
t_GE = r'>='
t_ASSIGN = r'='
t_ignore = ' \t\n'
# Special case handling for CASE and END
def t_CASE(t):
    r'case'
    return t
def t_END(t):
    r'end'
    return t
def t_WHEN(t):
    r'when'
    return t
# Parser
def p_switch_statement(p):
    '''
    switch_statement : CASE expression COLON when_clauses END
    '''

def p_when_clauses(p):
    '''
    when_clauses : when_clause when_clauses
                 | empty
    '''

def p_when_clause(p):
    '''
    when_clause : WHEN expression COLON statements
    '''

def p_statements(p):
    '''
    statements : statement statements
               | empty
    '''

def p_statement(p):
    '''
    statement : assignment_statement
                | empty

    '''
def p_assignment_statement(p):
    '''
    assignment_statement : IDENTIFIER ASSIGN expression
    '''
def p_expression(p):
    '''
    expression : NUMBER
               | IDENTIFIER
               | expression PLUS expression
               | expression MINUS expression
               | expression TIMES expression
               | expression DIVIDE expression
               | LPAREN expression RPAREN
               | expression EQ expression
               | expression NEQ expression
               | expression LT expression
               | expression LE expression
               | expression GT expression
               | expression GE expression
    '''

def p_empty(p):
    '''
    empty :
    '''

def p_error(p):
    global syntax_correct
    syntax_correct = False
    print(f"Syntax error at line {p.lineno}, Unexpected token '{p.value}'")
    exit(0)
# Build the lexer and parser
lexer = lex.lex()
parser = yacc.yacc()

# Test the parser with a Ruby switch case statement
ruby_code = """
cse x:
  when :
    a=b
  whe 2:
    b=c
ed
"""

lexer.input(ruby_code)
for token in lexer:
    print(token)
if syntax_correct:
    print("Syntax is correct.")
else:
    print("Incorrect syntax")
parser.parse(ruby_code)


import argparse
import json
import logging
import os
import shutil
import sys
import tempfile

from datetime import datetime

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(name="wt-util")
logger.setLevel(logging.DEBUG)

currdir = os.path.dirname(os.path.abspath(__file__))
options = {
    "original_settings_filepath": "",
    "backup_dir": os.path.join(currdir, "backup")
}

def parse_cmd_arguments():
    parser = argparse.ArgumentParser(prog="wt-util",
                                     description="Script to update windows terminal settings json",
                                     formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    # https://stackoverflow.com/questions/24180527/argparse-required-arguments-listed-under-optional-arguments

    mandatoryArgs = parser.add_argument_group("mandatory arguments")

    mandatoryArgs.add_argument("-s", "--settings",
                        type=str,
                        help="full path to windows terminal settings.json",
                        required=True)
    mandatoryArgs.add_argument("-p", "--profile",
                        type=str,
                        help="wt profile name",
                        required=True)
    mandatoryArgs.add_argument("-k", "--key",
                        type=str,
                        help="settings key in the given profile to be updated",
                        required=True)
    mandatoryArgs.add_argument("-v", "--value",
                        type=str,
                        help="new value to be updated for the given key",
                        required=True)
    parser.add_argument("-o", "--output-file",
                        type=str,
                        help="Updated settings will be written to this file.If not given original settings file will be overwritten",
                        default="")
    return parser.parse_args()

def set_options(cmd_options):
    options["original_settings_filepath"] = cmd_options.settings
    options["profile_name"] = cmd_options.profile
    options["settings_key"] = cmd_options.key
    options["settings_value"] = cmd_options.value
    if (cmd_options.output_file != ""):
        options["output_file"] = cmd_options.output_file
    else:
        options["output_file"] = cmd_options.settings

def create_backup_settings(backup_filepath):
    logger.debug("Creating backup of settings json")
    shutil.copy2(options["original_settings_filepath"],
                 backup_filepath)
    logger.debug("Successfully created backup of settings json")

def test_backup():
    with tempfile.TemporaryDirectory() as tempdir:
        backup_file = os.path.join(tempdir, "settings_bk.json")
        logger.debug(backup_file)
        create_backup_settings(backup_file)
        original_file_lines = 0
        backup_file_lines = 0
        with open(options["original_settings_filepath"], 'r') as f:
            original_file_lines = len(f.readlines())

        with open(backup_file, 'r') as f:
            backup_file_lines = len(f.readlines())

        assert original_file_lines == backup_file_lines

def test():
    test_backup()

def get_timestr():
    now = datetime.today()
    date = now.date()
    time = now.time()
    return "{}_{}_{}_{}_{}_{}".format(date.day, date.month, date.year,
                                      time.hour, time.minute, time.second)

def check_options():
    if (not os.path.isfile(options["original_settings_filepath"])):
        raise FileNotFoundError("Incorrect settings json path")

def get_backup_filepath():
    os.makedirs(options["backup_dir"], exist_ok=True)
    backup_filepath = os.path.join(options["backup_dir"],
                                   "settings_bk_{}.json".format(get_timestr()))
    return backup_filepath

def load_json(filepath: str) -> dict:
    with open(filepath, 'r') as file:
        return json.load(file)

def write_json(d: dict, json_filepath: str):
    with open(json_filepath, 'w') as file:
        json.dump(d, file, indent=4)

def get_profile_idx(profiles_list: list, profile_name: str) -> int:
    for idx, profile in enumerate(profiles_list):
        if (profile["name"] == profile_name):
            return idx
    raise ValueError("There is no profile in settings with name %(name)s" % {
                     "name": profile_name})

def get_updated_settings() -> dict:
    settings_dict = load_json(options["original_settings_filepath"])
    profile_idx = get_profile_idx(
        settings_dict["profiles"]["list"], options["profile_name"])
    sys.stdout.write("Profile: {}\n".format(options["profile_name"]))
    sys.stdout.write("Key: {}\n".format(options["settings_key"]))
    sys.stdout.write("Previous value: {}\n".format(
        settings_dict["profiles"]["list"][profile_idx].get(options["settings_key"], '""')))
    sys.stdout.write("New value: {}\n".format(options["settings_value"]))

    settings_dict["profiles"]["list"][profile_idx][options["settings_key"]] = options["settings_value"]
    return settings_dict

def write_settings(settings_dict: dict):
    write_json(settings_dict, options["output_file"])
    sys.stdout.write("Settings updated successfully\n")

def main():
    cmd_options = parse_cmd_arguments()
    set_options(cmd_options)
    check_options()
    create_backup_settings(get_backup_filepath())
    new_settings = get_updated_settings()
    write_settings(new_settings)

if __name__ == "__main__":
    main()
    # test()


import sqlite3 as sq3
conn=sq3.connect("First.db")
#==================================================
cur=conn.cursor()
cur.execute('Create table T_fish(date text,name text,nums int,price real,Explain text)')
cur.execute("insert into T_fish Values('2018-3-28','黑鱼',10,28.3,'Tom')")
conn.commit()

#==================================================
conn.close


""" 171. Excel Sheet Column Number

Given a column title as appear in an Excel sheet, return its corresponding column number.

For example:

    A -> 1
    B -> 2
    C -> 3
    ...
    Z -> 26
    AA -> 27
    AB -> 28
    ...
Example 1:

Input: "A"
Output: 1
Example 2:

Input: "AB"
Output: 28
Example 3:

Input: "ZY"
Output: 701

https://leetcode.com/problems/excel-sheet-column-number/description/
"""

class Solution:
    def titleToNumber(self, s):
        """
        :type s: str
        :rtype: int
        """
        ans = 0
        for idx, val in enumerate(reversed(s.lower())):
            ans += 26 ** idx * (ord(val) - ord('a') + 1)
        return ans


class Singleton(object):
    # overwriting __new__ method, this is how we ensure that it returns always the same object
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance

s0 = Singleton()
s1 = Singleton()
print(s0)
print(s1)
print(s0 == s1)


#!/usr/bin/env python

#
# REST server implementation
# author:   L. Saetta
# updated:  18/10/2021
# based on some code from https://github.com/philipperemy/deep-speaker
#
import io
import time
import os
import logging
import json
import uvicorn
import numpy as np
from fastapi import FastAPI, UploadFile, File, HTTPException
from fastapi.responses import StreamingResponse

# needed for the cloud, access to Object Storage
import oci
import ocifs

# global configurations in config.py
import config

# the DL model
from conv_models import DeepSpeakerModel

# code for adding new speakers to DB
from speaker_management import add_speaker

# utilities functions
from utilities import compute_embeddings, distance_cosine_similarity, print_dict
from utilities import load_centroids_newfile, save_wav, swap_centroids_files_local, swap_centroids_files_oss
from utilities import NumpyArrayEncoder, load_centroids_from_oss, load_centroids_from_local
from utilities import create_path, write_new_centroids_to_oss, write_new_centroids_to_local
from utilities import restore_centroids_from_bck_local, restore_centroids_from_bck_oss, get_list_speakers_names

#
# constants for audio processing
#
from constants import SAMPLE_RATE, NUM_FRAMES

#
# log settings
#
log = logging.getLogger("server")
logging.basicConfig(format='%(asctime)s %(levelname)-8s %(message)s',
    level=os.environ.get("LOGLEVEL", "INFO"), datefmt='%Y-%m-%d %H:%M:%S')

log.info("Starting the server...")

#
# Functions
#

#
# load the pre-trained DL model
#
def load_model():
    log.info("Loading the DL model...")

    CONFIG_TYPE = config.global_settings['CONFIG_TYPE']
    MODEL_FILE = config.global_settings['MODEL_FILE']

    vmodel = DeepSpeakerModel()

    # renamed model file to model.h5 (was: ResCNN_triplet_training_checkpoint_265.h5)

    # continue to load local file
    # but the model is not changing.. do we need a special location?
    # we can continue to ship with the code !
    vmodel.m.load_weights(create_path(MODEL_FILE), by_name=True)

    return vmodel
#
# This loads the centroids file DB and handle the two cases: local, cloud CONFIG
#
def load_centroids():
    log.info("Loading the centroids DB...")

    CONFIG_TYPE = config.global_settings['CONFIG_TYPE']

    # with CONFIG_TYPE we manage the different storage in Cloud (Object storage)
    # and locally (on fs)
    if CONFIG_TYPE == "local":
        new_centroids = load_centroids_from_local()
    else:
        if CONFIG_TYPE == "cloud":
            new_centroids = load_centroids_from_oss()

    log.info("Number of distinct speakers: " + str(len(new_centroids)))

    return new_centroids

#
# swap centroid files
#
def swap_centroids_files():
    log.info("Swapping the centroids DB...")

    CONFIG_TYPE = config.global_settings['CONFIG_TYPE']

    if CONFIG_TYPE == "local":
        swap_centroids_files_local()
    else:
        if CONFIG_TYPE == "cloud":
            swap_centroids_files_oss()

#
# This handle the centroids file restore and handle the two cases: local, cloud CONFIG
#
def restore_centroids_from_bck():
    log.info("Restoring the centroids DB...")

    CONFIG_TYPE = config.global_settings['CONFIG_TYPE']

    # with CONFIG_TYPE we manage the different storage in Cloud (Object storage)
    # and locally (on fs)
    if CONFIG_TYPE == "local":
        restore_centroids_from_bck_local()
    else:
        if CONFIG_TYPE == "cloud":
            restore_centroids_from_bck_oss()

    return

# return the dictionary with all scores
# score is the distance between the current sound vector and the centroid
# current sound vector is in embedding
# list is limited to MAX_RESULTS
def compare_other_centroids(embedding, centroids):
    tmp_dict = {}

    for key in centroids.keys():
        dist = round(distance_cosine_similarity(embedding, centroids[key])[0], 3)
        tmp_dict[key] = dist

    # sort
    tmp_list = sorted(tmp_dict.items(), key=lambda x:x[1])
    # in tmp_list I have tuples like ('Lorenzo_DeMarchis', 0.278)

    # here I limit to MAX_RESULTS
    new_tmp_list = []

    for i, el in enumerate(tmp_list):
        if i < config.global_settings['MAX_RESULTS']:
            new_dict = {}
            # unpack the tuple
            new_dict['name'] = el[0]
            new_dict['result'] = el[1]
            new_tmp_list.append(new_dict)

    out_dict = {}
    out_dict["result"] = new_tmp_list

    return out_dict

def compute_distances(embedding, centroids):
    dict_dist = {}

    for key in centroids.keys():
        dist = round(distance_cosine_similarity(embedding, centroids[key])[0], 3)

        dict_dist[key] = dist

    # sort
    tmp_list = sorted(dict_dist.items(), key=lambda x:x[1])

    # here I limit to MAX_RESULTS
    new_tmp_list = []

    for i, el in enumerate(tmp_list):
        if i < config.global_settings['MAX_RESULTS']:
            new_tmp_list.append(el)

    out_dict = dict(new_tmp_list)

    return out_dict

# load the DL model
model = load_model()

# load the centroids file
# file must be modified every time a new speaker is added
#
centroids = load_centroids()

# create the app
app = FastAPI(title=config.global_settings['TITLE'], version=config.global_settings['VERSION'],
        description=config.global_settings['DESCRIPTION'])

#
# functions handling HTTP requests
#

#
# This is the function that handles the POST request for identification
# it expects a wav file in binary format as input
# and gives as output a JSON with pairs name:distance
# where distance is the distance from the given input and the centroid for name
#
@app.post("/identify", tags=["Identification"])
def identify(file: bytes = File(...)):

    # for timing the request
    tStart = time.time()

    log.info('Identify: Received a request')

    try:
        embedding = compute_embeddings(file, model)

        # compare with all centroids
        out_dict = compare_other_centroids(embedding, centroids)

        print_dict(out_dict)

        tEla = time.time() - tStart
        print()
        print('Elapsed time (sec.)', round(tEla, 3))

    except Exception as e:
        print('The exception is:', e)
        print("Input is not a valid audio file!")
        raise HTTPException(status_code=415, detail="Unsupported file provided.")

    return out_dict

#
# compare name with names of first NUM_CANDIDATES
# if names is in first NUM_CANDIDATES return OK
#
@app.post("/verify", tags=["Identification"])
def verify(name: str, file: bytes = File(...)):

    # for timing the request
    tStart = time.time()

    log.info('Verify: Received a request')

    final_dict_out = {}

    try:
        embedding = compute_embeddings(file, model)

        # compare with all centroids
        # out dict is already in iorder of increasing distance
        out_dict = compare_other_centroids(embedding, centroids)

        # compute the summary result
        final_dict_out["summary"] = "false"
        final_dict_out['result'] = out_dict

        list_pair = out_dict["result"]

        for i, pair in enumerate(list_pair):
            # consider only the first NUM_CANDIDATES
            if i < config.global_settings['NUM_CANDIDATES']:
                # compare ignoring case
                if pair["name"].upper() == name.upper():
                    final_dict_out["summary"] = "true"
                    break

        print_dict(final_dict_out)

        tEla = time.time() - tStart
        print()
        print('Elapsed time (sec.)', round(tEla, 3))

    except Exception as e:
        print('The exception is:', e)
        print("Input is not a valid audio file!")
        raise HTTPException(status_code=415, detail="Unsupported file provided.")

    return final_dict_out

# By using @app.get("/") you are allowing the GET method to work for the / endpoint.
@app.get("/", tags=["Operation"])
def home():
    return "Congratulations! Your API is working. Now head over to http://localhost:8888/docs."

#
# return the list of registered speakers' names
# the list can be sorted
#
@app.get("/list_speakers", tags=["Operation"])
def list_speakers(ordered: str = "false"):
    global centroids

    log.info('List speakers: Received a request')

    list_speakers = get_list_speakers_names(centroids, ordered)

    out_dict = {}
    out_dict['speakers'] = list_speakers

    print_dict(out_dict)

    return out_dict
#
# This function handles the request for adding a new speaker to the DB
#
@app.post("/add_speaker", tags=["Operation"])
def add_new_speaker(name: str, file: bytes = File(...)):
    global centroids

    log.info("Adding speaker: "  + name)

    # for timing the request
    tStart = time.time()

    try:
        # save in a wav file in the local dir
        save_wav(name, file)

        filename = create_path(name + ".wav")

        # create the new_centroids structure
        new_centroids = add_speaker(name, filename, centroids, model)

        # if CONFIG = cloud must copy new centroids to OSS
        if config.global_settings['CONFIG_TYPE'] == "cloud":
            log.info("Writing new centroid to oss")
            write_new_centroids_to_oss(new_centroids)
        else:
            # local
            log.info("Writing new centroid to local")
            write_new_centroids_to_local(new_centroids)

        # swap the files (handles the double config cloud or local)
        log.info("Swap centroids files")
        swap_centroids_files()

        # reload
        log.info("Reload centroids")
        centroids = load_centroids()

        out_dict = {}
        out_dict['result'] = "true"

        tEla = time.time() - tStart
        print()
        print('Elapsed time (sec.)', round(tEla, 3))

    except Exception as e:
        print('The exception is:', e)
        print("Input is not a valid!")
        raise HTTPException(status_code=415, detail="Unsupported request.")

    return out_dict
#
# delete speaker
#
@app.post("/delete_speaker", tags=["Operation"])
def delete_speaker(name: str):
    global centroids

    log.info("Delete a speaker from DB")

    # create the new_centroids without speaker = name
    # check if name is in speakers list
    list_speakers = get_list_speakers_names(centroids, ordered=False)

    if name in list_speakers:
        # Cancel, operate on a copy
        new_centroids = centroids.copy()

        # Remove the speaker from the data structure
        del new_centroids[name]

        # now save
        if config.global_settings['CONFIG_TYPE'] == "cloud":
            log.info("Writing new centroid to oss")
            write_new_centroids_to_oss(new_centroids)
        else:
            # local
            log.info("Writing new centroid to local")
            write_new_centroids_to_local(new_centroids)

        # swap
        log.info("Swap centroids files")
        swap_centroids_files()

        # after creating the new centroids file, reload it
        centroids = load_centroids()
    else:
        # do nothing
        log.info(name + " not in list speakers")

    dict_out = {}
    dict_out["result"] = "true"

    return dict_out
#
# force the reload of the centroids file
#
@app.get("/reload", tags=["Operation"])
def reload():
    global centroids

    centroids = load_centroids()

    out_dict = {}
    out_dict['result'] = "true"

    return out_dict
#
# restore of the centroids file
#
@app.get("/restore_centroids", tags=["Operation"])
def restore_centroids():
    global centroids

    print("Restore centroids")
    restore_centroids_from_bck()

    centroids = load_centroids()

    out_dict = {}
    out_dict['result'] = "true"

    return out_dict

#
# return the list of registered speakers' names reading the file
# the list can be sorted
#
@app.get("/list_speakers_from_newfile", tags=["Operation"])
def list_speakers_from_newfile(ordered: str = "false"):

    new_centroids = load_centroids_newfile()

    list_speakers = []

    for key in new_centroids.keys():
        list_speakers.append(key)

    if ordered == "true":
        list_speakers = sorted(list_speakers)

    out_dict = {}
    out_dict['speakers'] = list_speakers

    print_dict(out_dict)

    return out_dict

#
# Main
#
if __name__ == '__main__':
    # set IP on which is listening, port
    # listen on all IP
    uvicorn.run(app, host=config.global_settings['IP'], port=config.global_settings['PORT'])


# from crypt import methods
from crypt import methods
from tkinter.messagebox import NO
from flask import Blueprint, request

from app.models import User, Channel, ChannelMessage, db, ChannelMember
from flask_login import current_user
from app.aws import upload_file_to_s3, allowed_file, get_unique_filename

channel_routes = Blueprint('channels', __name__, url_prefix='channels')

@channel_routes.route('/<int:channel_id>', methods=['GET', 'PUT', 'DELETE'])
def get_one_put_delete_channel(channel_id):
    channel = Channel.query.get(channel_id)
    if request.method == 'GET':
        return channel.to_dict()

    if request.method == 'PUT':
        name = request.json['name']
        diss_cord_bot_message = ChannelMessage.query.filter(ChannelMessage.channel_id == channel_id).filter(ChannelMessage.sender_id == 1).first()
        diss_cord_bot_message.content = f'Welcome to {channel.server.name}\'s Channel {name}'
        db.session.commit()

        channel.name = request.json['name']
        db.session.commit()
        return channel.to_dict()

    if request.method == 'DELETE':
        db.session.delete(channel)
        db.session.commit()
        return {'channelId': channel.id}

@channel_routes.route('/<int:channel_id>/messages', methods=['POST'])
def post_channel_message(channel_id):
    url = None
    if "image" in request.files:
        image = request.files["image"]
        if not allowed_file(image.filename):
            return {"errors": "file type not permitted"}, 400
        image.filename = get_unique_filename(image.filename)
        upload = upload_file_to_s3(image)
        url = upload["url"]

    new_message = ChannelMessage(
        channel_id=channel_id,
        sender_id = current_user.id,
        content = request.form['content'],
        picture = url

    )
    db.session.add(new_message)
    db.session.commit()
    return new_message.to_dict()

@channel_routes.route('/<int:channel_id>/members', methods=['GET', 'POST'])
def get_all_or_post_to_channel_members(channel_id):

    server_general_channel = Channel.query.get(channel_id)

    print('after first query',server_general_channel.to_dict())

    if request.method == 'GET':
        print('before second querrrrrry')
        channel_members= ChannelMember.query.filter(ChannelMember.channel_id == channel_id).all()

        return {'channelMembers': {member.id:member.to_dict() for member in channel_members}}
    if request.method == 'POST':
        data = request.json
        joining_member = User.query.get(data['userId'])
        data = request.json
        member = ChannelMember(channel_id=channel_id, user_id=data['userId'])
        db.session.add(member)

        first_message = ChannelMessage(channel_id=channel_id, sender_id=1, content=f'ðŸ‘‹{joining_member.username} has slid into the channel')
        db.session.add(first_message)
        db.session.commit()
        channel = Channel.query.get(channel_id)

        return {'member':member.to_dict(), 'channel': channel.to_dict()}

@channel_routes.route('/<int:channel_id>/members/<int:member_id>', methods=['DELETE'])
def delete_server_member(channel_id, member_id):
    channel = Channel.query.get(channel_id)
    member = ChannelMember.query.get(member_id)
    db.session.delete(member)
    leaving_message = ChannelMessage(channel_id=channel_id, sender_id=1, content=f'ðŸ˜ {member.member.username} has left the channel')
    db.session.add(leaving_message)
    db.session.commit()
    return {'memberId': member_id, 'channelId': channel.id }


from requests_html import HTMLSession

session = HTMLSession()
url='https://time.com/'

r = session.get(url)

r.html.render(sleep=1,scrolldown=4)

top_stories = r.html.find('div',class_='latest-stories' )

print(top_stories)


from pyspark import SparkContext

logFile = r'C:\spark\spark-2.2.0-bin-hadoop2.7\README.md'
logdir = r'C:\spark\spark-2.2.0-bin-hadoop2.7\*.txt'
logdir1 = r'C:\spark\spark-2.2.0-bin-hadoop2.7'
sc = SparkContext(master="local[2]",appName="Simple App")

rdd = sc.parallelize([('a',7),('a',2),('b',2)])
rdd3 = sc.parallelize(range(100))
data = [1, 2, 3, 4, 5]
distData = sc.parallelize(data,)
a = distData.reduce(lambda a, b: a + b)

print(a)

# print(a)
#

def map_function(line):
    return len(line.split(' '))
logData1 = sc.textFile(logFile).cache()
logData = sc.textFile(logFile)
logData2 = sc.textFile(logdir) # đọc nhiều file thì sẽ map các file lại thành 1 ( map các line lại với nhau)
logData3 = sc.wholeTextFiles(logdir1) # đọc nhiều file thì sẽ map các file lại thành 1 ( map các line lại với nhau)

numAs = logData.filter(lambda line: 'a' in line).count()
numbBs = logData.filter(lambda line: 'b' in line).count()
a = logData.map(lambda x: len(x.split())).reduce(lambda a,b: a+b)
word_list = logData.flatMap(lambda x: x.split()) # tạo ra 1 RDD chứa data là các word, trong file
word_list1 = logData.map(lambda x: x.split()) # tạo ra 1 RDD chứa data là các word, trong file

map_for_reduce = word_list.map(lambda x: (x, 1))
word_count = map_for_reduce.reduceByKey(lambda a, b: a + b)
word_count = word_list.map(lambda x: (x,1)).reduceByKey(lambda a,b: a+b)
word_count_tuple = map_for_reduce.reduce(lambda a, b: a + b)
map_for_reduce.persist() # save map_for_reduce after first time computed, later use map_for_reduce don't need compute again.

map_1 = logData.map(map_function).reduce(lambda a,b: a if a >b else b)

counter = 0
rdd = sc.parallelize(data)

# Wrong: Don't do this!!
def increment_counter(x):
    global counter
    counter += x
rdd.foreach(increment_counter)

print("Counter value: ", counter)

x = logData.filter(lambda x: 'a' in x)

sc.stop()

rdd3.groupBy(lambda x: x % 2).mapValues(list).collect()


import uuid
import pytest
from result import Ok

from core.festival.application.query.get_beer_by_id_query import GetBeerByIdQuery
from core.festival.application.query.get_beer_by_id_query_handler import GetBeerByIdQueryHandler
from core.festival.infrastructure.services.inmemory_beer_repository import InMemoryBeerRepository
from core.festival.tests.beer_builder import BeerBuilder

@pytest.mark.asyncio
async def test_get_beer_by_id_success() -> None:
    # Arrange
    beer = BeerBuilder().build()
    beer_repository = InMemoryBeerRepository(beers=[beer])
    handler = GetBeerByIdQueryHandler(beer_repository)
    query = GetBeerByIdQuery(id=beer.beer_id.value)

    # Act
    result = await handler.handle(query)

    # Assert
    assert isinstance(result, Ok)
    assert result.ok() == beer

@pytest.mark.asyncio
async def test_get_beer_by_id_not_found() -> None:
    # Arrange
    beer_repository = InMemoryBeerRepository(beers=[])
    handler = GetBeerByIdQueryHandler(beer_repository)
    query = GetBeerByIdQuery(id=uuid.uuid4())

    # Act
    result = await handler.handle(query)

    # Assert
    assert isinstance(result, Ok)
    assert result.ok() == None


import cv2
import numpy as np
import matplotlib.pyplot as plt

# load and convert to binary
img = cv2.imread('./images/image.jpg', 0)
_, binary = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# disk kernel
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))

# erosion
eroded = cv2.erode(binary, kernel)

# plot
fig, ax = plt.subplots(1, 3, figsize=(10, 10))
ax[0].imshow(img, cmap='gray')
ax[0].set_title('Original')
ax[1].imshow(binary, cmap='gray')
ax[1].set_title('Binary')
ax[2].imshow(eroded, cmap='gray')
ax[2].set_title('Eroded')
plt.show()


from pyjamas.ui import RootPanel, HTML, MenuBar, MenuItem, DockPanel, HorizontalPanel, TabPanel, SimplePanel, PopupPanel, FlowPanel, FormPanel, ScrollPanel, Label, HasAlignment, VerticalPanel, TextArea, TextBox, DialogBox, Frame, NamedFrame, Image, Button, DialogBox, CheckBox, RadioButton, HTMLPanel, MouseListener, KeyboardListener, Hyperlink, Tree, TreeItem, FileUpload
from pyjamas.Timer import Timer
from Tooltip import TooltipListener
from pyjamas import Window, History, DOM
from pyjamas.JSONService import JSONProxy
from ContextMenuPopupPanel import ContextMenuPopupPanel

class DataService(JSONProxy):
  def __init__(self):
    JSONProxy.__init__(self, "/projects/services/", ["get_username", "get_meetinginfo","send_chatmessage","receive_chatmessage","send_flash","receive_flash","send_editor","receive_editor","user_quit", "driver_status","switch_driver","new_file","new_directory","open_file","save_file","get_file_tree","delete_file","sync_all"])

class Basic:
  def onModuleLoad(self):
    self.remote = DataService()
    self.initEditor = False
    # this tells us whether or not we are trying to quit...
    self.quitting = False
    self.switching = False

    # file info
    self.current_open = None
    self.modified = False
    self.originalContents = ""

    # Figure out session info -- am i driver or passenger, etc.
    self.remote.get_meetinginfo(self)

    # building the menu bar
    self.active_menu = Label("")
    self.info = Button("Info", getattr(self, "onInfoClick"))
    self.file_list = []
    self.remote.get_file_tree(self) # will need to change rd to actual root directory.

    self.files = Button("Files", getattr(self, "onFilesClick"))
    #self.FileContext = SimplePanel("La di da")
    self.mode = Button("Mode", getattr(self, "onModeClick"))
    self.audio = Button("Audio", getattr(self, "onAudioClick"))
    self.flash = Button("Start Flash", getattr(self, "toggleFlash"))
    self.quit = Button("Quit", getattr(self, "onQuitClick"))
    self.menu_body = SimplePanel()
    self.menu_contents = HTMLPanel("")
    self.menu_body.setWidget(self.menu_contents)
    self.active_flash = Label("Off")
    self.color = Label("white")
    # put them together
    self.head = HorizontalPanel()
    self.head.add(Label("|"))
    self.head.add(self.info)
    self.head.add(self.files)
    self.head.add(self.mode)
    self.head.add(self.audio)
    self.head.add(self.flash)
    self.head.add(self.quit)
    self.head.add(Label("|"))
    self.head.add(self.menu_body)

    # the left side
    # editor
    # The editorID is the id of the actual editor text area
    # the functionID is the id of the setupeditarea and set_listener/set_editable() functions
    # the synchID is the id of the interval command for setting synchEditors/synchListeners based on
    #     whether driver or passenger.
    ### For now let's try hard-coding these
    self.editorID = "MYeditorID"
    self.editorHTMLID = "MYeditorHTMLID"
    self.functionID = "MYfunctionID"
    self.synchID = "MYsynchID"
    self.chatID = "MYchatID"
    self.intervalID = "MYintervalID"
    self.editorsynchID = "MYeditorsynchID"
    self.listensynchID = "MYlistensynchID"
    self.termfunctionID = "MYtermfunctionID"

    # This is where we store the stuff going back and forth from the editor in driver mode.
    # listenID no longer exists, fix after demo.
    self.functionHTML = HTML("")
    self.editorHTML = HTML(" ")
    self.editorHTML.setVisible(False)
    self.editorHTML.setID(self.editorHTMLID)

    # this gets the contents of the editor into the div area so we can send it
    self.driversynch = """
    """

    #

    self.passengersynch = """
    """

    initialcontent = """ """

    self.editor = HTMLPanel("<div id='"+self.synchID+"'

"+ "<textarea id='"+self.editorID+"' style='height: 575px; width: 100%;'></textarea>

")

    self.editorTextArea = TextArea()
    self.editorTextArea.setID(self.editorID)
    self.editor.add(self.editorTextArea, self.editorID)
    self.editor.add(self.functionHTML, self.functionID)
    self.editor.add(self.editorHTML, self.editorHTMLID)

    self.editor.add(HTML(initialcontent), self.synchID)
    self.editor.setWidth("100%")
    self.editor.setHeight("100%")

    #innerhtml = "

";
    #DOM.setInnerHTML(DOM.getElementById(self.editorHTMLID), innerhtml)#tpl[1]) was innerText

    # the right side
    vp = VerticalPanel()
    vp.setBorderWidth(1)
    # the console
    self.term = HTMLPanel("

")  #Frame("http://127.0.0.1:8023/")
    self.term.setWidth("100%")
    self.term.setHeight("390px")
    console = SimplePanel()
    console.add(self.term)
    console.setWidth("400px")
    console.setHeight("100%")
    # not so hacky -- indeed, pretty decent little text chat
    self.text_area = ScrollPanel()
    self.text_area.setStyleName("text-area")
    self.text = HTML("(There is a 600 character limit on messages)")
    self.text_area.setWidget(self.text)
    self.text_area.setSize("487px", "151px")
    self.text_box = TextBox()
    self.text_box.setVisibleLength("58")
    self.text_box.setMaxLength("600")
    self.text_box.setID(self.chatID)
    self.text_box.addKeyboardListener(self)
    text_send = Button("Send", getattr(self, "onTextSend"))
    text_entry = HorizontalPanel()
    text_entry.add(self.text_box)
    text_entry.add(text_send)
    text_entry.setWidth("340px")
    real_chat = VerticalPanel()
    #real_chat.add(self.chat_transcript)
    real_chat.add(self.text_area)
    self.text_area.setScrollPosition(999999)
    real_chat.add(text_entry)
    real_chat.setStyleName("whitebg")

    vp.add(console) # console and chat added to vertical panel
    vp.add(real_chat)
    vp.setWidth("100%")
    vp.setHeight("100%")
    vp.setCellHeight(console, "50%")
    vp.setCellHeight(real_chat, "50%")

    # putting the left and right sides together
    hp = HorizontalPanel()
    hp.setBorderWidth(1)
    hp.setHorizontalAlignment(HasAlignment.ALIGN_CENTER)
    hp.setVerticalAlignment(HasAlignment.ALIGN_MIDDLE)
    hp.add(self.editor)
    hp.add(vp)
    hp.setCellWidth(self.editor, "50%")
    hp.setCellWidth(vp, "50%")
    hp.setCellVerticalAlignment(console, HasAlignment.ALIGN_TOP)
    hp.setWidth("100%")
    hp.setHeight("100%")

    # footer label
    self.footer = Label("A TeamCEG production")
    self.footer.setStyleName("footer")

    # putting it all together
    self.panel = DockPanel()
    self.panel.add(self.head, DockPanel.NORTH)
    self.panel.add(hp, DockPanel.CENTER)
    self.panel.add(self.footer, DockPanel.SOUTH)
    self.panel.setCellWidth(hp, "100%")
    self.panel.setCellHeight(hp, "100%")
    self.panel.setCellWidth(self.head, "100%")
    self.panel.setWidth("995px")  # out of 1024
    self.panel.setHeight("400px")  # out of 768

    RootPanel().add(self.panel)

    # start the timer for updates from server
    self.currpass = Label("No Partner logged in")
    self.onTimer()

  def onRemoteResponse(self, response, request_info):
    if request_info.method == 'get_username':
      if (len(response[3]) < 1):  # if there is no passenger
        for tpl in response:
          self.driver.setText("%s" % tpl[1])
      else:
        for tpl in response:
          self.driver.setText("%s" % tpl[1])
          self.passenger.setText("%s" % tpl[3])
    elif request_info.method == 'get_meetinginfo':
      haspassenger = False
      previousconsoleID = self.consoleID
      for tpl in response:
        if str(tpl[0]) == 'isdriver':
          if str(tpl[1]) == 'True':
            self.isdriver = True
            if self.initEditor == False:
              self.editor.add(HTML(self.driversynch), self.synchID)
              self.initEditor = True
          else:
            self.isdriver = False
            self.editor.add(HTML(self.passengersynch), self.synchID)
        if str(tpl[0]) == 'project':
          self.project = Label("%s" % tpl[1])
        if str(tpl[0]) == 'driver':
          self.driver = Label("%s" % tpl[1])
        if str(tpl[0]) == 'drivername':
          self.drivername = Label("%s" % tpl[1])
        if str(tpl[0]) == 'new_sid':
          self.consoleID = str(tpl[1])
        if str(tpl[0]) == 'new_ssh':
          self.ssh = str(tpl[1])
        if str(tpl[0]) == 'new_user':
          self.usr = str(tpl[1])
        if str(tpl[0]) == 'new_key':
          self.key = str(tpl[1])
        if str(tpl[0]) == 'passenger':
          self.passenger = Label("%s" % tpl[1])
          haspassenger = True
        if str(tpl[0]) == 'passengername':
          self.passengername = Label("%s" % tpl[1])
      if haspassenger == False:
        self.passenger = Label("")
        self.passengername = Label("")
        self.passenger.setText("No Partner logged in")  # so passenger is not undefined,
        self.passengername.setText("No Partner logged in")
      if str(self.consoleID) != str(previousconsoleID):
        #window.alert("Changing console in get_meetinginfo")
        self.term.add(HTML(""), self.termfunctionID)

    elif request_info.method == 'send_chatmessage':
      for tpl in response:
        #alert(str(tpl[1]))
        self.text.setHTML(self.text.getHTML() + "
" + str(tpl[1]))
        self.text_area.setWidget(self.text)
        self.text_area.setScrollPosition(999999)
    elif request_info.method == 'receive_chatmessage':
      for tpl in response:
        #alert(str(tpl[1]))
        self.text.setHTML(self.text.getHTML() + "
" + str(tpl[1]))
        self.text_area.setWidget(self.text)
        self.text_area.setScrollPosition(999999)
    elif request_info.method == 'send_flash':
      pass
    elif request_info.method == 'receive_flash':
      for tpl in response:
        if str(tpl[1]) == "off":
          if self.Flash:
            self.toggleFlash()
        else:
          if not self.Flash:
            self.toggleFlash()
    elif request_info.method == 'send_editor':
      #window.alert("sent editor")
      pass
    elif request_info.method == 'receive_editor':
      # check to see if maybe there is an error here because of empty string?
      for tpl in response:
        #alert(str(tpl[1]))
        content = tpl[1]
        innerhtml = "
" + content+"
";
        DOM.setInnerHTML(DOM.getElementById(self.editorHTMLID), innerhtml)#tpl[1]) was innerText
        #self.editorHTML.setVisible(False)

    elif request_info.method == 'driver_status':
      if self.switching == False:
        self.switching = True
        for tpl in response:
          if (str(tpl[0])) == 'new_sid':
            self.consoleID = str(tpl[1])
          if (str(tpl[0])) == 'new_ssh':
            self.ssh = str(tpl[1])
          if (str(tpl[0])) == 'new_user':
            self.usr = str(tpl[1])
          if (str(tpl[0])) == 'new_key':
            self.key = str(tpl[1])
          if (str(tpl[0])) == 'isdriver':
            if str(tpl[1]) == 'False':
              if self.isdriver == True:
                self.isdriver = False
                self.editor.add(HTML(self.passengersynch), self.synchID)
                #window.alert("Doing a console set from isdriver False in driverstatus")
                self.term.add(HTML(""), self.termfunctionID)
            if str(tpl[1]) == 'True':
              if self.isdriver == False:
                self.isdriver = True
                self.editor.add(HTML(self.driversynch), self.synchID)
                #new_ssh,new_user,new_key,
                #window.alert("Doing a console set from isdriver true in driverstatus")
                self.term.add(HTML(""), self.termfunctionID)
          self.switching = False

    elif request_info.method == 'switch_driver':
      for tpl in response:
        if (str(tpl[0])) == 'new_sid':
            self.consoleID = str(tpl[1])
        if (str(tpl[0])) == 'new_ssh':
          self.ssh = str(tpl[1])
        if (str(tpl[0])) == 'new_user':
          self.usr = str(tpl[1])
        if (str(tpl[0])) == 'new_key':
          self.key = str(tpl[1])
        if (str(tpl[0])) == 'isdriver':
          if (str(tpl[1])) == "True":
            if self.isdriver == False:
              self.isdriver = True
              self.editor.add(HTML(self.driversynch), self.synchID)
              self.switching = False
              #window.alert("console set from switch-driver isdriver true")
              self.term.add(HTML(""), self.termfunctionID)
              # need to hold off until we know the id self.term.add(HTML(""),"MYtermfunctionID")
          elif str(tpl[1]) == "False":
            if self.isdriver == True:
              self.isdriver = False
              self.editor.add(HTML(self.passengersynch), self.synchID)
              self.switching = False
              #window.alert("console set from switch-driver isdriver FALSE")
              self.term.add(HTML(""), self.termfunctionID)
              # self.term.add(HTML(""),"MYtermfunctionID")

    elif request_info.method == 'new_file':
      for tpl in response:
        window.alert(str(tpl[1]))
    elif request_info.method == 'new_directory':
      for tpl in response:
        window.alert(str(tpl[1]))
    elif request_info.method == 'open_file':
      for tpl in response:
        #window.alert(str(tpl[1]))
        # todo: SAVE whatever is currently in the editor
        # add response text to editor
        contents = str(tpl[1])
        contents = contents.replace('\n','\\n')
        self.editor.add(HTML(""), self.functionID)
        self.originalContents = str(tpl[1])
        self.modified = False
    elif request_info.method == 'save_file':
      self.modified = False
      for tpl in response:
        window.alert(str(tpl[1]))

    elif request_info.method == 'delete_file':
      for tpl in response:
        window.alert(str(tpl[1]))
    elif request_info.method == 'get_file_tree':
      self.file_list = []
      for tpl in response:
        #window.alert(str(tpl[0])+ " " + str(tpl[1]) + " " + str(tpl[2]))
        self.file_list.append(tpl)

    elif request_info.method == 'user_quit':
      self.location = Window.getLocation()
      self.location.setHref("http://teamceg.princeton.edu/")
    elif request_info.method == 'sync_all':
      pass
    else:
      console.error("Error in onRemoteResponse function in Basic.py")

  def onRemoteError(self, response, request_info):
    pass

  def onInfoClick(self):

    if self.active_menu.getText() == "Info":
      self.active_menu.setText("")
      self.menu_body.setWidget(self.menu_contents)
    else:
      self.active_menu.setText("Info")
      infomsg = Label("Driver: %s, Passenger: %s" % (self.driver.getText(), self.passenger.getText()))
      infomsg.setStyleName("not-button")
      self.menu_body.setWidget(infomsg)

  def onFilesClick(self):
    if self.active_menu.getText() == "Files":
      self.active_menu.setText("")
      self.menu_body.setWidget(self.menu_contents)
    else:
      self.active_menu.setText("Files")
      filepanel = HorizontalPanel()
      filetreebutton = Button("File Tree", getattr(self, "onFileTreeOpenClick"))
      filesavebutton = Button("Save", getattr(self,"onFileSave"))
      filetreebutton.setStyleName("supp-button")
      filesavebutton.setStyleName("supp-button")
      filepanel.add(filetreebutton)
      filepanel.add(filesavebutton)
      self.menu_body.setWidget(filepanel)

  def onFileSave(self):
    # get the text from the editor and send a save command to the server.
    if self.isdriver == True:
      content = DOM.getInnerText(DOM.getElementById(self.editorHTMLID))
      self.remote.save_file(str(self.current_open[2]),content, self)
      self.originalContents = content

  def onFileUploadOpenClick(self):
    self.uploadform = FormPanel()
    self.uploadform.setEncoding(FormPanel.ENCODING_MULTIPART)
    self.uploadform.setMethod(FormPanel.METHOD_POST)
    self.uploadform.setAction("http://www.google.com")
    self.uploadform.setTarget("results")
    upload_hp = HorizontalPanel()
    upload_hp.setSpacing(7)
    upload_hp.add(Label("Upload file:"))
    self.fileup = FileUpload()
    self.fileup.setName("file")
    upload_hp.add(self.fileup)
    fileuploadsubmitbutt = Button("Submit", getattr(self, "onFileUploadSubmitClick"))
    fileuploadclosebutt = Button("Cancel", getattr(self, "onFileUploadCloseClick"))
    uploadbutt_hp = HorizontalPanel()
    uploadbutt_hp.setSpacing(7)
    uploadbutt_hp.add(fileuploadsubmitbutt)
    uploadbutt_hp.add(fileuploadclosebutt)
    upload_vp = VerticalPanel()
    upload_vp.setSpacing(4)
    upload_vp.add(upload_hp)
    results = NamedFrame("results")
    upload_vp.add(results)
    upload_vp.add(uploadbutt_hp)
    upload_vp.setCellHorizontalAlignment(uploadbutt_hp, HasAlignment.ALIGN_CENTER)
    self.uploadform.add(upload_vp)
    self.upload_box = DialogBox()
    self.upload_box.setHTML("File Upload")
    self.upload_box.setWidget(self.uploadform)
    self.upload_box.setPopupPosition(350, 150)
    self.upload_box.show()
  def onFileUploadSubmitClick(self):
    self.uploadform.submit()
    self.upload_box.hide()
  def onFileUploadCloseClick(self):
    self.upload_box.hide()
  def onFileDirOpenClick(self):
    pass ###
  def onFileTreeOpenClick(self):
    filetree = Tree()
    filetree.addTreeListener(self)
    i = 0
    ## Values will be full paths of the files, so we can send them directly
    ## Names will be filename within the directory or the directory name
    self.remote.get_file_tree(self)
    while (i < len(self.file_list)) and (self.file_list[i][0][0] == "1"):
      s1 = self.createTreeItem(str(self.file_list[i][0][1:]), value=self.file_list[i][2])#"root/")
      i = i + 1
      while (i < len(self.file_list)) and (self.file_list[i][0][0] == "2"):
        s2 = self.createTreeItem(str(self.file_list[i][0][1:]), value=self.file_list[i][2])
        s1.addItem(s2)
        s1.setState(True, fireEvents=False)
        i = i + 1
        while (i < len(self.file_list)) and (self.file_list[i][0][0] == "3"):
          s3 = self.createTreeItem(str(self.file_list[i][0][1:]), value=self.file_list[i][2])
          s2.addItem(s3)
          s2.setState(False, fireEvents=False)
          i = i + 1
          while (i < len(self.file_list)) and (self.file_list[i][0][0] == "4"):
            s4 = self.createTreeItem(str(self.file_list[i][0][1:]), value=self.file_list[i][2])
            s3.addItem(s4)
            s3.setState(False, fireEvents=False)
            i = i + 1
            while (i < len(self.file_list)) and (self.file_list[i][0][0] == "5"):
              s5 = self.createTreeItem(str(self.file_list[i][0][1:]), value=self.file_list[i][2])
              s4.addItem(s5)
              s4.setState(False, fireEvents=False)
              i = i + 1
              while (i < len(self.file_list)) and (self.file_list[i][0][0] == "6"):
                s6 = self.createTreeItem(str(self.file_list[i][0][1:]), value=self.file_list[i][2])
                s5.addItem(s5)
                s5.setState(False, fireEvents=False)
                i = i + 1
                while (i < len(self.file_list)) and (self.file_list[i][0][0] == "7"):
                  s7 = self.createTreeItem(str(self.file_list[i][0][1:]), value=self.file_list[i][2])
                  s6.addItem(s5)
                  s6.setState(False, fireEvents=False)
                  i = i + 1
                  while (i < len(self.file_list)) and (self.file_list[i][0][0] == "8"):
                    s8 = self.createTreeItem(str(self.file_list[i][0][1:]), value=self.file_list[i][2])
                    s7.addItem(s5)
                    s7.setState(False, fireEvents=False)
                    i = i + 1
                    while (i < len(self.file_list)) and (self.file_list[i][0][0] == "9"):
                      s9 = self.createTreeItem(str(self.file_list[i][0][1:]), value=self.file_list[i][2])
                      s8.addItem(s5)
                      s8.setState(False, fireEvents=False)
                      i = i + 1
      #  s1.setState(True, fireEvents=False)
      filetree.addItem(s1)
    filetreepanel = VerticalPanel()
    filetreepanel.setSpacing(7)
    filetreepanel.setCellHorizontalAlignment(filetree, HasAlignment.ALIGN_LEFT)
    filetreepanel.add(filetree)
    filetreebutt = Button("Close", getattr(self, "onFileTreeCloseClick"))
    filetreepanel.add(filetreebutt)
    filetreepanel.setCellHorizontalAlignment(filetreebutt, HasAlignment.ALIGN_CENTER)
    filetreepanel.setWidth("400px")
    self.file_box = DialogBox()
    if self.current_open != None:
      self.file_box.setHTML("File Navigation Currently Editing: %s" % str(self.current_open[2]))
    else:
      self.file_box.setHTML("File Navigation")
    self.file_box.setWidget(filetreepanel)
    self.file_box.setPopupPosition(350, 200)
    self.file_box.show()
  def createTreeItem(self, label, value=None):
    item = TreeItem(label)
    DOM.setStyleAttribute(item.getElement(), "cursor", "pointer")
    #Will not work don't bother ##item.setContextMenu(self) # this needs latest version of pjs
    if value != None:
      item.setUserObject(value)
    return item
  def onTreeItemSelected(self, item):
    acted = False
    value = item.getUserObject()
    # prevent non-driver from modifying file tree structure
    if self.isdriver == False:
      return
    # check if the file currently opened has been modified
    currentcontent = DOM.getInnerText(DOM.getElementById(self.editorHTMLID))

    if str(currentcontent) != self.originalContents:
      if self.originalContents != None:
        self.modified = True

    # if it is a file -> open it.
    for thing in self.file_list:
      if str(thing[2]) == str(value):
        if str(thing[1])=="file":
          # Is there currently a file open?
          if self.current_open != None:
            if self.modified == True:
              # force the user to save or discard
              self.nextfile = thing
              guts = VerticalPanel()
              guts.setSpacing(4)
              guts.add(HTML('Unsaved changes were detected in an open file. Would you like to save your changes?'))
              gutshp = HorizontalPanel()
              gutshp.setSpacing(7)
              gutshp.add(Button("Save", getattr(self, "onDialogSave")))
              gutshp.add(Button("Discard", getattr(self, "onDialogDiscard")))
              guts.add(gutshp)
              guts.setCellHorizontalAlignment(gutshp, HasAlignment.ALIGN_CENTER)
              self.savediscard_box = DialogBox()
              self.savediscard_box.setHTML("Warning: Unsaved Changes")
              self.savediscard_box.setWidget(guts)
              self.savediscard_box.setPopupPosition(200, 200)
              self.savediscard_box.show()
              acted = True
            else:
              self.remote.open_file(str(value),self)
              acted = True
              self.modified = False
              self.current_open = thing
          else:
            self.remote.open_file(str(value),self)
            acted = True
            self.modified = False
            self.current_open = thing
    # if it is a directory -> make a popup to add/delete files dirs
    if acted == False:
      #window.alert("Will display a dialog window to manage directory: " + str(value))
      self.current_directory = str(value) + "/"
      contents = VerticalPanel()
      contents.setSpacing(4)
      contents.add(HTML('Add or delete files and directories.'))
      contentshp = HorizontalPanel()
      contentshp.setSpacing(7)
      contentshp.add(Button("Add",getattr(self,"onAddDialog")))
      contentshp.add(Button("Delete",getattr(self,"onDeleteDialog")))
      contentshp.add(Button("Cancel",getattr(self,"onCancelManageDialog")))
      contents.add(contentshp)
      contents.setCellHorizontalAlignment(contentshp, HasAlignment.ALIGN_CENTER)
      self.manage_directory_box = DialogBox()
      self.manage_directory_box.setHTML("Manage Directory")
      self.manage_directory_box.setWidget(contents)
      self.manage_directory_box.setPopupPosition(200,200)
      self.manage_directory_box.show()

  def onTreeItemStateChanged(self, item):
    pass
  def onFileTreeCloseClick(self):
    self.file_box.hide()

  def onAddDialog(self):
    contents = VerticalPanel()
    contents.setSpacing(4)
    contents.add(HTML('Add files and directories.'))
    contentshpfd = HorizontalPanel()
    self.NewDir = RadioButton("group1","directory")
    self.NewFile = RadioButton("group1","file")
    self.NewFile.setChecked(True)
    contentshpfd.add(self.NewDir)
    contentshpfd.add(self.NewFile)

    contentshpn = HorizontalPanel()
    contentshpn.setSpacing(7)
    self.NewFileName = TextBox()
    self.NewFileName.setID(self.chatID) # This should protect it from ajaxterm stealing...
    contentshpn.add(self.NewFileName)
    contentshp = HorizontalPanel()
    contentshp.setSpacing(7)
    contentshp.add(Button("Add",getattr(self,"onAddOK")))
    contentshp.add(Button("Cancel",getattr(self,"onCancelAdd")))
    contents.add(contentshpfd)
    contents.add(contentshpn)
    contents.add(contentshp)
    contents.setCellHorizontalAlignment(contentshp, HasAlignment.ALIGN_CENTER)
    self.manage_add_box = DialogBox()
    self.manage_add_box.setHTML("Add")
    self.manage_add_box.setWidget(contents)
    self.manage_add_box.setPopupPosition(200,200)

    self.manage_add_box.show()
    # hide the manage directory box, and the file tree -- it's distracting
    self.manage_directory_box.hide()
    self.file_box.hide()

  def onAddOK(self):
    newfile = self.current_directory + self.NewFileName.getText()
    newfile = newfile.lstrip("/")
    if self.NewDir.isChecked():
      self.remote.new_directory(newfile,self)
      self.remote.get_file_tree(self)
    else:
      self.remote.new_file(newfile,self)
      self.remote.get_file_tree(self)
    self.manage_add_box.hide()

  def onCancelAdd(self):
    self.manage_add_box.hide()

  def onDeleteDialog(self):
    contents = VerticalPanel()
    contents.setSpacing(4)
    contents.add(HTML('Delete files and directories.'))
    contentshpfd = HorizontalPanel()
    self.DelDir = RadioButton("group2","whole directory")
    self.DelFile = RadioButton("group2","files")
    self.DelFile.setChecked(True)
    self.DelFile.addClickListener(getattr(self,"onFileClick"))
    self.DelDir.addClickListener(getattr(self,"onDirClick"))
    contentshpfd.add(self.DelDir)
    contentshpfd.add(self.DelFile)
    contentshpn = VerticalPanel()
    contentshpn.setSpacing(7)
    self.FilesToDelete = []
    # find the files in this directory
    level = "0"
    for i in range(0,len(self.file_list)):
      if str(self.file_list[i][2]) == str(self.current_directory)[:len(str(self.current_directory))-1]:
        level = str(int(self.file_list[i][0][0]) + 1)
        start = i
    for i in range(start+1, len(self.file_list)):
      if self.file_list[i][0][0] == level:
        self.FilesToDelete.append(CheckBox(str(self.file_list[i][2])))
      else:
        level = "0"

    for i in range(0,len(self.FilesToDelete)):
      contentshpn.add(self.FilesToDelete[i])
    contentshp = HorizontalPanel()
    contentshp.setSpacing(7)
    contentshp.add(Button("Delete",getattr(self,"onDelOK")))
    contentshp.add(Button("Cancel",getattr(self,"onCancelDel")))
    contents.add(contentshpfd)
    contents.add(contentshpn)
    contents.add(contentshp)
    contents.setCellHorizontalAlignment(contentshp, HasAlignment.ALIGN_CENTER)
    self.manage_del_box = DialogBox()
    self.manage_del_box.setHTML("Delete")
    self.manage_del_box.setWidget(contents)
    self.manage_del_box.setPopupPosition(200,200)

    self.manage_del_box.show()
    # hide the manage directory box, and the file tree -- it's distracting
    self.manage_directory_box.hide()
    self.file_box.hide()

  def onFileClick(self):
    for i in range(0, len(self.FilesToDelete)):
      self.FilesToDelete[i].setEnabled(True)

  def onDirClick(self):
    for i in range(0, len(self.FilesToDelete)):
      self.FilesToDelete[i].setChecked(True)
      self.FilesToDelete[i].setEnabled(False)

  def onDelOK(self):
    if self.DelDir.isChecked():
      dir = self.current_directory[:len(self.current_directory)]
      dir = dir.lstrip("/")
      dir = dir.rstrip("/")
      self.remote.delete_file(dir,self) # do we need to prevent root?

    # just files
    else:
      for i in range(0, len(self.FilesToDelete)):
        if self.FilesToDelete[i].isChecked():
          fname = self.current_directory + self.FilesToDelete[i].getText() # we put file names (not full paths)in the list
          fname = fname.lstrip("/")
          self.remote.delete_file(fname,self)
    self.remote.get_file_tree(self)
    self.manage_del_box.hide()

  def onCancelDel(self):
    self.manage_del_box.hide()

  def onCancelManageDialog(self):
    self.manage_directory_box.hide()

  def onDialogSave(self):
    content = DOM.getInnerText(DOM.getElementById(self.editorHTMLID))
    self.remote.save_file(str(self.current_open[2]), content, self) #self.current_open
    self.remote.open_file(str(self.nextfile[2]),self) #self.nextfile
    self.modified = False
    # set the content to none
    self.current_open = self.nextfile
    self.savediscard_box.hide()

  def onDialogDiscard(self):
    self.remote.open_file(str(self.nextfile[2]),self) # self.nextfile
    self.modified = False
    # set the content to None
    self.current_open = self.nextfile
    self.savediscard_box.hide()

  def onModeClick(self):
    if self.active_menu.getText() == "Mode":
      self.active_menu.setText("")
      self.menu_body.setWidget(self.menu_contents)
    else:
      self.active_menu.setText("Mode")
      modepanel = HorizontalPanel()
      modebutt = Button("Switch Drivers", getattr(self, "onSwitchDriversClick"))
      modebutt.setStyleName("supp-button")
      modepanel.add(modebutt)
      self.menu_body.setWidget(modepanel)

  def onSwitchDriversClick(self):
    #window.alert("You are trying to switch drivers")
    if self.isdriver == True:
      self.switching = True
      self.editor.add(HTML(""), self.functionID)
      self.remote.switch_driver(self)
      #window.alert("Just sent switch command.")
    else:
      window.alert("Passengers cannot elect to switch!")

  def onAudioClick(self):
    if self.active_menu.getText() == "Audio":
      self.active_menu.setText("")
      self.menu_body.setWidget(self.menu_contents)
    else:
      self.active_menu.setText("Audio")
      audiopanel = HorizontalPanel()
      audiobutton = Button("Skype Call", getattr(self, "onSkypeClick"))
      audiobutton.setStyleName("supp-button")
      audiopanel.add(audiobutton)
      self.menu_body.setWidget(audiopanel)
  def onSkypeClick(self):
    #window.alert("you are trying to make a skype call")
    #audiopanel.add(HTML("Skype call"))
    DOM.getElementById('Skype call').click()
    self.location = Window.getLocation()
    self.location.setHref("skype:NAME?call")

  def onTimer(self):
    # Check for new passenger
    if self.isdriver:
      self.remote.get_meetinginfo(self)
      if self.currpass.getText() != self.passenger.getText():
        self.currpass.setText(self.passenger.getText())
        if self.passenger.getText() == "No Partner logged in":
          #window.alert("No partners logged in")
          pass
        else:
          window.alert("New passenger %s detected" % self.passenger.getText())

    if self.quitting == False and self.switching == False:
      # do server update stuff here
      self.remote.receive_chatmessage(self)
      self.remote.receive_flash(self)
      # this only really matters for passengers
      if self.isdriver == False:
        self.remote.driver_status(self)

      if self.isdriver == True:
        content = DOM.getInnerText(DOM.getElementById(self.editorHTMLID))
        if len(content) > 0:
          self.remote.send_editor(content, self)
        else:
          self.remote.send_editor(" ", self)
      else:
        self.remote.receive_editor(self)

      # do flash stuff here
      if self.active_flash.getText() == "Flashing":
        if self.color.getText() == "pink":
          self.color.setText("green")
          self.panel.setStyleName("green")
        else:
          self.color.setText("pink")
          self.panel.setStyleName("pink")
      else:
        self.color.setText("white")
        self.panel.setStyleName("white")

    Timer(500, self)

  def toggleFlash(self):
    if self.active_flash.getText() == "Flashing":
      self.active_flash.setText("Off")
      self.flash.setText("Start Flash")
    else:
      self.active_flash.setText("Flashing")
      self.flash.setText("Stop Flash")

  def onTextSend(self):
    id = self.remote.get_username(self)
    if id < 0:
      console.error("Server Error or Invalid Response")
    self.remote.receive_chatmessage(self)
    msg = self.text_box.getText()
    self.remote.send_chatmessage(msg, self)
    self.text_box.setText("")

  def onKeyUp(self, sender, keyCode, modifers):
    pass
  def onKeyDown(self, sender, keyCode, modifiers):
    pass
  def onKeyPress(self, sender, keyCode, modifiers):
    if keyCode == KeyboardListener.KEY_ENTER and sender == self.text_box:
      id = self.remote.get_username(self)
      if id < 0:
        console.error("Server Error or Invalid Response")
      self.remote.receive_chatmessage(self)
      msg = self.text_box.getText()
      self.remote.send_chatmessage(msg, self)
      self.text_box.setText("")

  def onQuitClick(self):
    # We're trying to quit, pause communications
    self.quitting = True
    quitvp = VerticalPanel()
    quitvp.setSpacing(4)
    quitvp.add(HTML("We hope you had a productive session, come back soon!"))
    quithp = HorizontalPanel()
    quithp.setSpacing(7)
    quithp.add(Button("Wait, don't quit yet!", getattr(self, "onQuitCancel")))
    quithp.add(Button("Save and quit", getattr(self, "onQuitConfirm")))
    quitvp.add(quithp)
    quitvp.setCellHorizontalAlignment(quithp, HasAlignment.ALIGN_CENTER)
    self.quit_box = DialogBox()
    self.quit_box.setHTML("Quit Confirmation")
    self.quit_box.setWidget(quitvp)
    self.quit_box.setPopupPosition(350, 200)  # (left, top)
    self.quit_box.show()
  def onQuitCancel(self):
    self.quit_box.hide()
    # we're not trying to escape anymore, restart regular communications
    self.quitting = False
  def onQuitConfirm(self):
    self.quit_box.hide()
    self.remote.sync_all(self)
    self.remote.user_quit(self)


# Loading key libraries
import streamlit as st
import os
import numpy as np
import pandas as pd

from PIL import Image
import matplotlib.pyplot as plt
import seaborn as sns
import requests
import datetime

# get absolute path and goo two levels up
DIRPATH = DIRPATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

# set api endpoint
URL = 'https://bright1-sales-forecasting-ap1-2.hf.space'
API_ENDPOINT = '/predict'

# get list/choices for inputs
CITIES = ['Accra', 'Aflao', 'Akim Oda', 'Akwatia', 'Bekwai', 'Cape coast', 'Elmina,', 'Gbawe', 'Ho', 'Hohoe', 'intampo', 'Koforidua', 'Kumasi', 'Mampong', 'Obuasi', 'Prestea', 'Suhum', 'Tamale', 'Techiman', 'Tema', 'Teshie', 'Winneba']
CLUSTER = [ i for i in range(0, 17)]
STORE_ID = [ i for i in range(1, 55)]
CATEGORY_ID = [ i for i in range(0, 35)]

# Setting the page configurations
st.set_page_config(page_title = "Prediction Forecasting", layout= "wide", initial_sidebar_state= "auto")

st.title("Grocery Store Forecasting Prediction") # Setting the page title

image1 = Image.open('src/app/images1.jpg') # src\app\images1.jpg

#  create a function to make a request to the api
def make_prediction(store_id, category_id, onpromotion, city, store_type, cluster, date):

    # set paramter for the api
    parameters = {
    'store_id':int(store_id),
    'category_id':int(category_id),
    'onpromotion' :int(onpromotion),
    'city' : city,
    'store_type' : int(store_type),
    'cluster': int(cluster),
    'date_': date,

    }

    response = requests.post(url=f'{URL}{API_ENDPOINT}', params=parameters) # make a post request to the api

    sales_value = response.json()['sales'] #  get the sales value from the response

    sales_value = round(sales_value, 4) #  round up the sales value into 4 decimal places
    return sales_value

# display a head imdage for the app.
st.image(image1, width = 700)

st.sidebar.markdown('User Input Details and Information')

# Create interface
date= st.sidebar.date_input("Enter the Date",datetime.date(2023, 6, 30), min_value=datetime.date(2018, 1, 1))
store_id= st.sidebar.selectbox('Store id', options=STORE_ID)
category_id= st.sidebar.selectbox('categegory_id', options=CATEGORY_ID)
onpromotion= st.sidebar.number_input('onpromotion', step=1)
city =  st.sidebar.selectbox("city:", options= CITIES)
store_type=  st.sidebar.selectbox('type', options=[0, 1, 2, 3, 4])
cluster = st.sidebar.selectbox('cluster', options = CLUSTER )

# get predicted value
if st.sidebar.button('Predict', use_container_width=True, type='primary'):
            # make prediction
            sales_value = make_prediction(store_id, category_id, onpromotion,city, store_type, cluster, date)
            st.success('The predicted target is ' + str(sales_value))


import numpy as np
import os
import json
import matplotlib.pyplot as plt

from typing import Dict, Tuple, List, Any

def plt_tendency(logs: List[Dict[str, Any]], fig_path: str) -> Dict[str, Any]:
    list_epoch = [log['epoch'] for log in logs]
    list_train_time = [log['train_time'] for log in logs]
    list_eval_time = [log['eval_time'] for log in logs]
    list_train_pearson_rho = [log['train_pearson_rho'] for log in logs]
    list_train_spearmanr_rho = [log['train_spearmanr_rho'] for log in logs]
    list_train_kendalltau_rho = [log['train_kendalltau_rho'] for log in logs]
    list_train_mae = [log['train_mae'] for log in logs]
    list_train_rmse = [log['train_rmse'] for log in logs]
    list_validate_pearson_rho = [log['validate_pearson_rho'] for log in logs]
    list_validate_spearmanr_rho = [log['validate_spearmanr_rho'] for log in logs]
    list_validate_kendalltau_rho = [log['validate_kendalltau_rho'] for log in logs]
    list_test_pearson_rho = [log['test_pearson_rho'] for log in logs]
    list_test_spearmanr_rho = [log['test_spearmanr_rho'] for log in logs]
    list_test_kendalltau_rho = [log['test_kendalltau_rho'] for log in logs]
    list_test_mae = [log['test_mae'] for log in logs]
    list_test_rmse = [log['test_rmse'] for log in logs]

    fig = plt.figure(figsize=(6, 4))
    plt.plot(list_epoch, list_test_pearson_rho, color='red', label='pearson')
    plt.plot(list_epoch, list_test_spearmanr_rho, color='green', label='spearmanr')
    plt.plot(list_epoch, list_test_kendalltau_rho, color='blue', label='kendalltau')
    plt.plot(list_epoch, list_test_mae, color='purple', linestyle='--', label='mae')
    plt.plot(list_epoch, list_test_rmse, color='pink', linestyle='--', label='rmse')
    plt.legend()
    if not os.path.isdir('hpwl-figures'):
        os.mkdir('hpwl-figures')
    plt.savefig(fig_path)

    list_total = np.array(list_validate_pearson_rho) + np.array(list_validate_spearmanr_rho) + np.array(
        list_validate_kendalltau_rho)
    best_epoch = np.argmax(list_total)

    return {
        'train_time': list_train_time[best_epoch] / 5,
        'pearson': list_test_pearson_rho[best_epoch],
        'spearmanr': list_test_spearmanr_rho[best_epoch],
        'kendalltau': list_test_kendalltau_rho[best_epoch],
        'mae': list_test_mae[best_epoch],
        'rmse': list_test_rmse[best_epoch],
    }, best_epoch

PLT_TUPLES = [
#     ('MLP', 'hpwl-superblue19/MLP.json'),
#     ('Net2f-topo', 'hpwl-superblue19/Net2f.json'),
#     ('Net2a-topo', 'hpwl-superblue19/Net2a.json'),
#     ('LHNN', 'hpwl-superblue19/LHNN.json'),
#     ('Ours', 'hpwl-superblue19/hyper.json'),
#     ('Ours-topo', 'hpwl-superblue19/hyper-topo.json'),

    ('Ours (evaluate)', 'hpwl-superblue19/hyper-trans.json'),
    ('Ours', 'hpwl-superblue19/hyper.json'),
    ('Ours (fine-tune)', 'hpwl-superblue19/hyper-ft.json'),
]

if __name__ == '__main__':
    for name, path in PLT_TUPLES:
        try:
            with open(path) as fp:
                d = json.load(fp)
            ret, be = plt_tendency(d, f'hpwl-figures/{name}.png')
            print(f'For {name}@{be}:')
            for k, v in ret.items():
                print(f'\t{k}: {v:.3f}')
        except FileNotFoundError:
            print(f'For {name}: not found')


import pytest

from zarr.n5 import N5ChunkWrapper, N5FSStore
from zarr.creation import create
from zarr.storage import atexit_rmtree
from numcodecs import GZip
import numpy as np
from typing import Tuple
import json
import atexit

from zarr.tests.util import have_fsspec

def test_make_n5_chunk_wrapper():
    dtype = "uint8"
    chunk_shape = (10,)
    codec = GZip()
    # ValueError when specifying both compressor and compressor_config
    with pytest.raises(ValueError):
        N5ChunkWrapper(
            dtype, chunk_shape=chunk_shape, compressor_config=codec.get_config(), compressor=codec
        )

    wrapper_a = N5ChunkWrapper(dtype, chunk_shape=chunk_shape, compressor_config=codec.get_config())
    wrapper_b = N5ChunkWrapper(dtype, chunk_shape=chunk_shape, compressor=codec)
    assert wrapper_a == wrapper_b

@pytest.mark.parametrize("chunk_shape", ((2,), (4, 4), (8, 8, 8)))
def test_partial_chunk_decode(chunk_shape: Tuple[int, ...]):
    # Test that the N5Chunk wrapper can handle fractional chunks that
    # may be generated by other N5 implementations
    dtype = "uint8"
    codec = GZip()
    codec_wrapped = N5ChunkWrapper(dtype, chunk_shape=chunk_shape, compressor=codec)
    subslices = tuple(slice(0, cs // 2) for cs in chunk_shape)
    chunk = np.zeros(chunk_shape, dtype=dtype)
    chunk[subslices] = 1
    subchunk = np.ascontiguousarray(chunk[subslices])
    assert np.array_equal(codec_wrapped.decode(codec_wrapped.encode(subchunk)), chunk)

@pytest.mark.skipif(have_fsspec is False, reason="needs fsspec")
def test_dtype_decode():
    path = "data/array.n5"
    atexit_rmtree(path)
    atexit.register(atexit_rmtree, path)
    n5_store = N5FSStore(path)
    create(100, store=n5_store)
    dtype_n5 = json.loads(n5_store[".zarray"])["dtype"]
    dtype_zarr = json.loads(create(100).store[".zarray"])["dtype"]
    assert dtype_n5 == dtype_zarr


load("//build/bazel/rust:library.bzl", _crate_name = "pl_crate_name")

def crate_path(label, typ_path = None):
    [pkg_name, label] = label.split(":")
    label = _crate_name(label, pkg_name)

    if typ_path:
        return "::{}::{}".format(label, typ_path)

    return "::" + label


from sqlalchemy.dialects import postgresql

from pycroft.model import ddl
from sqlalchemy import null, and_, or_, func, Column, Integer, String, union, \
    literal, literal_column, select
from sqlalchemy.orm import Query

from .base import ModelBase
from .ddl import View, DDLManager
from .user import User, Property, Membership, PropertyGroup

manager = DDLManager()

property_query_stmt = union(
    Query([User.id.label('user_id'), Property.name.label('property_name'),
           literal(False).label('denied')])
    .select_from(Membership)
    .join(PropertyGroup)
    .join(User)
    .filter(and_(
        or_(Membership.begins_at == null(), Membership.begins_at <= literal_column('evaluation_time')),
        or_(Membership.ends_at == null(), literal_column('evaluation_time') <= Membership.ends_at),
    ))
    .join(Property)
    .group_by(User.id, Property.name)
    .having(func.every(Property.granted))
    .statement,

    Query([User.id.label('user_id'), Property.name.label('property_name'),
           literal(True).label('denied')])
    .select_from(Membership)
    .join(PropertyGroup)
    .join(User)
    .filter(and_(
        or_(Membership.begins_at == null(), Membership.begins_at <= literal_column('evaluation_time')),
        or_(Membership.ends_at == null(), literal_column('evaluation_time') <= Membership.ends_at),
    ))
    .join(Property)
    .group_by(User.id, Property.name)
    # granted by ≥1 membership, but also denied by ≥1 membership
    .having(and_(func.bool_or(Property.granted), ~func.every(Property.granted)))
    .statement,
)

evaluate_properties_function = ddl.Function(
    'evaluate_properties', ['evaluation_time timestamp with time zone'],
    'TABLE (user_id INT, property_name VARCHAR(255), denied BOOLEAN)',
    str(
        property_query_stmt.compile(
            dialect=postgresql.dialect(),
            compile_kwargs={'literal_binds': True}
        )
    ),
    volatility='stable',
)

manager.add_function(
    Membership.__table__,
    evaluate_properties_function
)

current_property = View(
    name='current_property',
    #metadata=ModelBase.metadata,
    query=(
        select([literal_column('user_id'), literal_column('property_name'),
                literal_column('denied')])
        .select_from(func.evaluate_properties(func.current_timestamp()))
    ),
)
manager.add_view(Membership.__table__, current_property)

class CurrentProperty(ModelBase):
    __table__ = current_property.table
    __mapper_args__ = {
        'primary_key': (current_property.table.c.user_id,
                        current_property.table.c.property_name),
    }

manager.register()


from re import compile
from glob import glob
from p_tqdm import p_uimap
from eis1600.processing.preprocessing import get_yml_and_miu_df
from eis1600.processing.postprocessing import write_updated_miu_to_file

sheikhuna = compile('[و]?شيخنا')

def untag_sheikhuna(row):
    if row['TOKENS'] and sheikhuna.match(row['TOKENS']) and row['TAGS_LISTS'] and [tag for tag in row['TAGS_LISTS']
                                                                                if tag.startswith('P1')]:
        if len(row['TAGS_LISTS']) > 1:
            row['TAGS_LISTS'].pop()
            return row['TAGS_LISTS'], True
        else:
            return None, True
    else:
        return row['TAGS_LISTS'], False

def check_file(file):
    with open(file, 'r+', encoding='utf-8') as fh:
        fh.readline()
        fh.readline()
        if fh.readline() == 'reviewed    : REVIEWED2\n':
            fh.seek(0)
            yml, df = get_yml_and_miu_df(fh)
            df['TAGS_LISTS'], changed = zip(*df[['TOKENS', 'TAGS_LISTS']].apply(untag_sheikhuna, axis=1))
            if any(changed):
                write_updated_miu_to_file(fh, yml, df)

def main():
    files = glob('*.EIS1600')

    res = []
    res += p_uimap(check_file, files)


import glob
from skimage import io
import os
import numpy as np

dirname = '20210711_test_out'
files = glob.glob('%s/**/*.png' % dirname,recursive=True)

testsets = {'showcase1':[],'showcase2':[],'showcase3':[]}

for file in files:
    for k in testsets.keys():
        if k in file:
            testsets[k].append(file)

ordered_testsets = {}

for k in testsets.keys():
    ordered_arr = ['']*len(testsets[k])
    print('ordered array now',len(ordered_arr))

    for f in testsets[k]:
        basename = os.path.basename(f)
        idx = int(basename.split('_')[0]) - 1
        ordered_arr[idx] = f

    ordered_testsets[k] = ordered_arr

# creating stacks
os.makedirs('%s/stacks' % dirname, exist_ok=True)

for k in testsets.keys():

    imgarr = []
    for f in ordered_testsets[k]:
        imgarr.append(io.imread(f))

    io.imsave('%s/stacks/%s.tif' % (dirname, k),np.array(imgarr))
    print('generated stack for',k)


class Solution(object):
    # @param A, a list of integers
    # @return an integer
    def firstMissingPositive(self, nums):
        i = 0
        while i < len(nums):
            if nums[i] > 0 and nums[i] - 1 < len(nums) and nums[i] != nums[nums[i]-1]:
                nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]
            else:
                i += 1

        for i, integer in enumerate(nums):
            if integer != i + 1:
                return i + 1
        return len(nums) + 1


# Python3 for Mirror Binary Tree
# 			  1								1
# 			 / \						   / \
# 			3	2			--->		  2	  3
# 		       / \						 / \
# 			  5	  4				   	    4   5

# RECURSIVE
def mirror(root):
	if not root:
		return
	mirror(root.left)
	mirror(root.right)
	root.left, root.right = root.right, root.left

# ITERATIVE
def mirror(root):
	queue = []
	queue.append(root)
	while queue:
		q = queue.pop(0)
		if q.left:
			queue.append(q.left)
		if q.right:
			queue.append(q.right)
		q.left, q.right = q.right, q.left


import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from .GCN_layer import GCN as GraphConv_ordi
from tools.construct_graph_simple import normalize_digraph

class CausalScore(nn.Module):

    def __init__(self, dim, hidden1, ratio, norm):
        super(CausalScore, self).__init__()

        self.dim = dim
        self.hidden1 = hidden1
        self.convs1 = nn.ModuleList()
        # self.batch_norms1 = nn.ModuleList()
        for i in range(len(self.hidden1)):
            if i == 0:
                conv = GraphConv_ordi(in_features=self.dim, out_features=self.hidden1[0])
            else:
                conv = GraphConv_ordi(in_features=self.hidden1[i - 1], out_features=self.hidden1[i])
            self.convs1.append(conv)
            # self.batch_norms1.append(nn.BatchNorm1d(self.hidden1[i]))
        self.convs1.append(GraphConv_ordi(in_features=self.hidden1[-1], out_features=1))
        self.ratio = ratio
        self.norm = norm

    def forward(self, x, edge):
        node_score, x_1 = self.get_score(x, edge)
        (causal_x, causal_edge), (conf_x, conf_edge) = \
            split_graph_score_softmax(x_1, edge, node_score, self.ratio, self.norm)
        return (causal_x, causal_edge), (conf_x, conf_edge), node_score

    def get_score(self, x, edge):
        # for conv, bn in zip(self.convs1, self.batch_norms1):
        #     x = conv(x, edge)  # GraphConv
        #     x = F.relu(bn(x))
        for conv in self.convs1[:-1]:
            x = conv(x, edge)  # GraphConv
            x = F.relu(x)
        node_score = self.convs1[-1](x, edge)
        return node_score, x

class PredictionNet(torch.nn.Module):

    def __init__(self, in_features, num_class, hidden2):
        super(PredictionNet, self).__init__()

        self.hidden2 = hidden2
        self.convs2 = nn.ModuleList()
        self.batch_norms2 = nn.ModuleList()
        for i in range(len(self.hidden2)):
            if i == 0:
                conv = GraphConv_ordi(in_features=in_features, out_features=self.hidden2[0])
            else:
                conv = GraphConv_ordi(in_features=self.hidden2[i - 1], out_features=self.hidden2[i])
            self.convs2.append(conv)
            self.batch_norms2.append(nn.BatchNorm1d(self.hidden2[i]))

        self.causal_mlp = nn.Sequential(
            nn.Linear(sum(self.hidden2) * 2, self.hidden2[-1] * 4),
            # nn.BatchNorm1d(self.hidden2[-1]),
            nn.ReLU(True),
            nn.Linear(self.hidden2[-1] * 4, num_class)
        )
        self.conf_mlp = nn.Sequential(
            nn.Linear(sum(self.hidden2) * 2, self.hidden2[-1] * 4),
            # nn.BatchNorm1d(self.hidden2[-1]),
            nn.ReLU(True),
            nn.Linear(self.hidden2[-1] * 4, num_class)
        )

    def forward(self, x, edge):
        graph_x = self.get_graph_rep(x, edge)
        return self.get_causal_pred(graph_x)

    def get_graph_rep(self, x, edge):
        xs = []
        for conv, bn in zip(self.convs2, self.batch_norms2):
            x = conv(x, edge)
            x = F.relu(bn(x.transpose(1, 2)).transpose(1, 2))
            xs.append(x)
        return torch.cat([self.readout(xx) for xx in xs], dim=-1)  #

    def get_causal_pred(self, causal_graph_x):
        pred = self.causal_mlp(causal_graph_x)  # [32, 10]
        return pred

    def get_conf_pred(self, conf_graph_x):
        pred = self.conf_mlp(conf_graph_x)  # [32, 10]
        return pred

    def get_comb_pred(self, causal_graph_x, conf_graph_x):
        causal_pred = self.causal_mlp(causal_graph_x)  # y_c
        conf_pred = self.conf_mlp(conf_graph_x).detach()  # y_s
        return torch.sigmoid(conf_pred) * causal_pred  # \hat{y}

    def readout(self, x):
        return torch.concat([global_max_pool(x), global_mean_pool(x)], dim=-1)

def global_max_pool(x):  # x:[B,P,d]
    return F.max_pool1d(x.transpose(1, 2), x.shape[1]).squeeze(2)

def global_mean_pool(x):  # x:[B,P,d]
    return F.avg_pool1d(x.transpose(1, 2), x.shape[1]).squeeze(2)

def split_graph_score_softmax(x, A, node_score, ratio, norm=False, tau=0.1):
    pass

def get_sub_graph(x, A, group, norm='DAD', type_int=0):
    pass