import crypto.interfaces.commandline.base as base_cli
import time

from crypto.classes.ciphers.aes import AESCipher
from crypto.classes.ciphers.blowfish import BlowfishCipher
from crypto.classes.ciphers.cast import CASTCipher
from crypto.classes.ciphers.xor import XORCipher
from crypto.classes.encoders.base import NullEncoder
from crypto.classes.encoders.binary import Base64Encoder, URLSafeBase64Encoder

CHAINING_MODE_CHOICES = set(
    AESCipher.supported_modes.keys() +
    BlowfishCipher.supported_modes.keys() +
    CASTCipher.supported_modes.keys()
)

CIPHERS = {
    'AES': AESCipher,
    'BLOWFISH': BlowfishCipher,
    'CAST': CASTCipher,
    'XOR': XORCipher
}
CIPHER_CHOICES = CIPHERS.keys()
CIPHER_DEFAULT = "XOR"

ENCODERS = {
    'BASE64': Base64Encoder,
    'NULL': NullEncoder,
    'URLSAFEBASE64': URLSafeBase64Encoder,
}
ENCODER_CHOICES = ENCODERS.keys()
ENCODER_DEFAULT = "BASE64"

class CipherInterface(base_cli.DataInterface):
    def __init__(
        self,
        cipher,
        clipboard=None,
        data_input_path=None,
        data_output_path=None,
        decrypt=None,
        encoder=None,
        iv_gen=None,
        iv_path=None,
        key_gen=None,
        key_path=None,
        mode=None,
        *args,
        **kwargs
    ):
        """Sets up the cipher itself when initializing."""
        super(CipherInterface, self).__init__(
            clipboard,
            data_input_path,
            data_output_path
        )
        self.cipher = CIPHERS[cipher]()
        self.cipher.data = self.data
        self.decrypt = decrypt
        self.generated_key = False
        self.generated_iv = False

        self.set_mode(mode)
        self.set_key(key_gen, key_path)
        self.set_iv(iv_gen, iv_path)
        self.set_encoder(encoder)

    def execute(self):
        """Performs necessary encryption/decryption and associated writing
        operations.
        """
        epoch = "%s" % int(time.time())

        if self.generated_key:
            self.write_to_file("%s.key" % epoch, self.cipher.key)
        if self.generated_iv:
            self.write_to_file("%s.iv" % epoch, self.cipher.iv)

        if self.decrypt:
            self.store_data(self.cipher.decrypt(self.data))
        else:
            self.store_data(self.cipher.encrypt(self.data))

    def set_encoder(self, encoder):
        """Set the cipher's encoder."""
        if encoder:
            self.cipher.set_encoding(ENCODERS[encoder])

    def set_key(self, key_gen, key_path):
        """Determine and set cipher's key. Reading file `key_path` takes highest
        priority. When `key_gen` is True, will generate a key instead. Lowest
        priority is to fetch the key from a commandline prompt.
        """
        if key_path:
            self.cipher.key = self.read_from_file(key_path)
            return
        elif not self.decrypt and key_gen and hasattr(
            self.cipher,
            'generate_key'
        ):
            self.generated_key = True
            self.cipher.key = self.cipher.generate_key()
            return
        else:
            self.cipher.key = self.get_from_prompt("Please enter a valid key: ")

    def set_iv(self, iv_gen, iv_path):
        """Determine and set cipher's IV if appropriate. Reading file `iv_path`
        takes highest priority. When `iv_gen` is True, will generate an IV
        instead. Lowest priority is to fetch the IV from a commandline prompt.
        """
        if 'iv' not in self.cipher.attributes:
            return
        elif not self.cipher.mode.requires_iv:
            return
        elif iv_path:
            self.cipher.iv = self.read_from_file(iv_path)
        elif not self.decrypt and iv_gen and hasattr(
            self.cipher,
            'generate_iv'
        ):
            self.generated_iv = True
            self.cipher.iv = self.cipher.generate_iv()
        else:
            self.cipher.iv = self.get_from_prompt("Please enter a valid IV: ")

    def set_mode(self, mode):
        """Set the cipher's mode if appropriate."""
        if 'mode' in self.cipher.attributes and mode:
            self.cipher.mode = mode

def execute(args):
    """Instantiates interface from argparse namespace and executes."""
    interface = CipherInterface(**vars(args))
    interface.execute()

def add_parser_args(parser):
    """Adds Cipher related arguments to ArgumentParser and sets execute method.
    Add positional argument 'cipher'.
    Uses optional switches (d, e, iv, IV, k, K, m).
    """
    parser.set_defaults(execute=execute)

    parser.add_argument(
        "cipher",
        choices=CIPHER_CHOICES,
        default=CIPHER_DEFAULT,
        help="Cipher algorithm to apply.",
        type=str.upper
    )

    parser.add_argument(
        "--decrypt",
        "-d",
        action="store_true",
        default=False,
        help="When True will decrypt data. When False will encrypt data."
    )

    parser.add_argument(
        "--encoder",
        "-e",
        choices=ENCODER_CHOICES,
        default=ENCODER_DEFAULT,
        help="Encoder/Decoder to apply to text when encrypting/decrypting.",
        type=str.upper
    )

    parser.add_argument(
        "--iv",
        "-iv",
        dest="iv_path",
        help=("Path to initialization vector used to encrypt or decrypt. IV " +
            "must adhere to constraints of cipher."
        )
    )

    parser.add_argument(
        "--iv-gen",
        "-IV",
        action="store_true",
        default=False,
        help="Generate a random IV automatically."
    )

    parser.add_argument(
        "--key",
        "-k",
        dest="key_path",
        help=("Path to key used to encrypt or decrypt. Key size must adhere " +
            "to constraints of cipher."
        )
    )

    parser.add_argument(
        "--key-gen",
        "-K",
        action="store_true",
        default=False,
        help="Generate a random key automatically."
    )

    parser.add_argument(
        "--mode",
        "-m",
        choices=CHAINING_MODE_CHOICES,
        default=None,
        help="Chaining mode to use. This applies only to block ciphers.",
        type=str.upper
    )


from os import popen
from glob import glob

# folders-name
input_path = "./img-input"
output_path = "./img-output"

# quality of produced .webp images [0-100]
quality = input("Quality (default 80): ") or "80"

if int(quality) < 0 or int(quality) > 100:
    print("image quality out of range[0-100]")
    exit(0)

img_list = []
for img_name in glob(input_path+'/*'):
    # can use more image types(bmp,tiff,gif)
    if img_name.endswith(".jpg") or img_name.endswith(".png") or img_name.endswith(".jpeg"):
        # extract images' name(image_name.[jpg|png]) from the full path
        img_list.append(img_name.split('\\')[-1])
# print(img_list)   # debug

for img_name in img_list:
    cmd ='"bin/cwebp" \"'+input_path+'/'+img_name+'\" -q '+quality+' -o \"'+output_path+'/'+(img_name.split('.')[0])+'.webp\"'
    popen(cmd)
    # print(cmd)    # debug


#coding:utf-8

"""
ID:          issue-2080
ISSUE:       2080
TITLE:       Ability to format UUID from char(16) OCTETS to human readable form and vice versa
DESCRIPTION:
JIRA:        CORE-1656
FBTEST:      bugs.core_1656
"""

import pytest
from firebird.qa import *

db = db_factory()

test_script = """select uuid_to_char(char_to_uuid('93519227-8D50-4E47-81AA-8F6678C096A1')) from rdb$database;
"""

act = isql_act('db', test_script)

expected_stdout = """
UUID_TO_CHAR
====================================
93519227-8D50-4E47-81AA-8F6678C096A1

"""

@pytest.mark.version('>=3.0')
def test_1(act: Action):
    act.expected_stdout = expected_stdout
    act.execute()
    assert act.clean_stdout == act.clean_expected_stdout


# Entrez jest systemem wyszukiwania online wprowadzonym przez NCBI
# Entrez moduł parsuje XML, zwraca dane w formie list() lub dict()
#
from Bio import Entrez, SeqIO
Entrez.email = "Your.Name.Here@example.org" # wskaż osobę wykazującą zapytania
# podstawowe informacje np. bazy danych
#info = Entrez.einfo() # funkcje wyszukiwania danych: einfo or esearch, efetch, ...
#record = Entrez.read(info)
#print(record)  # key: DbList - wykaz dostępnych baz danych
#info.close()

### pełny wykaz funkcji i parametrów dostępu dla w/w funkcji
##  https://www.ncbi.nlm.nih.gov/books/NBK25499/#chapter4.EFetch

# wyszukiwanie danych
#info = Entrez.esearch(db = "pubmed",term = "genome")  # m.in przedstawia listę identyfikatorów UID pasujących do zapytania tekstowego
#record = Entrez.read(info)
#print(record)
# Wyszukiwanie bez podania bazy danych
#info = Entrez.egquery(term = "genome")
#record = Entrez.read(info)
#print(record)
#print(record['eGQueryResult'][0]['DbName'])

## efetch do wyszukiwania i pobierania pełnych szczegółów rekordu z Entrez.
### UID stanowi wartość parametru funkcji id
#handle = Entrez.efetch(db="nucleotide", id="AY851612", rettype="gb", retmode="text")
#print(handle.readline().strip())

#handle = Entrez.efetch(db = "nucleotide", id = "EU490707", rettype = "fasta")
#record = SeqIO.read( handle, "fasta")
#print(record)

###  podsumowanie wyszukanych dokumentów dla listy wejściowych identyfikatorów UID
#info = Entrez.esummary(db="pubmed", id="19304878,14630660", retmode="xml")
#records = Entrez.parse(info)
#### uwaga przy odczycie zwracaj uwagę na typy/klasy argumentów wyjściowych
### wykorzystaj pętlę lub funkcję next dla 'generator'
### możesz wykorzystać też metody https://biopython.readthedocs.io/en/latest/api/Bio.Entrez.Parser.html
### dla 'Bio.Entrez.Parser.DictionaryElement'

# for record in records:
#     # each record is a Python dictionary or list.
#     print(record)

# info.close()

##########Zadanie 1
## Połącz się z Entrez - systemem wyszukiwania informacji w NCBI.
## Sprawdż ile publikacji w bazie PubMed znajduje się na temat 'covid-19' (parametr term)

info = Entrez.esearch(db = "pubmed",term = "covid-19")
record = Entrez.read(info)
print(record['Count'])

########### Zadanie 2
#### W bazie danych nucleotide wyszukaj informacje dla kwerendy: 'covid'
info = Entrez.esearch(db = "nucleotide",term = "covid")
record = Entrez.read(info)

#### a) wypisz wszystkie UID  dla w/w kwerendy (key: IdList)
# print(record)
print(record['IdList'])

####  b) dla 3-go znalezionego UID odczytaj (użyj funkcji efetch z parametrem retmode="xml")
#### dodatkowe informacje z bazy "nucleotide"
info = Entrez.efetch(db="nucleotide", id="1937369466", retmode="xml")
record = Entrez.read(info)
print(record)

####  (i) nazwę tego biomarkera/cząstki
#'GBReference_title': 'Staphylococcus aureus infected embolic stroke upregulates Orm1 and Cxcl2 in a rat model of septic stroke pathology'

####  (ii) z jakiego organizmu były pobrane próbki do badań
#'GBSeq_organism': 'Rattus norvegicus'


from jittor import transform
import jittor as jt
import matplotlib.pyplot as plt
from tqdm import tqdm
from PIL import Image

filename = ['data/1.tif', 'data/2.tif', 'data/3.tif', 'data/4.tif', 'data/5.jpg']
num_eachpic = 1000
num_base = 0

if __name__ == '__main__':
    jt.set_global_seed(648)

    for aPic in filename:
        # 数据输入
        img = Image.open(aPic)
        '''
        print(img.size)        #(1760 x 2640)      (1904, 4096)
        input()
        '''
        # 定义并应用变换，得到一个新图片
        data_transforms_1 = transform.Compose([
            transform.RandomResizedCrop(size = (224, 224), scale = (0.05, 1.0))
        ])

        count = 0
        for i in range(int(img.size[1]/112)):
            for j in range(int(img.size[0]/112)):
                height = 224
                width = 224
                if i*112 + height > img.size[1]:
                    height = img.size[1] - i*112
                if j*112 + width > img.size[0]:
                    width = img.size[0] - j*112
                tmp = transform.crop(img, top = i*112, left = j*112, height = height, width = width)
                tmp = transform.resize(tmp, size=(224, 224))
                tmp.save("result/{}.png".format(count + num_base),quality = 0.95)
                count += 1

        for i in range(num_eachpic):
            tmp = data_transforms_1(img)
            tmp.save("result/{}.png".format(i + count + num_base),quality = 0.95)
            if i + count >= 1000:
                break

        num_base += 1000


from initialize_my_contract import initialize
from model import algo
import pandas as pd

from process_data import pre_precess_for_model
from aggregation import decode

_, _, _, _, my_contract = initialize()

def take_all_data_from_blockchain():
    result = []
    pp = my_contract.functions.getTotal().call()
    for i in range(len(pp)):
        feats = decode(pp[i][2])
        covid_res = pp[i][1]
        feats.insert(1, covid_res)
        result.append(feats)
    dataset = pre_precess_for_model(result)
    print(f'We have {dataset.shape[0]} for current records number.')
    return dataset
    # algo(kk, dp)

def predict_for_datapoint(datapoint):
    print(f'Get the datapoint\n {datapoint}')
    print("Waiting...")
    all_data = take_all_data_from_blockchain()
    result = algo(all_data, datapoint)
    return result

# For test this function
if __name__ == '__main__':
    dp = pd.read_csv('C:/Users/zjy/Desktop/test_dataset.csv')
    predict_for_datapoint(dp)


position = {
    '1': '1',
    '2': '2',
    '3': '3',
    '4': '4',
    '5': '5',
    '6': '6',
    '7': '7',
    '8': '8',
    '9': '9'
}

original_positions = {
    '1': '1',
    '2': '2',
    '3': '3',
    '4': '4',
    '5': '5',
    '6': '6',
    '7': '7',
    '8': '8',
    '9': '9'
}

X = 'X'
O = 'O'

possible_input = ( '1', '2', '3', '4', '5', '6', '7', '8', '9' )
taken_positions = []

def update_grid(chosen_position, symbol):
    position.update({chosen_position: symbol})

def print_grid():
    print(f" {position['1']} | {position['2']} | {position['3']}")
    print(f"---|---|---                                         ")
    print(f" {position['4']} | {position['5']} | {position['6']}")
    print(f"---|---|---                                         ")
    print(f" {position['7']} | {position['8']} | {position['9']}")

def all_positions_have_changed(position, original_positions):
    number_of_original_positions = len(position)
    number_of_values_changed = 0

    # Find number of values changed
    for key in position:
        if position[key] != original_positions[key]:
            number_of_values_changed += 1

    # Check and return weather all positions have changed
    if (number_of_values_changed == number_of_original_positions):
        return True
    else:
        return False


class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        for row in board:
            visited=set()
            for col in row:
                if col!='.' and col in visited:
                    return False
                visited.add(col)
        n=len(board)
        for col in range(n):
            visited=set()
            for row in board:
                if row[col]!='.' and row[col] in visited:
                    return False
                visited.add(row[col])
        for row3 in range(0,9,3):
            for col3 in range(0,9,3):
                visited=set()
                for row in range(row3,row3+3):
                    for col in range(col3,col3+3):
                        if board[row][col]!='.' and board[row][col] in visited:
                            return False
                        visited.add(board[row][col])
        return True


import tweepy
import os

def init_tweepy():
    CONSUMER_KEY = os.environ['TWITTER_CONSUMER_KEY']
    CONSUMER_SECRET = os.environ['TWITTER_CONSUMER_SECRET']
    ACCESS_TOKEN = os.environ['TWITTER_ACCESS_TOKEN']
    ACCESS_SECRET = os.environ['TWITTER_ACCESS_SECRET']

    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
    auth.set_access_token(ACCESS_TOKEN, ACCESS_SECRET)

    return tweepy.API(auth)

def update_status(api, content):
    try:
        api.update_status(content)
    except tweepy.error.TweepError as e:
        if e.api_code == 187:
            print('Duplicate tweet.')
        else:
            raise e


import minizinc
import pymzm

model = pymzm.Model()

xs = model.add_variables("x", indices=range(4), vtype=pymzm.Variable.VTYPE_BOOL)
model.add_constraint(pymzm.Expression.AND([
    xs[0] | xs[1] | ~xs[2],
    xs[1] | xs[2] | ~xs[3],
    xs[0] | ~xs[1] | xs[3],
]))
model.set_solve_criteria(pymzm.SOLVE_SATISFY)
model.generate()

gecode = minizinc.Solver.lookup("gecode")
result = minizinc.Instance(gecode, model).solve(all_solutions=False)

for i in range(4):
    print(f"x_{i} = {result[f'x_{i}']}")


# Write a program which reads a word, lower-cases all its letters, then prints out a square array where the first row
# contains the word, and each subsequent line is the previous line circular-shifted one place to the left.  Example
# for entered word word =="MoXiE":

word = input('Enter the string to modify: ').lower()
length = len(word)
accumulator = ''
for i in range(length):
    accumulator = word[i:] + word[:i]
    print(accumulator)


#############################################################
#       AUTHOR: MELQUIZEDEC MOO MEDINA                      #
#       PROGRAMA: Cola.py                                   #
#       Description: PROGRAMA DE LA CLASE NODO              #
#       DATE:  12/SEP/2020                                  #
#############################################################
from Lista import *

class Cola(Lista):

    def __init__(self, dato):
        Lista.__init__(self,dato)
        self.tamanio=1

    def insertar(self,dato):
        respuesta=self.insertarNodo(dato)
        if respuesta!=False:
            self.tamanio = self.tamanio + 1
            return respuesta

    def quitar(self):
        dato=self.eliminarNodoCabeza()
        if dato:
            self.tamanio=self.tamanio-1
            return dato
        else:
            return  False


# coding=utf-8
from dataflows import Flow, printer, delete_fields, update_resource, add_computed_field, load
import csv
from datapackage_pipelines_budgetkey.pipelines.maya.maya_parser_utils import rename_fields, add_fields, fix_fields, \
    verify_row_count, verify_same_row_count, verify_row_values

SUG_MISPAR_ZIHUY_MAPPING = {'מספר ת.ז.': 'id_number',
                            'ID no.':'id_number',
                            'מספר דרכון': 'passport_number',
                            'Passport no.': 'passport_number',
                            'מספר ביטוח לאומי':'social_security_number',
                            'מספר זיהוי לא ידוע': 'unknown'
                            }

RENAME_FIELDS = {
    'Shem': 'FullName',
    'ShemPriatiVeMishpacha': 'FullName',

    'EnglishName': 'FullNameEn',

    'TaarichTchilatHaKehuna': 'ReportDate',
    'TaarichTchilatHaCehuna': 'ReportDate',

    'HaTafkidSheMila': 'Position',
    'MekomHaAvoda': 'CompanyName',

    'MeshechZmanSheMilaBaTafkid': 'DurationInPosition/When',
    'MeshechHaZmanSheMilaTafkid': 'DurationInPosition/When',

    'MisparZihuy1': 'MisparZihuy',
    'SugMisparZihuy1':'SugMisparZihuy',
}

FIELDS = [
    'SugMisparZihuy',
    'MisparZihuy',
    'FullName',
    'ReportDate'
]

OPTIONAL_FIELDS = ['FullNameEn']

TABLE_FIELDS = [
    'Position',
    'CompanyName',
    'DurationInPosition/When'
]

def validate(rows):
    for row in rows:
        verify_row_count(row, FIELDS, 1)
        verify_row_count(row, OPTIONAL_FIELDS, 1, is_required=False)
        verify_same_row_count(row, TABLE_FIELDS)
        verify_row_values(row, 'SugMisparZihuy', SUG_MISPAR_ZIHUY_MAPPING)
        yield row

def filter_by_type(rows):
    for row in rows:
        if row['type'] == 'ת091' or row['type'] == 'ת093':
            yield row

def _is_null_string(string):
    return not string or string == '-' * len(string) or string == '_' * len(string)

def parse_document(rows):
    for row in rows:
        doc = row['document']

        table_elements = len(doc.get(TABLE_FIELDS[0],[]))
        for field in FIELDS:
            row[field] = doc[field][0]
        for field in OPTIONAL_FIELDS:
            row[field] = doc[field][0] if doc.get(field) else None
        row['SugMisparZihuy'] = SUG_MISPAR_ZIHUY_MAPPING[row['SugMisparZihuy']]

        for i in range(table_elements):
            work_record = {k:doc[k][i]  for k in TABLE_FIELDS}
            new_record = {}
            new_record.update(row)
            new_record.update(work_record)
            yield new_record

        #Add an empty record in case user did not fill any work record
        if table_elements == 0:
            new_record = {}
            new_record.update(row)
            new_record.update({k:""  for k in TABLE_FIELDS})
            yield new_record

def flow(*_):
    return Flow(
        update_resource(
            -1, name='reported_work_record', path="data/reported_work_record.csv",
        ),
        filter_by_type,
        rename_fields(RENAME_FIELDS),
        add_fields(FIELDS, 'string'),
        add_fields(TABLE_FIELDS, 'string'),
        add_fields(OPTIONAL_FIELDS, 'string'),
        validate,
        parse_document,
        fix_fields(TABLE_FIELDS + OPTIONAL_FIELDS + FIELDS),
        delete_fields(['document', 'pdf', 'other', 'num_files', 'parser_version', 'source', 's3_object_name', 'id', 'company', 'type', 'fix_for', 'fixed_by', 'next_doc', 'prev_doc']),
    )

if __name__ == '__main__':
    csv.field_size_limit(512 * 1024)

    Flow(
        load('/var/datapackages/maya/maya_complete_notification_list/datapackage.json'),
        flow(),
        printer(),
    ).process()


#!/usr/bin/python3
"""A script taht adds two integers"""

def add_integer(a, b=98):
    """A Function that adds two integers
    Args:
        a: The first integer
        b: The second integer
    Return:
        Sum of a + b
    """

    if not isinstance(a, (int, float)):
        raise TypeError("a must be an integer")
    if not isinstance(b, (int, float)):
        raise TypeError("b must be an integer")

    a = int(a) if isinstance(a, float) else a
    b = int(b) if isinstance(b, float) else b

    return a + b


import string
import mathExpr as ME

def Error(str):
    print(str)

def CheckChar(char, CharList):
    for i in CharList:
        if i == char:
            return True
    return False

def id(input):
    lower = list(string.ascii_lowercase)
    upper = list(string.ascii_uppercase)
    digits = [str(i) for i in range(0, 10)]
    CHARS = lower + upper + digits

    flag = False
    for i in lower:
        if input[0] == i: flag = True;break
    for i in upper:
        if input[0] == i: flag = True;break
    if flag:
        for i in input[1:]:
            if CheckChar(i, CHARS) == False:
                return False
        return True

    return False

def nummber(input):
    digits = [str(i) for i in range(0, 10)]
    flag = False
    for i in input:
        for j in digits:
            if i == j:
                flag = True
                break
        if flag == False:
            return False
        else:
            flag = False
    return True

def check_logic(list):
    for i in list:
        if i == '>' or i == '<' or i == '=' or i == '!':
            return True
    return False

def Parse(lists):
    return [Stmt(list) for list in lists]

def CheckExprNum(list):
    for i in list:
        if i == '=':
            return 1
        if i == 'if':
            return 2
        if i == 'while':
            return 3

def Stmt(list):
    ExprNum = CheckExprNum(list)
    if ExprNum == 1:
        return Expr1(list)
    if ExprNum == 2:
        return Expr2(list)
    if ExprNum == 3:
        return Expr3(list)

def FindLogic(list):
    start = 0
    flag1 = True
    end = 0
    flag2 = True
    for i in range(len(list)):
        if list[i] == '(' and flag1:
            flag1 = False
            start = i
        elif list[i] == ')' and flag2:
            flag2 = False
            end = i
    if end < start:
        return -1, -1
    elif end == start:
        return 0, 0
    else:
        return start, end

def Expr1(list):
    if id(list[0]) and list[1] == '=':
        return ME.math_expr(list[2:])
    else:
        Error('id error')
        return False

def Expr2(list):
    if list[0] == 'if':
        start, end = FindLogic(list[1:])
        if start + end == 0:
            Error('their no logical expr')
        elif start + end < 0:
            Error('logical expr () not correct')
        else:
            if check_logic(list[start + 1:end]):
                return Stmt(list[end + 2:])
            else:
                Error('logical expr not correct')
                return False

def Expr3(list):
    if list[0] == 'while':
        start, end = FindLogic(list[1:])
        if start + end == 0:
            Error('their no logical expr')
        elif start + end < 0:
            Error('logical expr () not correct')
        else:
            if check_logic(list[start + 1:end]):
                return Stmt(list[end + 2:])
            else:
                Error('logical expr not correct')
                return False


from collections import defaultdict
from pathlib import Path

import numpy as np
import torch.utils.data as torch_data

# from ..utils import common_utils
from .augmentor.data_augmentor import DataAugmentor
from .processor.data_processor import DataProcessor
from .processor.point_feature_encoder import PointFeatureEncoder
from ..utils import box_utils, common_utils

import traceback

class DatasetTemplate(torch_data.Dataset):
    def __init__(self, dataset_cfg=None, class_names=None, training=True, root_path=None, logger=None, pseudo=False, pseudo_set=None, vis=False, points_range=False, **kwargs):
        super().__init__()
        self.dataset_cfg = dataset_cfg
        self.training = training
        self.vis = vis
        self.class_names = class_names #['car']

        self.pseudo = pseudo
        self.points_range = points_range
        self.range_feat = self.dataset_cfg.get("RANGE_FEAT", False)

        # for pseudo only
        self.index_to_class_names = {}
        self.index_to_class_names[-1] = 'invalid'
        self.index_to_class_names[0] = 'bg'
        for i in range(len(self.class_names)):
            self.index_to_class_names[i+1] = self.class_names[i]

        self.pseudo_set = pseudo_set
        self.root_path = root_path if root_path is not None else Path(self.dataset_cfg.DATA_PATH)
        self.logger = logger
        if self.dataset_cfg is None or class_names is None:
            return

        print("self.dataset_cfg", self.dataset_cfg)
        self.point_cloud_range = np.array(self.dataset_cfg.POINT_CLOUD_RANGE, dtype=np.float32)

        if dataset_cfg.DATASET == 'NuscenesDataset':
            self.point_feature_encoder = PointFeatureEncoder(
                    self.dataset_cfg.POINT_FEATURE_ENCODING,
                    point_cloud_range=self.point_cloud_range
            )
            # disable velo
            self.data_augmentor = DataAugmentor(
                self.root_path, self.dataset_cfg.DATA_AUGMENTOR, self.class_names, logger=self.logger, nusc=False, pseudo=self.pseudo
            ) if self.training else None
            ###
            self.data_processor = DataProcessor(
                self.dataset_cfg.DATA_PROCESSOR, point_cloud_range=self.point_cloud_range,
                training=self.training
            )
            #####
            self.voxel_size = self.data_processor.voxel_size
            self.grid_size = self.data_processor.grid_size
            self.total_epochs = 0
            self._merge_all_iters_to_one_epoch = False

        elif dataset_cfg.DATASET == 'KittiDataset' or 'WaymoDaDataset':
            self.point_feature_encoder = PointFeatureEncoder(
                self.dataset_cfg.POINT_FEATURE_ENCODING,
                point_cloud_range=self.point_cloud_range
            )
            self.data_augmentor = DataAugmentor(
                self.root_path, self.dataset_cfg.DATA_AUGMENTOR, self.class_names, logger=self.logger, pseudo=self.pseudo
            ) if self.training else None
            self.data_processor = DataProcessor(
                self.dataset_cfg.DATA_PROCESSOR, point_cloud_range=self.point_cloud_range, training=self.training
            )

            self.grid_size = self.data_processor.grid_size
            self.voxel_size = self.data_processor.voxel_size
            self.total_epochs = 0
            self._merge_all_iters_to_one_epoch = False

    @property
    def mode(self):
        return 'train' if self.training else 'test'

    def __getstate__(self):
        d = dict(self.__dict__)
        del d['logger']
        return d

    def __setstate__(self, d):
        self.__dict__.update(d)

    @staticmethod
    def generate_prediction_dicts(batch_dict, pred_dicts, class_names, output_path=None):
        """
        To support a custom dataset, implement this function to receive the predicted results from the model, and then
        transform the unified normative coordinate to your required coordinate, and optionally save them to disk.

        Args:
            batch_dict: dict of original data from the dataloader
            pred_dicts: dict of predicted results from the model
                pred_boxes: (N, 7), Tensor
                pred_scores: (N), Tensor
                pred_labels: (N), Tensor
            class_names:
            output_path: if it is not None, save the results to this path
        Returns:

        """

    def merge_all_iters_to_one_epoch(self, merge=True, epochs=None):
        if merge:
            self._merge_all_iters_to_one_epoch = True
            self.total_epochs = epochs
        else:
            self._merge_all_iters_to_one_epoch = False

    def __len__(self):
        raise NotImplementedError

    def __getitem__(self, index):
        """
        To support a custom dataset, implement this function to load the raw data (and labels), then transform them to
        the unified normative coordinate and call the function self.prepare_data() to process the data and send them
        to the model.

        Args:
            index:

        Returns:

        """
        raise NotImplementedError

    def prepare_data(self, data_dict):
        """
        Args:
            data_dict:
                points: (N, 3 + C_in)
                gt_boxes: optional, (N, 7 + C) [x, y, z, dx, dy, dz, heading, ...] (9+C)
                gt_names: optional, (N), string
                ...

        Returns:
            data_dict:
                frame_id: string
                points: (N, 3 + C_in)
                gt_boxes: optional, (N, 7 + C) [x, y, z, dx, dy, dz, heading, ...] (9+C)
                gt_names: optional, (N), string
                use_lead_xyz: bool
                voxels: optional (num_voxels, max_points_per_voxel, 3 + C)
                voxel_coords: optional (num_voxels, 3)
                voxel_num_points: optional (num_voxels)
                ...
        """
        if self.training:
            assert 'gt_boxes' in data_dict, 'gt_boxes should be provided for training'
            gt_boxes_mask = np.array([n in self.class_names for n in data_dict['gt_names']], dtype=np.bool_)

            data_dict = self.data_augmentor.forward(
                data_dict={
                    **data_dict,
                    'gt_boxes_mask': gt_boxes_mask
                }
            )
            if len(data_dict['gt_boxes']) == 0:
                new_index = np.random.randint(self.__len__())
                return self.__getitem__(new_index)
        # print("data_dict['gt_boxes'] ", data_dict['gt_boxes'] )

        if data_dict.get('gt_boxes', None) is not None:
            selected = common_utils.keep_arrays_by_name(data_dict['gt_names'], self.class_names)
            data_dict['gt_boxes'] = data_dict['gt_boxes'][selected]
            data_dict['gt_names'] = data_dict['gt_names'][selected]
            gt_classes = np.array([self.class_names.index(n) + 1 for n in data_dict['gt_names']], dtype=np.int32)
            # print("gt_classes", gt_classes)
            gt_boxes = np.concatenate((data_dict['gt_boxes'], gt_classes.reshape(-1, 1).astype(np.float32)), axis=1)
            data_dict['gt_boxes'] = gt_boxes

        # print("data_dict['gt_boxes'] after", data_dict['gt_boxes'] ) 7+ 1(class name idx)
        data_dict = self.point_feature_encoder.forward(data_dict)

        data_dict = self.data_processor.forward(
            data_dict=data_dict)
        # print("data_dict processor", data_dict)

        # if self.training:
        data_dict.pop('gt_names')

        return data_dict

    def _dict_select(self, dict_, inds):
        for k, v in dict_.items():
            if isinstance(v, dict):
                self._dict_select(v, inds)
            else:
                dict_[k] = v[inds]

    def prepare_data_nusc(self, input_dict,
                    voxel_generator=None,
                    max_voxels=20000,
                    remove_outside_points=False,
                    create_targets=True,
                    shuffle_points=False,
                    remove_unknown=False,
                    gt_rotation_noise=(-np.pi / 3, np.pi / 3),
                    gt_loc_noise_std=(1.0, 1.0, 1.0),
                    global_rotation_noise=(-np.pi / 4, np.pi / 4),
                    global_scaling_noise=(0.95, 1.05),
                    global_loc_noise_std=(0.2, 0.2, 0.2),
                    global_random_rot_range=(0.78, 2.35),
                    global_translate_noise_std=(0, 0, 0),
                    num_point_features=4,
                    anchor_area_threshold=1,
                    gt_points_drop=0.0,
                    gt_drop_max_keep=10,
                    remove_points_after_sample=True,
                    anchor_cache=None,
                    remove_environment=False,
                    random_crop=False,
                    reference_detections=None,
                    out_size_factor=2,
                    use_group_id=False,
                    multi_gpu=False,
                    min_points_in_gt=-1,
                    random_flip_x=True,
                    random_flip_y=True,
                    sample_importance=1.0,
                    out_dtype=np.float32,
                    with_velo=False):
        """convert point cloud to voxels, create targets if ground truths
        exists.

        input_dict format: dataset.get_sensor_data format

        """
        '''
        if self.training:
            assert 'gt_boxes' in data_dict, 'gt_boxes should be provided for training'
            gt_boxes_mask = np.array([n in self.class_names for n in data_dict['gt_names']], dtype=np.bool_)

            data_dict = self.data_augmentor.forward(
                data_dict={
                    **data_dict,
                    'gt_boxes_mask': gt_boxes_mask
                }
            )
            if len(data_dict['gt_boxes']) == 0:
                new_index = np.random.randint(self.__len__())
                return self.__getitem__(new_index)
        '''

        # if dataset_cfg.DATASET in ["KittiDataset", "LyftDataset"]:
        #     points = input_dict["lidar"]["points"]
        # elif dataset_cfg.DATASET == "NuScenesDataset":
        # print('dataset training', self.training)
        points = input_dict["points_combined"]
        gt_dict = {}
        # print("self.training", self.training)

        ################## add anno ################
        if self.training:
            if self.pseudo:
                anno_dict = input_dict["annotations_lidar"]
                gt_dict = {
                    "gt_boxes": input_dict["pseudo_boxes"],
                    "gt_names": np.array([self.index_to_class_names[i] for i in input_dict["pseudo_classes_filtered"]]),
                    "gt_classes": input_dict["pseudo_classes_filtered"],
                    "gt_importance": input_dict["pseudo_importance"],
                }

            else:
                anno_dict = input_dict["annotations_lidar"]
                gt_dict = {
                    "gt_boxes": anno_dict["boxes"],
                    "gt_names": anno_dict["names"],
                    "gt_importance": np.ones([anno_dict["boxes"].shape[0]], dtype=anno_dict["boxes"].dtype),
                }

                # print("out gtbox len", len(gt_dict['gt_boxes']))

                if "difficulty" not in anno_dict:
                    difficulty = np.zeros([anno_dict["boxes"].shape[0]],
                                        dtype=np.int32)
                    gt_dict["difficulty"] = difficulty
                else:
                    gt_dict["difficulty"] = anno_dict["difficulty"]
                if use_group_id and "group_ids" in anno_dict:
                    group_ids = anno_dict["group_ids"]
                    gt_dict["group_ids"] = group_ids

        ################## add calib, rgb2points ################
        calib = None
        if "calib" in input_dict:
            calib = input_dict["calib"]

        # if reference_detections is not None:
        #     assert calib is not None and "image" in input_dict
        #     C, R, T = box_utils.projection_matrix_to_CRT_kitti(calib["P2"])
        #     frustums = box_utils.get_frustum_v2(reference_detections, C)
        #     frustums -= T
        #     frustums = np.einsum('ij, akj->aki', np.linalg.inv(R), frustums)
        #     frustums = box_utils.camera_to_lidar(frustums, rect, Trv2c)
        #     surfaces = box_utils.corner_to_surfaces_3d_jit(frustums)
        #     masks = points_in_convex_polygon_3d_jit(points, surfaces)
        #     points = points[masks.any(-1)]

        # if remove_outside_points:
        #     assert calib is not None
        #     image_shape = input_dict["image"]["image_shape"]
        #     points = box_utils.remove_outside_points(
        #         points, calib["rect"], calib["Trv2c"], calib["P2"], image_shape)
        # if remove_environment is True and training:
        #     selected = common_utils.keep_arrays_by_name(gt_dict['gt_names'], self.class_names)
        #     self._dict_select(gt_dict, selected)
        #     masks = self.points_in_rbbox(points, gt_dict["gt_boxes"])
        #     points = points[masks.any(-1)]

        ################## select bbox samples ################
        if self.training and not self.pseudo:
            """
            boxes_lidar = gt_dict["gt_boxes"]
            bev_map = simplevis.nuscene_vis(points, boxes_lidar)
            cv2.imshow('pre-noise', bev_map)
            """
            selected = common_utils.drop_arrays_by_name(gt_dict["gt_names"], ["DontCare", "ignore"])
            self._dict_select(gt_dict, selected)

            if remove_unknown:
                remove_mask = gt_dict["difficulty"] == -1
                """
                gt_boxes_remove = gt_boxes[remove_mask]
                gt_boxes_remove[:, 3:6] += 0.25
                points = prep.remove_points_in_boxes(points, gt_boxes_remove)
                """
                keep_mask = np.logical_not(remove_mask)

                self._dict_select(gt_dict, keep_mask)

            gt_dict.pop("difficulty")
            if min_points_in_gt > 0:
                # points_count_rbbox takes 10ms with 10 sweeps nuscenes data
                point_counts = box_utils.points_count_rbbox(points, gt_dict["gt_boxes"])
                mask = point_counts >= min_points_in_gt
                self._dict_select(gt_dict, mask)

            gt_boxes_mask = np.array(
                [n in self.class_names for n in gt_dict["gt_names"]], dtype=np.bool_)

            gt_dict["gt_boxes_mask"] = gt_boxes_mask

            # need pseudo filter ?
            # else:
            #     pseudo_class_filter_mask = input_dict["pseudo_classes_filtered"] >= 0
            #     print("pseudo_class_filter_mask", pseudo_class_filter_mask)
            #     self._dict_select(gt_dict, pseudo_class_filter_mask)
            #     print("filtered")
            #     print("gt_dict", gt_dict)

            ###### mask classes ###########

            if self.data_augmentor is not None:

                group_ids = None
                if "group_ids" in gt_dict:
                    group_ids = gt_dict["group_ids"]
                # print("gt_dict before",gt_dict)

                gt_dict["points"] = points
                # print("initial gt_dict", gt_dict['points'].shape) #voxelization

                if len(gt_dict['gt_boxes']) == 0:
                    new_index = np.random.randint(self.__len__())
                    return self.__getitem__(new_index)

                gt_dict = self.data_augmentor.forward(
                    data_dict={
                        **gt_dict
                    }
                )
                # print("after autg gt_dict", gt_dict['points'].shape) #voxelization
                # print("gt_dict after",gt_dict)

                if len(gt_dict['gt_boxes']) == 0:
                    new_index = np.random.randint(self.__len__())
                    return self.__getitem__(new_index)

                # sampled_dict = db_sampler.sample_all( finish

            ####################### point feature encoder (Noise not included) ########################
                    # self.point_feature_encoder
            group_ids = None
            if "group_ids" in gt_dict:
                group_ids = gt_dict["group_ids"]

            gt_classes = np.array(
                [self.class_names.index(n) + 1 for n in gt_dict["gt_names"]], dtype=np.int32)
            gt_dict["gt_classes"] = gt_classes

            # res["lidar"]["annotations"] = gt_dict
            #################################################################################

            # gt_dict["gt_boxes"], points = prep.random_flip(gt_dict["gt_boxes"],
            #                                             points, 0.5, random_flip_x, random_flip_y)
            # gt_dict["gt_boxes"], points = prep.global_rotation_v2(
            #     gt_dict["gt_boxes"], points, *global_rotation_noise)
            # gt_dict["gt_boxes"], points = prep.global_scaling_v2(
            #     gt_dict["gt_boxes"], points, *global_scaling_noise)

            # gt_dict["gt_boxes"], points = prep.global_translate_(gt_dict["gt_boxes"], points, global_translate_noise_std)

            # bv_range = voxel_generator.point_cloud_range[[0, 1, 3, 4]]
            # mask = prep.filter_gt_box_outside_range_by_center(gt_dict["gt_boxes"], bv_range)
            # self._dict_select(gt_dict, mask)

            # limit rad to [-pi, pi] ???
            # gt_dict["gt_boxes"][:, 6] = self.limit_period(
            #     gt_dict["gt_boxes"][:, 6], offset=0.5, period=2 * np.pi)

            # boxes_lidar = gt_dict["gt_boxes"]
            # bev_map = simplevis.nuscene_vis(points, boxes_lidar)
            # cv2.imshow('post-noise', bev_map)
            # cv2.waitKey(0)
        # print("gt_dict['gt_boxes'] ", gt_dict['gt_boxes'] )

        ################## add class label ################

        if gt_dict.get('gt_boxes', None) is not None:
            if not self.pseudo:
                selected = common_utils.keep_arrays_by_name(gt_dict['gt_names'], self.class_names)
                gt_dict['gt_boxes'] = gt_dict['gt_boxes'][selected]
                gt_dict['gt_names'] = gt_dict['gt_names'][selected]
                gt_classes = np.array([self.class_names.index(n) + 1 for n in gt_dict['gt_names']], dtype=np.int32)
            else:
                # print("gt_dict[gt names]", gt_dict["gt_names"])
                selected = common_utils.drop_arrays_by_name(gt_dict["gt_names"], ["invalid"])
                fg_selected = common_utils.drop_arrays_by_name(gt_dict["gt_names"], ["invalid", "bg"])
                self._dict_select(gt_dict, selected)

                gt_classes = gt_dict['gt_classes']
            gt_boxes = np.concatenate((gt_dict['gt_boxes'], gt_classes.reshape(-1, 1).astype(np.float32)), axis=1)
            gt_dict['gt_boxes'] = gt_boxes
        else:
            fg_selected = []
            # print("gt_dict['gt_boxes']", gt_dict['gt_boxes'].shape)
        # print("gt_dict['gt_boxes'] after", gt_dict['gt_boxes'] ) 9 + 1(class name idx) might be used for segmentation.
        #
        if self.pseudo:
            # print("fg_selected", fg_selected)
            if len(fg_selected) == 0:
                # print("self.__len__()", self.__len__())
                new_index = np.random.randint(self.__len__())
                return self.__getitem__(new_index)
            gt_dict['pseudo_weights'] = gt_dict['gt_importance']

        if not self.training or self.pseudo:
            gt_dict["points"] = points

        # print("gt_dict", gt_dict)
        # print("initial gt_dict points before", gt_dict['points'].shape) #voxelization

        gt_dict = self.point_feature_encoder.forward(gt_dict)

        # print("gt_dict after", gt_dict)
        # print("initial gt_dict points after", gt_dict['points'].shape) #voxelization

        gt_dict = self.data_processor.forward(data_dict=gt_dict)

        ################## visualization label ################

        if not self.training and self.vis:
            anno_dict = input_dict["annotations_lidar"]
            gt_dict["gt_boxes"] = anno_dict["boxes"]
            gt_dict["gt_names"] = anno_dict["names"]

        # print("class_names", anno_dict["class_names"])
        # print("gt_names", gt_dict["gt_names"])

        # print("PRINTE")
        if self.points_range:
            # range_points = gt_dict["points"][:,:3]
            # zero = np.zeros(3)
            # points_range = np.array([np.linalg.norm(i-zero) for i in range_points])
            points_range = np.linalg.norm(gt_dict["points"][:, 0:3], axis=1)
            gt_dict['points_range'] = points_range
            # print("points_range", points_range[..., np.newaxis].shape)
            if self.range_feat:
                # print("gt_dict[ppoint]", gt_dict["points"].shape)
                gt_dict["points"] = np.concatenate((gt_dict["points"], points_range[..., np.newaxis]), axis=1)
                # print("gt_dict['points'] after", gt_dict["points"].shape)
                # print("last point in", gt_dict["points"][-1])
                # print("last range", points_range[-1])

        # get gt name only for visualization

        # print("gt_dict", gt_dict)
        if not self.training and self.vis:
            gt_dict.pop("gt_names")

        if not self.training:
            gt_dict['metadata'] = input_dict['metadata']

            return gt_dict

        gt_dict.pop('gt_names')

        return gt_dict

        ###########################
        #### Did not complete #####
        ###########################

        # if self.pseudo:
        #     print("data_dict processor psue", gt_dict.keys())
        #
        # train  gt_dict.keys())
        # 'gt_boxes', 'gt_names', 'gt_importance', 'points', 'gt_classes',
        # 'use_lead_xyz', 'voxels', 'voxel_coords', 'voxel_num_points'

        #voxelization
        # metrics = {}

        # # [0, -40, -3, 70.4, 40, 1]
        # voxel_size = voxel_generator.voxel_size
        # pc_range = voxel_generator.point_cloud_range
        # grid_size = voxel_generator.grid_size
        # # [352, 400]
        # if not multi_gpu:
        #     res = voxel_generator.generate(
        #         points, max_voxels)
        #     voxels = res["voxels"]
        #     coordinates = res["coordinates"]
        #     num_points = res["num_points_per_voxel"]
        #     num_voxels = np.array([voxels.shape[0]], dtype=np.int64)
        # else:
        #     res = voxel_generator.generate_multi_gpu(
        #         points, max_voxels)
        #     voxels = res["voxels"]
        #     coordinates = res["coordinates"]
        #     num_points = res["num_points_per_voxel"]
        #     num_voxels = np.array([res["voxel_num"]], dtype=np.int64)
        # metrics["voxel_gene_time"] = time.time() - t1
        # example = {
        #     'voxels': voxels,
        #     'num_points': num_points,
        #     'coordinates': coordinates,
        #     "num_voxels": num_voxels,
        #     "metrics": metrics,
        # }
        # if calib is not None:
        #     example["calib"] = calib
        # feature_map_size = grid_size[:2] // out_size_factor
        # feature_map_size = [*feature_map_size, 1][::-1]
        # if anchor_cache is not None:
        #     anchors = anchor_cache["anchors"]
        #     anchors_bv = anchor_cache["anchors_bv"]
        #     anchors_dict = anchor_cache["anchors_dict"]
        #     matched_thresholds = anchor_cache["matched_thresholds"]
        #     unmatched_thresholds = anchor_cache["unmatched_thresholds"]

        # else:
        #     ret = target_assigner.generate_anchors(feature_map_size)
        #     anchors = ret["anchors"]
        #     anchors = anchors.reshape([-1, target_assigner.box_ndim])
        #     anchors_dict = target_assigner.generate_anchors_dict(feature_map_size)
        #     anchors_bv = self.rbbox2d_to_near_bbox(
        #         anchors[:, [0, 1, 3, 4, 6]])
        #     matched_thresholds = ret["matched_thresholds"]
        #     unmatched_thresholds = ret["unmatched_thresholds"]
        # example["anchors"] = anchors
        # anchors_mask = None
        # if anchor_area_threshold >= 0:
        #     # slow with high resolution. recommend disable this forever.
        #     coors = coordinates
        #     dense_voxel_map = self.sparse_sum_for_anchors_mask(
        #         coors, tuple(grid_size[::-1][1:]))
        #     dense_voxel_map = dense_voxel_map.cumsum(0)
        #     dense_voxel_map = dense_voxel_map.cumsum(1)
        #     anchors_area = self.fused_get_anchors_area(
        #         dense_voxel_map, anchors_bv, voxel_size, pc_range, grid_size)
        #     anchors_mask = anchors_area > anchor_area_threshold
        #     # example['anchors_mask'] = anchors_mask.astype(np.uint8)
        #     example['anchors_mask'] = anchors_mask
        # print("prep time", time.time() - t)
        # metrics["prep_time"] = time.time() - t
        # print("transform_points_to_voxels", gt_dict)

        # print("gt_dict", gt_dict)

        # gt_dict["frame_id"] = input_dict["frame_id"]

        # assign target and anchors

        # if create_targets:
        #     # t1 = time.time()
        #     targets_dict = target_assigner.assign(
        #         anchors,
        #         anchors_dict,
        #         gt_dict["gt_boxes"],
        #         anchors_mask,
        #         gt_classes=gt_dict["gt_classes"],
        #         gt_names=gt_dict["gt_names"],
        #         matched_thresholds=matched_thresholds,
        #         unmatched_thresholds=unmatched_thresholds,
        #         importance=gt_dict["gt_importance"])

        #     """
        #     boxes_lidar = gt_dict["gt_boxes"]
        #     bev_map = simplevis.nuscene_vis(points, boxes_lidar, gt_dict["gt_names"])
        #     assigned_anchors = anchors[targets_dict['labels'] > 0]
        #     ignored_anchors = anchors[targets_dict['labels'] == -1]
        #     bev_map = simplevis.draw_box_in_bev(bev_map, [-50, -50, 3, 50, 50, 1], ignored_anchors, [128, 128, 128], 2)
        #     bev_map = simplevis.draw_box_in_bev(bev_map, [-50, -50, 3, 50, 50, 1], assigned_anchors, [255, 0, 0])
        #     cv2.imshow('anchors', bev_map)
        #     cv2.waitKey(0)

        #     boxes_lidar = gt_dict["gt_boxes"]
        #     pp_map = np.zeros(grid_size[:2], dtype=np.float32)
        #     voxels_max = np.max(voxels[:, :, 2], axis=1, keepdims=False)
        #     voxels_min = np.min(voxels[:, :, 2], axis=1, keepdims=False)
        #     voxels_height = voxels_max - voxels_min
        #     voxels_height = np.minimum(voxels_height, 4)
        #     # sns.distplot(voxels_height)
        #     # plt.show()
        #     pp_map[coordinates[:, 1], coordinates[:, 2]] = voxels_height / 4
        #     pp_map = (pp_map * 255).astype(np.uint8)
        #     pp_map = cv2.cvtColor(pp_map, cv2.COLOR_GRAY2RGB)
        #     pp_map = simplevis.draw_box_in_bev(pp_map, [-50, -50, 3, 50, 50, 1], boxes_lidar, [128, 0, 128], 1)
        #     cv2.imshow('heights', pp_map)
        #     cv2.waitKey(0)
        #     """
        #     example.update({
        #         'labels': targets_dict['labels'],
        #         'reg_targets': targets_dict['bbox_targets'],
        #         # 'reg_weights': targets_dict['bbox_outside_weights'],
        #         'importance': targets_dict['importance'],
        #     })

        # # give sample idx number
        # gt_dict['idx'] = input_dict['idx']

        # return example

    @staticmethod
    def collate_batch(batch_list, _unused=False):
        data_dict = defaultdict(list)

        for cur_sample in batch_list:
            for key, val in cur_sample.items():
                data_dict[key].append(val)
        batch_size = len(batch_list)
        ret = {}

        for key, val in data_dict.items():
            # print("key", key)
            # print("val", val)
            try:
                if key in ['voxels', 'voxel_num_points', 'points_range']:
                    ret[key] = np.concatenate(val, axis=0)
                elif key in ['points', 'voxel_coords']:
                    coors = []
                    for i, coor in enumerate(val):
                        coor_pad = np.pad(coor, ((0, 0), (1, 0)), mode='constant', constant_values=i)
                        coors.append(coor_pad)
                    ret[key] = np.concatenate(coors, axis=0)
                elif key in ['gt_boxes']:
                    max_gt = max([len(x) for x in val])
                    batch_gt_boxes3d = np.zeros((batch_size, max_gt, val[0].shape[-1]), dtype=np.float32)
                    for k in range(batch_size):
                        batch_gt_boxes3d[k, :val[k].__len__(), :] = val[k]
                    ret[key] = batch_gt_boxes3d
                elif key in ['gt_importance','gt_classes','pseudo_weights']:
                    ret[key] = np.concatenate(val, axis=0)
                else:
                    # if key == 'gt_names':
                    #     ret[key] = val.tolist()
                    ret[key] = np.stack(val, axis=0)

            except:
                print('Error in collate_batch: key=%s' % key)
                raise TypeError

        ret['batch_size'] = batch_size
        return ret

    # @staticmethod
    # def collate_batch_pseudo(batch_list, _unused=False):
    #     data_dict = defaultdict(list)

    #     for cur_sample in batch_list:
    #         for key, val in cur_sample.items():
    #             data_dict[key].append(val)
    #     batch_size = len(batch_list)
    #     ret = {}

    #     for key, val in data_dict.items():
    #         try:
    #             if key in ['voxels', 'voxel_num_points']:
    #                 ret[key] = np.concatenate(val, axis=0)
    #                 # sinlge val
    #                 # for i, coor in enumerate(val):
    #                 #     ret[f'{key}_single{i}'] = coor
    #             elif key in ['points', 'voxel_coords']:
    #                 coors = []
    #                 for i, coor in enumerate(val):
    #                     coor_pad = np.pad(coor, ((0, 0), (1, 0)), mode='constant', constant_values=i)
    #                     coors.append(coor_pad)
    #                     # sinlge val
    #                     # ret[f'{key}_single{i}'] = coor
    #                 ret[key] = np.concatenate(coors, axis=0)
    #             elif key in ['gt_boxes']:
    #                 max_gt = max([len(x) for x in val])
    #                 batch_gt_boxes3d = np.zeros((batch_size, max_gt, val[0].shape[-1]), dtype=np.float32)
    #                 for k in range(batch_size):
    #                     batch_gt_boxes3d[k, :val[k].__len__(), :] = val[k]
    #                 ret[key] = batch_gt_boxes3d
    #             elif key in ['gt_importance','gt_classes','pseudo_weights']:
    #                 ret[key] = np.concatenate(val, axis=0)
    #             else:
    #                 ret[key] = np.stack(val, axis=0)

    #         except:
    #             print('Error in collate_batch: key=%s' % key)
    #             raise TypeError

    #         # if key == 'points':
    #         #     print('after key', ret[key].shape)
    #         # print('after val', len(val))
    #         # print('after ret[key]', ret[key].shape)

    #     ret['batch_size'] = batch_size
    #     return ret


from flask_cors import CORS, cross_origin
from flask import Flask, request, render_template
import requests
from googletrans import Translator

app = Flask(__name__, template_folder='templates')
cors = CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'

translator = Translator(service_urls=['translate.googleapis.com'])
old_mess = ""

@app.route("/")
@cross_origin()
def index():
    return render_template("index.html")

@app.route("/api", methods=['POST'])
@cross_origin()
def main():
    global old_mess
    contents = request.json
    webhook = "https://discord.com/api/webhooks/935794459839459338/q13g2ISGnr5WfOxdAqyAZ3_u5fDW5CwHDX-bSrpQL7eW0jB61BzZBnmHI1-HroEZUNMf"
    username = "Stupid bot"
    avatar_url = "https://pics.me.me/lm-a-stupid-bot-me-irl-34192545.png"
    # content = contents["content"] + \
    #    " ||Sent by https://dinhgiabao.codes/control_agof.html||"
    content = contents["content"]

    trans = translator.translate(content, dest="en")
    content = trans.text

    result = content.lower()

    #swearing = ["fuck", "dm", "mje", "ƒuck",
    #            "|<", "|=", "dit", "xuka blyat", "djt", "d1t", "dpt", "lon", "@hat suck", "hat suck", "f#ck", "địt", "lồn", "bitch", "fck", "f*ck","f u c k","b i t c h"]

    swearing =["hat","h a t","h at", "ha t"]
    for word in swearing:
        if word in result:
            content ="Hat insult detect :)"

    data = {'username': username,
            'avatar_url': avatar_url,
            'content': content, }

    if(old_mess != contents["content"]):
        r = requests.post(url=webhook, data=data)

    old_mess = contents["content"]
    return "ok"

if __name__ == '__main__':
    app.run()


import numpy as np
import pandas as pd
import pickle
from glob import glob
from os.path import join
from scipy import signal
from scipy import interpolate
from decim.adjuvant import slurm_submit as slu
from datetime import datetime

def fill_nan(A, kind='linear'):
    '''
    Interpolate to fill nan values
    INPUT: np.array of data series to interpolate np.nan values
    ARGUMENTS:
        - kind= 'linear' oder 'cubic'
    '''
    inds = np.arange(A.shape[0])
    good = np.where(np.isfinite(A))
    f = interpolate.interp1d(inds[good], A[good], bounds_error=False,
                             kind=kind)
    B = np.where(np.isfinite(A), A, f(inds))
    return B

def interpol(pupil, nan_locs=False, valid=[], kind='linear'):
    '''
    Do interpolation of np.nan values; extrapolate at start and end
    INPUT: Pupil array to be interpolated as np.array astype float
    ARGUMENTS:
        - nan_locs: True when array with valid samples is given,
        otherwise just interpolate the pupil array
        - valid: np.array of same length as pupil;
                    invalid samples FALSE & valid samples TRUE
        - kind: 'linear' or 'cubic' interpolation
    OUTPUT: array with interpolated pupil data
    '''
    if nan_locs is True:
        pupil[np.where(~valid)] = np.nan
    interp = fill_nan(pupil, kind=kind)
    interp = pd.DataFrame(interp).fillna(method='ffill')[0].values      # NaN at the end ffilled
    interp = pd.DataFrame(interp).fillna(method='bfill')[0].values      # NaN at the beginning bfilled
    return interp

    def margin(array, margin1=50, margin2=50, threshhold=50, op='larger'):
        '''
        Detect fragments of invalid samples of certain length,
        mark surrounding samples as invalid
        INPUT: boolean np.array; valid samples True & invalid samples FALSE
        ARGUMENTS:
            - margin 1: margin before fragment
            - margin 2: margin after fragment
            - threshhold: length of fragment of invalid samples
            - op: 'larger' or 'smaller'; how to use threshhold
        OUTPUT: boolean np.array; valid samples True & invalid samples FALSE
        '''
        convolved = np.convolve(array, [0.5, 1], 'same')                    # convolution marks begin of True-series with 0.5 and end of True-series with 1
        ev_start = np.where(convolved == .5)[0]
        fragment_ends = ev_start
        if convolved[0] != 0:
            fragment_ends = fragment_ends[1:len(fragment_ends)]
        if convolved[len(convolved) - 1] == 0:
            fragment_ends = np.append(fragment_ends, len(array))
        ev_end = np.where(convolved == 1)[0]
        if convolved[0] == 0:
            fragment_starts = np.append(0, ev_end)
        else:
            fragment_starts = ev_end
        if convolved[-1] == 1:
            fragment_starts = fragment_starts[0:-1]
        assert len(fragment_ends) == len(fragment_starts)
        fragment_length = fragment_ends - fragment_starts
        if op == 'larger':
            wh = np.where(fragment_length > threshhold)
        elif op == 'smaller':
            wh = np.where(fragment_length <= threshhold)
        smallfrag_ends = fragment_ends[wh]
        smallfrag_starts = fragment_starts[wh]
        for start, end in zip(smallfrag_starts, smallfrag_ends):
            array[start - margin1:start] = False
            array[end:end + margin2] = False
        return array

def islands(array, threshhold=200):
    '''
    Detects leftover fragments smaller than threshhold.

    Sets those detected fragments to NaN to make linear interpolation cleaner.
    '''
    convolved = np.convolve(array, [0.5, 1], 'same')
    ev_start = np.where(convolved == .5)[0]
    fragment_ends = ev_start
    if convolved[0] != 0:
        fragment_ends = fragment_ends[1:len(fragment_ends)]
    if convolved[len(convolved) - 1] == 0:
        fragment_ends = np.append(fragment_ends, len(array))
    ev_end = np.where(convolved == 1)[0]
    if convolved[0] == 0:
        fragment_starts = np.append(0, ev_end)
    else:
        fragment_starts = ev_end
    if convolved[-1] == 1:
        fragment_starts = fragment_starts[0:-1]
    assert len(fragment_ends) == len(fragment_starts)
    fragment_length = fragment_ends - fragment_starts
    wh = np.where(fragment_length < threshhold)
    smallfrag_ends = fragment_ends[wh]
    smallfrag_starts = fragment_starts[wh]
    for start, end in zip(smallfrag_starts, smallfrag_ends):
        array[start:end + 1] = False
    return array

def velocity(df, unit, time):
    f = np.abs((df[unit].values - np.roll(df[unit].values, -1)) /
               (df[time].values - np.roll(df[time].values, -1)))
    b = np.abs((df[unit].values - np.roll(df[unit].values, 1)) /
               (df[time].values - np.roll(df[time].values, 1)))
    return np.maximum(f, b)

def lowpass(array, cutoff=4, freq=125):

    lp_cof_sample = cutoff / (freq / 2)                                 # low pass
    blp, alp = signal.butter(3, lp_cof_sample)
    filtered = signal.filtfilt(blp, alp, array)
    return filtered

class PupilFrame(object):

    def __init__(self, subject, group, session, run,
                 directory='/Volumes/XKCD/PSP', out_dir=''):
        '''
        Initialize
        --------------------------------------------------------------
        ARGUMENTS:
        - subject: e.g. '001'
        - group: 'patient'
        - session: 'Baseline' / 'Followup'
        - run: '000', etc.
        - directory: e.g. '/Volumes/XKCD/PSP'
        '''
        self.subject = subject
        self.group = group
        self.session = session
        self.run = run
        self.directory = directory
        self.pupil = {}
        self.parameters = {}
        if out_dir == '':
            self.out_dir = join(self.directory, 'Pupil_Preprocessed_{}'.
                                format(datetime.now().strftime("%Y-%m-%d")))
        else:
            self.out_dir = join(out_dir, 'Pupil_Preprocessed_{}'.
                                format(datetime.now().strftime("%Y-%m-%d")))
        slu.mkdir_p(self.out_dir)

    def load_pupil(self):
        '''
        Load pupil data and discard irrelevant data.
        '''
        path = glob(join(self.directory, 'raw_data', self.subject,
                         '20*_PSP_{0}_{1}'.format(self.subject,
                                                  self.session),
                         self.run, 'pupil_data'))

        with open(path[0], 'rb') as f:
            file = pickle.load(f, encoding="latin-1")
        df = pd.DataFrame(file['pupil_positions'])
        self.pupil['left'] = df.loc[df.id == 0].drop(['norm_pos',
                                                      'ellipse',
                                                      'method'], axis=1)
        self.pupil['right'] = df.loc[df.id == 1].drop(['norm_pos',
                                                       'ellipse',
                                                       'method'], axis=1)

    def cut(self, side, n=3):
        '''
        Discard frames at begin and end of pupil data
        ARGUMENTS:
            - pupil side
            - length of margin in seconds
        '''
        self.pupil[side]
        m = n * 125
        self.pupil[side] = self.pupil[side].iloc[m:-m]

    def discard_basic(self, side, conf_cutoff=.9, d_cutoff=.98):
        '''

        '''
        df = self.pupil[side]
        df.loc[:, 'diameter_conf'] = df.diameter.copy()
        df.loc[df.confidence < conf_cutoff, 'diameter_conf'] = np.nan
        df.loc[df.diameter.abs() > df.diameter.abs().quantile(d_cutoff),
               'diameter_conf'] = np.nan
        self.pupil[side] = df

    def discard_velocity(self, side, n=1):
        df = self.pupil[side]
        df.loc[:, 'timestamp'] = \
            (df.timestamp - df.timestamp.values[0]) * 1000
        df.loc[:, 'dilation_speed'] = velocity(df, unit='diameter',
                                               time='timestamp')
        velo = df.dilation_speed.values
        median = df.dilation_speed.quantile(.5)
        MAD = np.median(np.abs(velo - median))
        threshhold = median + n * MAD
        df.loc[:, 'diameter_velo'] = df['diameter_conf'].copy()
        df.loc[df.dilation_speed > threshhold, 'diameter_velo'] = np.nan
        self.pupil[side] = df

    def interp1(self, side, sample_rate=125, margins=[7, 50],
                margin_threshhold=20, island_threshhold=25, lpf=4):
        df = self.pupil[side]
        df.loc[:, 'margins'] = ~df.diameter_velo.isnull()
        print(df.margins.mean())
        df.loc[:, 'margins'] = margin(df.loc[:, 'margins'].values,
                                      margin1=margins[0],
                                      margin2=margins[1],
                                      threshhold=margin_threshhold)
        print(df.margins.mean())
        df.loc[:, 'margins'] = islands(df.loc[:, 'margins'].values,
                                       threshhold=island_threshhold)
        print(df.margins.mean())
        df.loc[:, 'interpolated'] = interpol(pupil=df.diameter.copy().values,
                                             nan_locs=True,
                                             valid=df.margins.values,
                                             kind='linear')

        df.loc[:, 'filtered'] = lowpass(df['interpolated'], cutoff=lpf)
        self.pupil[side] = df

    def repeat(self, side, i, n=2.5, margins=[7, 50],
               margin_threshhold=20, island_threshhold=2, lpf=4):
        df = self.pupil[side]
        if i == 0:
            filtered = df['filtered']
        else:
            filtered = df['filtered_{}'.format(i - 1)]

        trend_diff = df['diameter_velo'] - filtered
        median = trend_diff.quantile(.5)
        MAD = np.median((trend_diff - median).abs().quantile(.5))
        threshhold = median + n * MAD
        df.loc[:, 't'] = trend_diff
        df.loc[:, 'td'] = df['diameter_velo'].copy()
        df.loc[df.t.abs() > threshhold, 'td'] = np.nan
        trend_line_dev = df['td'].values
        marg = ~np.isnan(trend_line_dev)
        marg = margin(marg, margin1=margins[0], margin2=margins[1],
                      threshhold=margin_threshhold)
        marg = islands(marg, threshhold=island_threshhold)
        print(1 - df['diameter_velo'].isnull().mean(),
              np.mean(~np.isnan(trend_line_dev)),
              np.mean(marg))
        df.loc[:, 'interpolated_{}'.format(i)] =\
            interpol(pupil=df.diameter.copy().values,
                     nan_locs=True, valid=marg,
                     kind='linear')
        df.loc[:, 'filtered_{}'.format(i)] = \
            lowpass(df['interpolated_{}'.format(i)].values, cutoff=lpf)
        self.pupil[side] = df

    def highpass(self, side, highpass=.01, sample_rate=125):
        '''
        Apply 3rd-order Butterworth highpass filter.
        '''

        sig = self.pupil[side].loc[:, 'filtered_19']                        # High pass:
        hp_cof_sample = highpass / (sample_rate / 2)
        bhp, ahp = signal.butter(3, hp_cof_sample, btype='high')
        highpassed = signal.filtfilt(bhp, ahp, sig)
        self.pupil[side]['highpass'] = highpassed

    def normalize(self, side):
        '''
        z-score
        '''
        sig = self.pupil[side].loc[:, 'highpass']
        self.pupil[side]['biz'] = (sig - sig.mean()) / sig.std()

    def save(self):

        for side in ['left', 'right']:
            self.pupil[side].\
                to_hdf(join(self.out_dir, 'Pupil_Preprocessed_SUB-{0}_{1}_{2}.hdf'.
                            format(self.subject,
                                   self.session,
                                   self.run)), key=side)

def execute(subject, group, session, run, directory='/Volumes/XKCD/PSP',
            velocity_threshhold=1, trendline_threshhold=2.5, lpf=4,
            margins=[7, 50], margin_threshhold=20, island_threshhold=25,
            cut_frames=3, conf_cutoff=.9, d_cutoff=.98, ret=False, out_dir=''):
    p = PupilFrame(subject, group, session, run, directory, out_dir=out_dir)
    try:
        p.load_pupil()
        for side in ['left', 'right']:
            p.cut(side=side, n=cut_frames)
            p.discard_basic(side=side, conf_cutoff=conf_cutoff,
                            d_cutoff=d_cutoff)
            p.discard_velocity(side=side, n=velocity_threshhold)
            p.interp1(side=side, margins=margins,
                      margin_threshhold=margin_threshhold,
                      island_threshhold=island_threshhold, lpf=lpf)
            for i in range(20):
                p.repeat(i=i, side=side, n=trendline_threshhold,
                         margins=margins,
                         margin_threshhold=margin_threshhold,
                         island_threshhold=island_threshhold, lpf=lpf)
            p.highpass(side=side)
            p.normalize(side=side)
        p.save()
        if ret is True:
            return(p.pupil)
    except IndexError:
        print('File Error for', subject, session, run)  # glob finds no files

'''
Test code:

subject = '001'
group = 'patient'
session = 'Baseline'
run = '000'
execute(subject, group, session, run)

V.1.0.1
Second pupil preprocessing script for PSP dataset
'''


import time
import pprint  # Useful for debug.
import sys
import sqlite3

from flask import *

pp = pprint.PrettyPrinter(indent=4)

messenger = Blueprint("messenger", __name__)  # Main page

def add_message(result):
    conn = sqlite3.connect("/var/www/jforseth.tech/database.db")
    cur = conn.cursor()
    with conn:
        cur.execute("INSERT INTO messages VALUES(:result)", {"result": result})

def read_messages():
    conn = sqlite3.connect("/var/www/jforseth.tech/database.db")
    cur = conn.cursor()
    cur.execute("SELECT * FROM messages")
    return cur.fetchall()

def clear_messages():
    conn = sqlite3.connect("/var/www/jforseth.tech/database.db")
    cur = conn.cursor()
    with conn:
        cur.execute("DELETE FROM messages")
        if sys.version_info[0] == 3:
            cur.execute("END TRANSACTION")
        #cur.execute("VACUUM")

@messenger.route("/messenger")
def messenger_main_page():
    messages = read_messages()
    messages = ["".join(i) for i in messages]
    return render_template("messenger/messenger.html", result=messages)

# When the user sends a message, it goes here.
@messenger.route("/messenger/result", methods=["POST", "GET"])
def new_message():
    if request.method == "POST":
        message = escape(request.form.get("message"))
        add_message(message)

    return redirect("/messenger")

@messenger.route("/message/stream")
def message_stream():
    def eventStream():
        previous_messages = read_messages()
        while True:
            time.sleep(10)
            messages = read_messages()

            if previous_messages != messages:
                previous_messages = messages
                formatted_messages = ["".join(i) for i in messages]

                yield "data: {}\n\n".format(formatted_messages[-1])

    return Response(eventStream(), mimetype="/var/www/jforseth.tech/text/event-stream")

@messenger.route("/messenger/clear", methods=["POST", "GET"])
def clear_all_messages():
    clear_messages()
    return redirect("/messenger")


from collections import deque

def solution(tickets):
    answer = []
    send = []
    for ticket in tickets:
        a_sub_b = [x for x in tickets if x not in ticket]
        if ticket[0] == "ICN":
            send.append([ticket, a_sub_b])
    print(send)

    bfs(tickets, send)
    return answer

# 출발지 도착지 없이 리스트 통채로 넣기
def bfs(tickets, root):
    visited = []
    queue = deque()
    queue.append(root)

    while queue:
        print(queue.popleft())
        nowticket, leftticket = queue.popleft()
        templist = []
        for ticket in leftticket:
            a_sub_b = [x for x in leftticket if x not in ticket]
            if nowticket[1] == ticket[0]: # 중복 방문 가능하다는 점에서 수정 필요
                templist.append([ticket, a_sub_b])

        queue.append(templist)

        answer = []
        for visit in visited:
            answer.append(visit[0])

    return answer

print(solution([["ICN", "SFO"], ["ICN", "ATL"], ["SFO", "ATL"], ["ATL", "ICN"], ["ATL","SFO"]]))


import numpy as np
import random

class Route:
    def __init__(self, path_matrix, start_city, route = None):
        self.path_matrix = path_matrix
        self.num_cities = len(path_matrix)
        self.start_city = start_city
        if route is not None:
            self.route = route
        else:
            self.route = [start_city]
            remaining_cities = list(range(self.num_cities))
            remaining_cities.remove(start_city)
            self.route.extend(random.sample(remaining_cities, self.num_cities - 1))

    def fitness(self):
        total_distance = 0

        for i in range(self.num_cities - 1):
            from_city = self.route[i]
            to_city = self.route[i + 1]
            total_distance += self.path_matrix[from_city][to_city]

        total_distance += self.path_matrix[self.route[-1]][self.start_city]

        return total_distance

    def crossover(self, other):
        start = random.randint(0, self.num_cities - 1)
        end = random.randint(start, self.num_cities)

        selected = self.route[start:end]

        remaining = [city for city in other.route if city not in selected]

        new_route = remaining[:start] + selected + remaining[start:]

        return Route(self.path_matrix, self.start_city, new_route)

    def mutate(self):
        index1, index2 = random.sample(range(self.num_cities), 2)
        self.route[index1], self.route[index2] = self.route[index2], self.route[index1]

def genetic_algorithm(path_matrix, start_city, population_size, generations, mutation_rate):
    population = [Route(path_matrix, start_city) for _ in range(population_size)]

    for generation in range(generations):
        population = sorted(population, key=lambda route: route.fitness())
        new_population = population[:population_size // 2]

        while len(new_population) < population_size:
            parent1, parent2 = random.sample(population, 2)
            child = parent1.crossover(parent2)
            if random.random() < mutation_rate:
                child.mutate()

            new_population.append(child)

        population = new_population

    best_path = min(population, key=lambda route: route.fitness())

    return best_path

# random seeds for consistency (no specific reason for the numbers, I just mashed my keyboard)
np.random.seed(43274932)
random.seed(98346276)

# Weighted adjacency matrix of the graph
graph = np.array([
    [float('inf'), 12, 10, float('inf'), float('inf'), float('inf'), 12],
    [12, float('inf'), 8, 12, float('inf'), float('inf'), float('inf')],
    [10, 8, float('inf'), 11, 3, float('inf'), 9],
    [float('inf'), 12, 11, float('inf'), 11, 10, float('inf')],
    [float('inf'), float('inf'), 3, 11, float('inf'), 6, 7],
    [float('inf'), float('inf'), float('inf'), 10, 6, float('inf'), 9],
    [12, float('inf'), 9, float('inf'), 7, 9, float('inf')]
])

# Specifying the city we start at
start_city = 0

best_route = genetic_algorithm(graph, start_city, population_size=100, generations=1000, mutation_rate=0.1)

print("Best route:", best_route.route)
print("Best route distance:", best_route.fitness())


from selenium import webdriver
import time
#from selenium.webdriver.support.ui import Select

link = "http://suninjuly.github.io/selects1.html"
browser = webdriver.Chrome()
browser.get(link)

def open1():
    try:
        time.sleep(1)
        num1 = browser.find_element_by_id('num1')
        num1el = num1.text
        num2 = browser.find_element_by_id('num2')
        num2el = num2.text
        sumselector = int(num1el) + int(num2el)
        print(sumselector)
        select = browser.find_elements_by_tag_name('select')
        select[0].click()
        browser.find_element_by_css_selector(f'[value = "{sumselector}"]').click()
        button = browser.find_elements_by_tag_name('button')
        button[0].click()

    finally:
        # ожидание чтобы визуально оценить результаты прохождения скрипта
        time.sleep(5)
        # закрываем браузер после всех манипуляций
        browser.quit()

open1()


name = 0
name3 = []
namein = 0
name = input("세글자 입력 : ")
def sam():
    for word in name:
        namein = input(f"word : ")
        while True:
            if word == namein[0]:
                name3.append(namein)
                break
            else:
                    print("다시")
    print("*" * 20)
    print(f"{name}")
    for n in range(len(name)):
        print(f"{name[n]} : {name3[n]}")
    print("*" * 20)
    return name3
f = open("event.txt", "a", encoding = "UTF-8")
for word in sam():
    f.write(word + "\n")
f.close()


#coding:utf-8

"""
ID:          issue-5581
ISSUE:       5581
TITLE:       Regression: Can not restore database with table contains field CHAR(n) and UTF8 character set
DESCRIPTION:
  We make initial DDL and DML using ISQL with connection charset = UTF8, and then run b/r.
  Ouput of restore is filtered so that only lines with 'ERROR' word can be displayed.
  This output should be EMPTY (i.e. no errors should occur).
JIRA:        CORE-5304
FBTEST:      bugs.core_5304
"""

import pytest
from pathlib import Path
from firebird.qa import *

init_script = """
    recreate table test(c char(10));
    commit;
    insert into test values(null);
    commit;
"""

db = db_factory(charset='UTF8', init=init_script)

act = python_act('db')

fbk_file = temp_file('tmp_core_5304.fbk')
fdb_file = temp_file('tmp_core_5304.fdb')

@pytest.mark.version('>=4.0')
def test_1(act: Action, fbk_file: Path, fdb_file: Path):
    with act.connect_server() as srv:
        srv.database.backup(database=act.db.db_path, backup=fbk_file)
        srv.wait()
        srv.database.restore(backup=fbk_file, database=fdb_file)
        srv.wait()


'Version of python-feedgen represented as tuple'
version = (0, 9, 0)

'Version of python-feedgen represented as string'
version_str = '.'.join([str(x) for x in version])

version_major = version[:1]
version_minor = version[:2]
version_full = version

version_major_str = '.'.join([str(x) for x in version_major])
version_minor_str = '.'.join([str(x) for x in version_minor])
version_full_str = '.'.join([str(x) for x in version_full])


# -*- coding:utf-8 -*-
"""
@author:Xiaoping
@file:python_study_0109.py
@time:2017/9/2  16:09
"""
#选票计算
while True:
    try:
        n = int(raw_input().strip())
        voteds = raw_input().strip().split(' ')
        m = int(raw_input().strip())
        votes = raw_input().strip().split(' ')
        dicvoteds = {}
        for name in voteds:
                dicvoteds[name] = 0
        notvotedname = []
        for name in votes:
            if name in dicvoteds:
                dicvoteds[name] += 1
            else:
                notvotedname.append(name)
        for name in voteds:
            print('%s : %d' % (name, dicvoteds.get(name)))
        print('Invalid : %d' % len(notvotedname))
    except:
        break


from game.console import Console
from game.interact import Interact
from game.jumper import Jumper
from game.word_bank import WordBank

class Director:
    """
    Stereotype:
        Controller
    """
    def __init__(self):
        """
        The class constructor.
        Args:
            self (Director): an instance of Director.
        """
        self.console = Console()
        self.jumper = Jumper()
        self.interact = Interact()
        self.word_bank = WordBank()
        self.keep_playing = True
        self.user_guess = ""
        self.word = self.word_bank.words
        self.blank_word = self.interact.get_blank_word(self.word)

    def start_game(self):
        """
        Starts the game loop to control the sequence of play.
        Args:
            self (Director): an instance of Director.
        """
        while self.keep_playing:
            self.get_inputs()
            self.do_updates()
            self.do_outputs()

    def get_inputs(self):
        """
        Gets the inputs at the beginning of each round of play.
        Args:
            self (Director): An instance of Director.
        """
        self.console.write(self.blank_word)
        jumper_display = self.jumper.display_jumper()
        self.console.write(jumper_display)
        self.user_guess = self.interact.get_guess()

    def do_updates(self):
        """
        Updates the important game information for each round of play.
        Args:
            self (Director): An instance of Director.
        """
        if self.jumper.correct_guess(self.user_guess, self.word):
            self.blank_word = self.interact.add_letter(self.user_guess, self.blank_word, self.word)
        else:
            self.jumper.lives -= 1

    def do_outputs(self):
        """
        Outputs the important game information for each round of play.
        Args:
            self (Director): An instance of Director.
        """
        if self.jumper.lives == 0:
            jumper_display = self.jumper.display_jumper()
            self.console.write(jumper_display)
            self.console.write(f"The word was \'{self.word}\' You Lose!")
            self.keep_playing = False
        elif not self.interact.check_win(self.blank_word):
            jumper_display = self.jumper.display_jumper()
            self.console.write(jumper_display)
            self.keep_playing = False
            self.console.write(f"The word was \'{self.word}\' You Win!")


def fibonacci(n):
    '''calculate Fibonacci series'''
    if n < 0:
        return []
    else:
        gen = fibonacci_gen()
        return [next(gen) for _ in range(n)]

def fibonacci_gen():
    '''Generate Fibonacci elements from the first position'''
    now = 0
    next_ = 1
    while True:
        yield now
        now, next_ = next_, now + next_


import requests
from grpc import StatusCode
from google.protobuf.json_format import MessageToDict
from google.protobuf.struct_pb2 import Struct
import json
from nuance.dlg.v1.common.dlg_common_messages_pb2 import *
from nuance.dlg.v1.dlg_messages_pb2 import *
from nuance.dlg.v1.dlg_interface_pb2_grpc import *
import time
import re
import os

class session_start:
    def __init__(self, config):
        self.log_list = []
        self.log_dict = {}
        self.payload_dict = None
        self.selector_dict = None
        self.project_data = None
        self.model_ref_dict = None
        self.response = {}
        self.request = {}
        self.session_started = False
        self.token = None
        self.channel = None
        self.text = None
        self.got_init_data = False
        self.config = config
        self.session_id = None
        self.logs_folder = "logs"
        self.got_token = False
        self.project_config = {"auth_url": "https://auth.crt.nuance.com/oauth2/token",
                               "serverUrl": "dlg.api.nuance.com:443",
                               "nlu_uri": "nlu.api.nuance.com:443", "client_id": None, "secret": None, "modelUrn": None,
                               "scope": "dlg", "channel": "default", "language": "en-US", "sleep": "1"}

    def get_setup_data(self):
        config = self.config
        project_config = self.project_config
        if config:
            try:
                config_file_contents = open(config)
                config_json = json.load(config_file_contents)
                config_file_contents.close()
            except Exception as e:
                self.response = {f'errorMessage: get_setup_data failed at: {e}'}
                return

            for key, value in config_json.items():
                if key in project_config.keys() and value != None and str(value).strip() != "":
                    project_config[key] = value

        for key, value in project_config.items():
            if key == "client_id":
                if ":" in str(project_config[key]):
                    project_config[key] = str(project_config[key]).replace(":", "%3A")
            if key == "secret":
                project_config[key] = str(project_config[key]).replace("'", "")

        if project_config["client_id"] is None or project_config["secret"] is None or project_config[
            "modelUrn"] is None:
            self.response = {"errorMessage: config if not setup, client_id,"
                             "secret,dlg_modelUrn and nlu_modelUrn are required"}
        else:
            self.got_init_data = True
        self.project_data = project_config

        self.model_ref_dict = {
            "uri": self.project_data["modelUrn"],
            "type": 0
        }
        self.selector_dict = {
            "channel": self.project_data["channel"],
            "language": self.project_data["language"],
            "library": "default"
        }

    def __enter__(self):
        self.get_setup_data()
        if self.got_init_data:
            self.get_token()
            if self.got_token == True:
                self.connect()
                self.stub = DialogServiceStub(self.channel)
                self.start_request()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.session_started and "errorMessage" not in str(self.status_request()):
            self.stop_request()

    def get_token(self):
        payload = {"grant_type": "client_credentials", "scope": self.project_data["scope"]}
        self.request = {"auth_url": self.project_data["auth_url"], "client_id": self.project_data["client_id"]}
        try:
            response = requests.post(self.project_data["auth_url"],
                                     auth=(self.project_data["client_id"], self.project_data["secret"]),
                                     data=payload)
            response.json()["access_token"]
            self.token = response.json()["access_token"]
            self.response = {"access_token": "*****"}
            self.got_token = True
        except Exception as e:
            self.response = {f'errorMessage: get_token failed check client_credentials: {e}'}

    def text_payload(self):
        if self.text is not None:
            return {"user_input": {"userText": self.text}}
        else:
            return {"user_input": {"userText": None}}

    def connect(self):
        self.response = "connect"
        try:
            call_credentials = grpc.access_token_call_credentials(self.token)
            channel_credentials = grpc.ssl_channel_credentials()
            channel_credentials = grpc.composite_channel_credentials(channel_credentials, call_credentials)
            channel = grpc.secure_channel(self.project_data["serverUrl"], credentials=channel_credentials)
            self.channel = channel
        except grpc.RpcError as e:
            self.response = {"errorMessage": "gRPC error at connect",
                             "RpcError": str(e)}

    def start_request(self):
        requestName = "start_request"
        session_id = None
        time.sleep(int(self.project_data.get('sleep')))
        selector = Selector(channel=self.selector_dict.get('channel'),
                            library=self.selector_dict.get('library'),
                            language=self.selector_dict.get('language'))
        start_payload = StartRequestPayload(model_ref=self.model_ref_dict)
        self.request = {"selector_dict": self.selector_dict,
                        "model_ref_dict": self.model_ref_dict}
        try:
            start_req = StartRequest(session_id=session_id,
                                     selector=selector,
                                     payload=start_payload)

            start_response, call = self.stub.Start.with_call(start_req)
            assert call.code() == StatusCode.OK
            response = MessageToDict(start_response)
            self.session_id = response.get('payload').get('sessionId')
            self.response = response
            self.session_started = True
        except grpc.RpcError as e:
            self.response = {"errorMessage": "gRPC error at start_request:",
                             "RpcError": str(e)}
        write_to_log(self.session_id, self.request, self.response,self.logs_folder,requestName)

    def start(self, expected=None):
        self.execute_request()
        assert_dlg(expected, self.response)

    def update_request(self, data):
        requestName = "update_request"
        data_struct = Struct()
        data_struct.update(data)
        try:
            update_payload = UpdateRequestPayload(data=data_struct)
            update_req = UpdateRequest(session_id=self.session_id, payload=update_payload)
            self.request = {"session_id": self.session_id,
                        "data": data}
            update_response, call = self.stub.Update.with_call(update_req)
            assert call.code() == StatusCode.OK
            response = MessageToDict(update_response)
            self.response = response
        except grpc.RpcError as e:
            self.response = {"errorMessage": "gRPC error at start_request:",
                             "RpcError": str(e)}
        write_to_log(self.session_id, self.request, self.response,self.logs_folder,requestName)

    def execute_request(self, text=None, expected=""):
        requestName = "execute_request"
        if not self.got_init_data  or self.got_token == False:
            return
        if text is not None:
            self.text = text
        self.payload_dict = self.text_payload()
        time.sleep(int(self.project_data.get('sleep')))
        selector = Selector(channel=self.selector_dict.get('channel'),
                            library=self.selector_dict.get('library'),
                            language=self.selector_dict.get('language'))
        input = UserInput(user_text=self.payload_dict.get('user_input').get('userText'))
        self.request = {"selector_dict": self.selector_dict, "payload_dict": self.payload_dict}
        if 'errorMessage' not in str(self.response):
            try:
                execute_payload = ExecuteRequestPayload(
                    user_input=input)
                execute_request = ExecuteRequest(session_id=self.session_id,
                                                 selector=selector,
                                                 payload=execute_payload)
                execute_response, call = self.stub.Execute.with_call(execute_request)
                assert call.code() == StatusCode.OK
                self.response = MessageToDict(execute_response)
            except grpc.RpcError as e:
                self.response = {"errorMessage": "gRPC error at execute_request",
                                 "RpcError": str(e)}
        write_to_log(self.session_id, self.request, self.response,self.logs_folder,requestName)
        assert_dlg(expected, self.response)
        return self.response

    def stop_request(self):
        requestName = "stop_request"
        self.request = {"session_id": self.session_id}
        stop_req = StopRequest(session_id=self.session_id)
        try:
            stop_response, call = self.stub.Stop.with_call(stop_req)
            assert call.code() == StatusCode.OK
            self.response = MessageToDict(stop_response)
        except grpc.RpcError as e:
            self.response = {"errorMessage": "gRPC error at stop_request",
                             "RpcError": str(e)}
        write_to_log(self.session_id, self.request, self.response,self.logs_folder,requestName)

    def status_request(self):
        status_request = StatusRequest(session_id=self.session_id)
        try:
            status_response, call = self.stub.Status.with_call(status_request)
            assert call.code() == StatusCode.OK
            self.response = MessageToDict(status_response)
        except grpc.RpcError as e:
            if e.code() == grpc.StatusCode.NOT_FOUND:
                self.response = {"errorMessage": "Session ended: NOT_FOUND error"}
            else:
                self.response = {"errorMessage": "gRPC error at status_request",
                                 "RpcError": str(e)}

        return self.response

def dlg_payload_log():
    logs_dir = "logs"
    if not os.path.exists(logs_dir):
        os.makedirs(logs_dir)
    return logs_dir

def clean_text(text):
    'update wild char with temp_dynamic'
    clean_text = re.sub(r'\{\*\}', 'temp_dynamic', text)

    'remove any special char except for .*'
    clean_text = re.sub(r'[\W]', '', clean_text.lower())
    clean_text = re.sub('temp_dynamic', '.*', clean_text)

    return clean_text

def assert_dlg(expected_text, response_text):
    execpted_text_clean = clean_text(str(expected_text))
    response_text_clean = clean_text(str(response_text))
    match = re.search(execpted_text_clean, response_text_clean)
    assert match is not None, \
        f"Expected '{expected_text}', but got '{response_text}'"

def write_to_log(session_id, request, response,logs_folder,requestName):
    if session_id:
        file_path = os.path.join(logs_folder, str(session_id))
        with open(file_path, "a") as file:
            json_str_request = json.dumps(request, indent=4)
            json_str_response = json.dumps(response, indent=4)
            file.write("--------------------------------------------------------------\n")
            file.write("Request for: ")
            file.write(requestName)
            file.write("\n")
            file.write(json_str_request)
            file.write("\n")
            file.write("Response")
            file.write("\n")
            file.write(json_str_response)
            file.write("\n")


"""publish doctsring from files into a confluence site

Examples:
    publish a page under the main root document

    confluence-publish "A root page title" file.py {file.py, ..}

"""

import logging
import json

from . import cli

def pp(obj):
    return json.dumps(obj, indent=2, sort_keys=True)

def subparser(subparsers, name, cmd):
    p = subparsers.add_parser(name)

    p.add_argument(cli.ConfigArgument)  # this must come first
    p.add_argument(cli.LoggingArguments)
    p.set_defaults(func=cmd)
    return p

def main():
    args = parse_args()
    func = args.func
    delattr(args, "func")
    func(**args.__dict__)

def parse_args(args=None):
    parser = cli.ArgumentParser()
    subparsers = parser.add_subparsers(required=True)

    publishp = subparser(subparsers, "publish", publish)
    publishp.add_argument("--commit", action="store_true")

    args = parser.parse_args(args)
    return args

def publish(commit):
    logging.debug("A")
    logging.info("B")
    logging.warning("C")

if __name__ == "__main__":
    main()


from google.cloud import storage
from google.oauth2 import service_account
import os

# Set the path to your service account key file
key_path = 'beaming-team-376517-82a98807d500.json'

# Set the environment variable
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = key_path

# Authenticate using the key file
credentials = service_account.Credentials.from_service_account_file(key_path)

# Define your GCP Cloud Storage bucket and folder paths
bucket_name = 'cloud-ai-platform-54bd831b-8d3c-431d-acbc-4f155b670016'

# Create a GCP Cloud Storage client
storage_client = storage.Client(credentials=credentials)

# Get a reference to the GCP Cloud Storage bucket
bucket = storage_client.bucket(bucket_name)
print("Bucket Obtained")

# List the objects in the bucket
blobs = bucket.list_blobs()
data = {}
for blob in blobs:
    label = blob.name.split('/')[1]
    data["gs://"+bucket_name+"/"+blob.name] = label

with open('garbage_dataset_importfile.csv', 'w') as f:
    for key in data.keys():
        f.write("%s,%s\n"%(key,data[key]))