class CType():

    C_SESSION           = 0
    C_TERRITORY         = 10
    C_UNIT              = 11
    C_UNIT_LAND         = 12
    C_UNIT_SEA          = 13
    C_UNIT_AIR          = 14
    C_IPC               = 15
    C_NATION            = 16
    C_ALLIANCE          = 17
    C_FACILITY          = 18
    C_REGION            = 19

    S_MAP                    = 100
    S_SESSION                = 101
    S_PH1_PURCHASE_REPAIR    = 110
    S_PH2_COMBAT_MOVE        = 111
    S_PH3_CONDUCT_COMBAT     = 112
    S_PH4_NONCOMBAT_MOVE     = 113
    S_PH5_MOBILIZE_NEW_UNITS = 114
    S_PH6_COLLECT_INCOME     = 115

    T_LAND              = 210
    T_SEA               = 211

    U_INFANTARY          = 300
    U_MECH_INFANTARY     = 301
    U_TANK               = 302
    U_ARTILLERY          = 303
    U_AAA                = 304
    U_FIGHTER            = 305
    U_T_BOMBER           = 306
    U_S_BOMBER           = 307
    U_CARGO              = 308
    U_SUBMARINE          = 309
    U_DESTROYER          = 310
    U_CRUISER            = 311
    U_BATTLESHIP         = 312
    U_CARRIER            = 313

    A_AXIS               = 400
    A_ALLIES             = 401
    A_NEUTRAL            = 402
    A_NEUTRAL_PRO_ALLIES = 403
    A_NEUTRAL_PRO_AXIS   = 404

    F_MAJOR_FACTORY     = 500
    F_MINOR_FACTORY     = 501
    F_AIR_BASE          = 502
    F_NAVAL_BASE        = 503

    R_EUROPE            = 600
    R_ASIA_FAR_EAST     = 601
    R_NORDAMERICA       = 602
    R_SOUTHAMERICA      = 603
    R_AFRICA            = 604
    R_PACIFIC           = 605
    R_ASIA_MIDDLE_EAST  = 606
    R_ATLANTIC          = 607
    R_INDIAN_OCEAN      = 608
    R_MEDITERRANEAN_SEA = 609
    R_NORTH_SEA         = 610
    R_BALTIC_SEA        = 611
    R_ARTIC_SEA         = 612
    R_BLACK_SEA         = 613
    R_ASIA_CENTRAL      = 614
    R_AUSTRALIA         = 615

    NA                  = 1000

    d_Str = {
        C_TERRITORY        : "Territory",
        C_UNIT             : "Unit",
        C_IPC              : "IPC",
        C_NATION           : "Nation",
        C_ALLIANCE         : "Alliance",
        C_FACILITY         : "Facility",
        C_REGION           : "Region",

        S_MAP                    : "Map",
        S_SESSION                : "Session",
        S_PH1_PURCHASE_REPAIR    : "Phase 1 Purchase Repair",
        S_PH2_COMBAT_MOVE        : "Phase 2 Combat Move",
        S_PH3_CONDUCT_COMBAT     : "Phase 3 Conduct Combat",
        S_PH4_NONCOMBAT_MOVE     : "Phase 4 Noncombat move",
        S_PH5_MOBILIZE_NEW_UNITS : "Phase 5 Mobilize new unis",
        S_PH6_COLLECT_INCOME     : "Phase 6 Collect income",

        T_LAND             : "Land",
        T_SEA              : "Sea",

        U_INFANTARY        : "Infantary",
        U_MECH_INFANTARY   : "Mech-Infantary",
        U_TANK             : "Tank",
        U_ARTILLERY        : "Artillery",
        U_AAA              : "AAA",
        U_FIGHTER          : "Fighter",
        U_T_BOMBER         : "Tactical-Bomber",
        U_S_BOMBER         : "Stratic-Bomber",
        U_CARGO            : "Cargo",
        U_SUBMARINE        : "Submarine",
        U_DESTROYER        : "Destroyer",
        U_CRUISER          : "Cruiser",
        U_BATTLESHIP       : "Battelship",
        U_CARRIER          : "Carrier",

        A_AXIS               : "Axis",
        A_ALLIES             : "Allies",
        A_NEUTRAL            : "Neutral",
        A_NEUTRAL_PRO_ALLIES : "Neutral pro allies",
        A_NEUTRAL_PRO_AXIS   : "Neutral pro axis",

        F_MAJOR_FACTORY    : "Major factory",
        F_MINOR_FACTORY    : "Minor factory",
        F_AIR_BASE         : "Air base",
        F_NAVAL_BASE       : "Naval base",

        R_EUROPE           : "Europe",
        R_ASIA_FAR_EAST    : "Asia far east",
        R_NORDAMERICA      : "North america",
        R_SOUTHAMERICA     : "South america",
        R_AFRICA           : "Africa",
        R_PACIFIC          : "Pacific",
        R_ASIA_MIDDLE_EAST : "Asia middle east",
        R_ATLANTIC         : "Atlantic",
        R_INDIAN_OCEAN     : "Indian ocean",
        R_MEDITERRANEAN_SEA: "Mediterranean sea",
        R_NORTH_SEA        : "Nord sea",
        R_BALTIC_SEA       : "Baltic sea",
        R_ARTIC_SEA        : "Artic sea",
        R_BLACK_SEA        : "Black sea",
        R_ASIA_CENTRAL     : "Asia central",
        R_AUSTRALIA        : "Australia",
        NA                 : "N/A"
    }

    d_Class = {
        C_TERRITORY        : C_TERRITORY,
        C_UNIT             : C_UNIT     ,
        C_IPC              : C_IPC      ,
        C_NATION           : C_NATION   ,
        C_ALLIANCE         : C_ALLIANCE ,
        C_FACILITY         : C_FACILITY ,
        C_REGION           : C_REGION   ,

        S_MAP                    : C_SESSION,
        S_SESSION                : C_SESSION,
        S_PH1_PURCHASE_REPAIR    : C_SESSION,
        S_PH2_COMBAT_MOVE        : C_SESSION,
        S_PH3_CONDUCT_COMBAT     : C_SESSION,
        S_PH4_NONCOMBAT_MOVE     : C_SESSION,
        S_PH5_MOBILIZE_NEW_UNITS : C_SESSION,
        S_PH6_COLLECT_INCOME     : C_SESSION,

        T_LAND             : C_TERRITORY,
        T_SEA              : C_TERRITORY,

        U_INFANTARY        : C_UNIT,
        U_MECH_INFANTARY   : C_UNIT,
        U_TANK             : C_UNIT,
        U_ARTILLERY        : C_UNIT,
        U_AAA              : C_UNIT,
        U_FIGHTER          : C_UNIT,
        U_T_BOMBER         : C_UNIT,
        U_S_BOMBER         : C_UNIT,
        U_CARGO            : C_UNIT,
        U_SUBMARINE        : C_UNIT,
        U_DESTROYER        : C_UNIT,
        U_CRUISER          : C_UNIT,
        U_BATTLESHIP       : C_UNIT,
        U_CARRIER          : C_UNIT,

        A_AXIS               : C_ALLIANCE,
        A_ALLIES             : C_ALLIANCE,
        A_NEUTRAL            : C_ALLIANCE,
        A_NEUTRAL_PRO_ALLIES : C_ALLIANCE,
        A_NEUTRAL_PRO_AXIS   : C_ALLIANCE,

        F_MAJOR_FACTORY    : C_FACILITY,
        F_MINOR_FACTORY    : C_FACILITY,
        F_AIR_BASE         : C_FACILITY,
        F_NAVAL_BASE       : C_FACILITY,

        R_EUROPE           : C_REGION,
        R_ASIA_FAR_EAST    : C_REGION,
        R_NORDAMERICA      : C_REGION,
        R_SOUTHAMERICA     : C_REGION,
        R_AFRICA           : C_REGION,
        R_PACIFIC          : C_REGION,
        R_ASIA_MIDDLE_EAST : C_REGION,
        R_ATLANTIC         : C_REGION,
        R_INDIAN_OCEAN     : C_REGION,
        R_MEDITERRANEAN_SEA: C_REGION,
        R_NORTH_SEA        : C_REGION,
        R_BALTIC_SEA       : C_REGION,
        R_ARTIC_SEA        : C_REGION,
        R_BLACK_SEA        : C_REGION,
        R_ASIA_CENTRAL     : C_REGION,
        R_AUSTRALIA        : C_REGION,

        NA                 : NA
    }

    d_Sub_Class = {
        U_INFANTARY        : C_UNIT_LAND,
        U_MECH_INFANTARY   : C_UNIT_LAND,
        U_TANK             : C_UNIT_LAND,
        U_ARTILLERY        : C_UNIT_LAND,
        U_AAA              : C_UNIT_LAND,
        U_FIGHTER          : C_UNIT_AIR,
        U_T_BOMBER         : C_UNIT_AIR,
        U_S_BOMBER         : C_UNIT_AIR,
        U_CARGO            : C_UNIT_SEA,
        U_SUBMARINE        : C_UNIT_SEA,
        U_DESTROYER        : C_UNIT_SEA,
        U_CRUISER          : C_UNIT_SEA,
        U_BATTLESHIP       : C_UNIT_SEA,
        U_CARRIER          : C_UNIT_SEA,
    }

    @staticmethod
    def str(t_type:int) -> str:
        try:
            return CType.d_Str[t_type]
        except:
            return None

    @staticmethod
    def type(s_type:str) -> int:
        keys = [k for k, v in CType.d_Str.items() if v == s_type]
        return keys[0]

    @staticmethod
    def na()->str:
        return CType.str(CType.NA)

    @staticmethod
    def get_class(t_type:int) -> int:
        try:
            return CType.d_Class[t_type]
        except:
            return None

    @staticmethod
    def get_sub_class(t_type:int) -> int:
        try:
            return CType.d_Sub_Class[t_type]
        except:
            return None

# test
if __name__ == "__main__":
    assert CType.str(CType.C_TERRITORY       ) == "Territory"
    assert CType.str(CType.C_UNIT            ) == "Unit"
    assert CType.str(CType.C_IPC             ) == "IPC"
    assert CType.str(CType.C_NATION          ) == "Nation"

    assert CType.str(CType.T_LAND            ) == "Land"
    assert CType.str(CType.T_SEA             ) == "Sea"

    assert CType.str(CType.U_INFANTARY       ) == "Infantary"
    assert CType.str(CType.U_MECH_INFANTARY  ) == "Mech-Infantary"
    assert CType.str(CType.U_TANK            ) == "Tank"
    assert CType.str(CType.U_ARTILLERY       ) == "Artillery"
    assert CType.str(CType.U_AAA             ) == "AAA"
    assert CType.str(CType.U_FIGHTER         ) == "Fighter"
    assert CType.str(CType.U_T_BOMBER        ) == "Tactical-Bomber"
    assert CType.str(CType.U_S_BOMBER        ) == "Stratic-Bomber"
    assert CType.str(CType.U_CARGO           ) == "Cargo"
    assert CType.str(CType.U_SUBMARINE       ) == "Submarine"
    assert CType.str(CType.U_DESTROYER       ) == "Destroyer"
    assert CType.str(CType.U_CRUISER         ) == "Cruiser"
    assert CType.str(CType.U_BATTLESHIP      ) == "Battelship"
    assert CType.str(CType.U_CARRIER         ) == "Carrier"
    assert CType.str(CType.A_AXIS            ) == "Axis"
    assert CType.str(CType.A_ALLIES          ) == "Allies"

    assert CType.str(CType.F_MAJOR_FACTORY   ) == "Major factory"
    assert CType.str(CType.F_MINOR_FACTORY   ) == "Minor factory"
    assert CType.str(CType.F_AIR_BASE        ) == "Air base"
    assert CType.str(CType.F_NAVAL_BASE      ) == "Naval base"

    assert CType.str(CType.R_EUROPE          ) == "Europe"
    assert CType.str(CType.R_ASIA_FAR_EAST   ) == "Asia far east"
    assert CType.str(CType.R_NORDAMERICA     ) == "North america"
    assert CType.str(CType.R_SOUTHAMERICA    ) == "South america"
    assert CType.str(CType.R_AFRICA          ) == "Africa"
    assert CType.str(CType.R_PACIFIC         ) == "Pacific"
    assert CType.str(CType.R_ASIA_MIDDLE_EAST) == "Asia middle east"

    assert CType.str(CType.NA                ) == "N/A"

    assert CType.get_class(CType.C_TERRITORY        )  == CType.C_TERRITORY
    assert CType.get_class(CType.C_UNIT             )  == CType.C_UNIT
    assert CType.get_class(CType.C_IPC              )  == CType.C_IPC
    assert CType.get_class(CType.C_NATION           )  == CType.C_NATION
    assert CType.get_class(CType.C_ALLIANCE         )  == CType.C_ALLIANCE
    assert CType.get_class(CType.C_FACILITY         )  == CType.C_FACILITY
    assert CType.get_class(CType.C_REGION           )  == CType.C_REGION

    assert CType.get_class(CType.T_LAND             )  == CType.C_TERRITORY
    assert CType.get_class(CType.T_SEA              )  == CType.C_TERRITORY

    assert CType.get_class(CType.U_INFANTARY        )  == CType.C_UNIT
    assert CType.get_class(CType.U_MECH_INFANTARY   )  == CType.C_UNIT
    assert CType.get_class(CType.U_TANK             )  == CType.C_UNIT
    assert CType.get_class(CType.U_ARTILLERY        )  == CType.C_UNIT
    assert CType.get_class(CType.U_AAA              )  == CType.C_UNIT
    assert CType.get_class(CType.U_FIGHTER          )  == CType.C_UNIT
    assert CType.get_class(CType.U_T_BOMBER         )  == CType.C_UNIT
    assert CType.get_class(CType.U_S_BOMBER         )  == CType.C_UNIT
    assert CType.get_class(CType.U_CARGO            )  == CType.C_UNIT
    assert CType.get_class(CType.U_SUBMARINE        )  == CType.C_UNIT
    assert CType.get_class(CType.U_DESTROYER        )  == CType.C_UNIT
    assert CType.get_class(CType.U_CRUISER          )  == CType.C_UNIT
    assert CType.get_class(CType.U_BATTLESHIP       )  == CType.C_UNIT
    assert CType.get_class(CType.U_CARRIER          )  == CType.C_UNIT

    assert CType.get_class(CType.A_AXIS             )  == CType.C_ALLIANCE
    assert CType.get_class(CType.A_ALLIES           )  == CType.C_ALLIANCE

    assert CType.get_class(CType.F_MAJOR_FACTORY    )  == CType.C_FACILITY
    assert CType.get_class(CType.F_MINOR_FACTORY    )  == CType.C_FACILITY
    assert CType.get_class(CType.F_AIR_BASE         )  == CType.C_FACILITY
    assert CType.get_class(CType.F_NAVAL_BASE       )  == CType.C_FACILITY

    assert CType.get_class(CType.R_EUROPE           )  == CType.C_REGION
    assert CType.get_class(CType.R_ASIA_FAR_EAST    )  == CType.C_REGION
    assert CType.get_class(CType.R_NORDAMERICA      )  == CType.C_REGION
    assert CType.get_class(CType.R_SOUTHAMERICA     )  == CType.C_REGION
    assert CType.get_class(CType.R_AFRICA           )  == CType.C_REGION
    assert CType.get_class(CType.R_PACIFIC          )  == CType.C_REGION
    assert CType.get_class(CType.R_ASIA_MIDDLE_EAST )  == CType.C_REGION

    assert CType.get_class(CType.NA                 )  == CType.NA

    assert CType.get_sub_class(CType.C_TERRITORY        )  == None
    assert CType.get_sub_class(CType.C_UNIT             )  == None
    assert CType.get_sub_class(CType.C_IPC              )  == None
    assert CType.get_sub_class(CType.C_NATION           )  == None
    assert CType.get_sub_class(CType.C_ALLIANCE         )  == None
    assert CType.get_sub_class(CType.C_FACILITY         )  == None
    assert CType.get_sub_class(CType.C_REGION           )  == None

    assert CType.get_sub_class(CType.T_LAND             )  == None
    assert CType.get_sub_class(CType.T_SEA              )  == None

    assert CType.get_sub_class(CType.U_INFANTARY        )  == CType.C_UNIT_LAND
    assert CType.get_sub_class(CType.U_MECH_INFANTARY   )  == CType.C_UNIT_LAND
    assert CType.get_sub_class(CType.U_TANK             )  == CType.C_UNIT_LAND
    assert CType.get_sub_class(CType.U_ARTILLERY        )  == CType.C_UNIT_LAND
    assert CType.get_sub_class(CType.U_AAA              )  == CType.C_UNIT_LAND
    assert CType.get_sub_class(CType.U_FIGHTER          )  == CType.C_UNIT_AIR
    assert CType.get_sub_class(CType.U_T_BOMBER         )  == CType.C_UNIT_AIR
    assert CType.get_sub_class(CType.U_S_BOMBER         )  == CType.C_UNIT_AIR
    assert CType.get_sub_class(CType.U_CARGO            )  == CType.C_UNIT_SEA
    assert CType.get_sub_class(CType.U_SUBMARINE        )  == CType.C_UNIT_SEA
    assert CType.get_sub_class(CType.U_DESTROYER        )  == CType.C_UNIT_SEA
    assert CType.get_sub_class(CType.U_CRUISER          )  == CType.C_UNIT_SEA
    assert CType.get_sub_class(CType.U_BATTLESHIP       )  == CType.C_UNIT_SEA
    assert CType.get_sub_class(CType.U_CARRIER          )  == CType.C_UNIT_SEA

    assert CType.get_sub_class(CType.A_AXIS             )  == None
    assert CType.get_sub_class(CType.A_ALLIES           )  == None

    assert CType.get_sub_class(CType.F_MAJOR_FACTORY    )  == None
    assert CType.get_sub_class(CType.F_MINOR_FACTORY    )  == None
    assert CType.get_sub_class(CType.F_AIR_BASE         )  == None
    assert CType.get_sub_class(CType.F_NAVAL_BASE       )  == None

    assert CType.get_sub_class(CType.R_EUROPE           )  == None
    assert CType.get_sub_class(CType.R_ASIA_FAR_EAST    )  == None
    assert CType.get_sub_class(CType.R_NORDAMERICA      )  == None
    assert CType.get_sub_class(CType.R_SOUTHAMERICA     )  == None
    assert CType.get_sub_class(CType.R_AFRICA           )  == None
    assert CType.get_sub_class(CType.R_PACIFIC          )  == None
    assert CType.get_sub_class(CType.R_ASIA_MIDDLE_EAST )  == None

    assert CType.get_sub_class(CType.NA                 )  == None


from tkinter import *
from tkinter import ttk #theme of tk
from tkinter import messagebox

GUI = Tk()#หน้าจอหลักของโปรแกรม
GUI.title('โปรแกรมบันทึกข้อมูล')
GUI.geometry('500x400')

L1 = Label(GUI,text='โปรแกรมบันทึกความรู้',font=('Sarabun',16),fg='green')
L1.place(x=20,y=30)

##################
def Button1():
    text = 'Python-101'
    messagebox.showinfo('วิชาเรียน',text)

FB1 = Frame(GUI) #สร้างเฟรม
FB1.place(x=100,y=80)
B1 = ttk.Button(FB1,text='วิชาเรียน',command=Button1)
B1.pack(ipadx=10,ipady=10)
##################
def Button2():
    text = 'ตอนนี้มีเงินในบัญชีอยู่ 300 บาท'
    messagebox.showinfo('เงินในบัญชี',text)

FB1 = Frame(GUI) #สร้างเฟรม
FB1.place(x=100,y=230)
B2 = ttk.Button(FB1,text='แสดงยอดเงิน',command=Button2)
B2.pack(ipadx=10,ipady=10)
##################

GUI.mainloop()


import os
import time
import glob
import pandas as pd
from tqdm import tqdm
from nltk.tokenize import TweetTokenizer
from joblib import Parallel, delayed
tqdm.pandas()

def make_data(data: list):
    cols = ["tweetid",
            "user_screen_name",
            "tweet_language",
            "tweet_text",
            "tweet_time",
            "is_retweet",
            "in_reply_to_tweetid",
            "hashtags",
            "urls",
            "user_mentions"]

    df = pd.DataFrame()

    for d in data:
        print(f"LOADING {d}")
        for chunk in pd.read_csv(d, chunksize=250000, low_memory=False, usecols=cols):
            df = pd.concat([df, chunk])

    # drop any possible duplicates:
    og_len = len(df)
    df.drop_duplicates(subset="tweetid", inplace=True)
    deduped = len(df)

    print(f"Found {og_len - deduped} duplicates")

    # extract english tweets:
    print("Extracting English tweets")
    df = df[df.tweet_language == "en"]

    # remove retweets:
    df = df[df.is_retweet == False]

    # remove excessively short tweets:
    print("Counting tokens")
    tokenizer = TweetTokenizer()
    df["tokens"] = Parallel(n_jobs=7)(delayed(tokenizer.tokenize)(line) for line in tqdm(df.tweet_text))
    df["n_tokens"] = df.tokens.apply(lambda row: len(row))
    df = df[df.n_tokens >= 10]

    print(f"Final sample size: {len(df)}")

    # save:
    print("Saving")
    df.reset_index(inplace=True, drop=True)
    df.to_feather(os.path.join("data", "processed", "ru_en_tweets.feather"))

if __name__ == "__main__":
    start = time.time()

    files = glob.glob(os.path.join("data", "raw-twitter", "*.csv"))
    make_data(files)

    end = time.time()
    timer = round((end - start) / 60, 3)

    print("Done!")
    print(f"Run time: {timer} minutes")


'''
문제 풀이
1. 각 배열 개수 (n -1) factorial 계산한다.
2. 배열의 몇번째 인덱스 뺄 것은 찾는다.
3. 배열의 개수 다 없어 질때 까지 반복한다.
'''

import math

def solution(n, k):
    answer = []
    array = list(range(1, n+1))
    count = 1

    while n:
        temp = math.factorial(n) // n
        index = k // temp
        k = k % temp
        if k == 0:
            answer.append(array.pop(index - 1))
        else:
            answer.append(array.pop(index))
        print(answer, temp, index, k)
        n -= 1
    return answer

print(solution(3, 5))


from Bio import SeqIO
import functools
import os
import tempfile

def basename(path):

    return os.path.splitext(os.path.basename(path))[0]

def format_blast_results(aln):

    hsp = aln.hsps[0]
    out = {'AlignmentLength': hsp.align_length,
           'BitScore': hsp.score,
           'Gaps': hsp.gaps,
           'Mismatches': hsp.positives - hsp.identities,
           'PercentIdentity': hsp.identities / aln.length,
           'QueryAln': hsp.query,
           'SubjAln': hsp.sbjct
           }

    return out

def parse_markers(path):

    def convert_typing_test(value):
        lookup = ('pcr', 'allelic', 'repeat',
                  'oligoprobe', 'snp', 'ampliconprobe')

        try:
            return lookup[int(value)]
        except ValueError:
            return value

    d = {}

    with open(path) as f:
        # old style format for now
        first_line = True
        for line in f:

            # skip header
            if first_line:
                first_line = False
                continue

            name, *l = line.strip().split('\t') + ['']  # diag

            d[name] = {'testname': l[0],
                       'testtype': convert_typing_test(l[1]),
                       'forward_primer': l[2],
                       'reverse_primer': l[3],
                       'amplicon_size': int(l[4]),
                       'amplicon_range': float(l[5]),
                       'allelic_db_file': l[6],
                       'repeat_size': l[7]}

    return d

def tempdir(func):

    #@functools.wraps
    def wrapper(*args, **kwargs):

        with tempfile.TemporaryDirectory() as d:
            return func(*args, temp_dir=d, **kwargs)

    return wrapper

class MultiFasta(object):

    def __init__(self, fasta_path):

        self.path = fasta_path
        self.sequences = self.get_sequences()
        self.str_seqs = tuple(str(s.seq) for s in self.sequences)

    def get_sequences(self):

        with open(self.path, 'r') as f:
            return list(SeqIO.parse(f, 'fasta'))

    def join_contigs(self):
        return 'XXX'.join(self.str_seqs)


from abc import abstractmethod
from typing import Dict, List, Optional, Union

from openclean.data.archive.base import ActionHandle
from openclean.data.schema import select_clause
from openclean.data.types import Columns, Scalar, DatasetSchema
from openclean.function.eval.base import Eval, EvalFunction, to_const_eval
from openclean.engine.object.function import FunctionHandle

"""Operator types."""

OP_COMMIT = 'commit'
OP_INSCOL = 'inscol'
OP_LOAD = 'load'
OP_SAMPLE = 'sample'
OP_UPDATE = 'update'

class OpHandle(ActionHandle):
    """The operator handle defines the interface for entries in the provenance
    log of a dataset. The defined methods are used to store the handle and to
    re-apply the operation using a evaluation function that is generated from
    the operator metadata.
    """
    def __init__(
        self, optype: str, schema: Optional[DatasetSchema] = None,
        columns: Optional[Columns] = None,
        func: Optional[Union[Scalar, FunctionHandle]] = None,
        args: Optional[Dict] = None, sources: Optional[Columns] = None
    ):
        """Initialize the operator metadata.

        Parameters
        ----------
        optype: string
            Unique operator type identifier.
        schema: list of string, default=None
            Column names in the dataset schema.
        columns: int, string, or list of int or string, default=None
            List of columns. This defines the columns that are affected (e.g.,
            updated) by the operation.
        func: scalar or openclean.engine.object.func.FunctionHandle
            Scalar value or library function that is used to generate values for
            the modified column(s).
        args: dict, default=None
            Additional keyword arguments that are passed to the callable together
            with the column values that are extracted from each row.
        sources: int, string, or list(int or string), default=None
            List of source columns from which the input values for the
            callable are extracted.
        """
        self.optype = optype
        self.schema = schema
        self.columns = columns
        self.func = func
        self.args = args
        self.sources = sources

    @property
    def is_insert(self) -> bool:
        """True if the operator type is 'inscol'.

        Returns
        -------
        bool
        """
        return self.optype == OP_INSCOL

    @property
    def is_update(self) -> bool:
        """True if the operator type is 'update'.

        Returns
        -------
        bool
        """
        return self.optype == OP_UPDATE

    def to_dict(self) -> Dict:
        """Get a dictionary serialization for the handle.

        Returns
        -------
        dict
        """
        # Get list of column names from the schema. FOr insert command the list
        # of columns are actually strings already.
        colnames = self.columns
        if self.is_update:
            colnames, _ = select_clause(schema=self.schema, columns=colnames)
        doc = {'optype': self.optype, 'columns': colnames}
        if self.func is not None:
            if isinstance(self.func, FunctionHandle):
                f = self.func
                doc['name'] = f.label if f.label is not None else f.name
                if f.namespace is not None:
                    doc['namespace'] = f.namespace
            else:
                # Assume that func is a scalar value.
                doc['value'] = self.func
        if self.args is not None:
            doc['arguments'] = [{'name': k, 'value': v} for k, v in self.args.items()]
        if self.sources is not None:
            srcnames, _ = select_clause(schema=self.schema, columns=self.sources)
            doc['sources'] = srcnames
        return doc

    @abstractmethod
    def to_eval(self) -> EvalFunction:
        """Get an evaluation function instance that can be used to re-apply the
        represented operation on a dataset version.

        Returns
        -------
        openclean.function.eval.base.EvalFunction
        """
        raise NotImplementedError()

class CommitOp(OpHandle):
    """Handle for a user commit operation."""
    def __init__(self):
        """Initialize the action type in the super class."""
        super(CommitOp, self).__init__(optype=OP_COMMIT)

    def to_eval(self) -> EvalFunction:
        """The commit operator cannot be converted to an evaluation function.
        If an attempt is made to do so a runtime error is raised.

        Returns
        -------
        openclean.function.eval.base.EvalFunction
        """
        raise RuntimeError('cannot re-apply commit')

class InsertOp(OpHandle):
    """Handle for an insert operation."""
    def __init__(
        self, schema: DatasetSchema, names: Union[str, List[str]], pos: Optional[int] = None,
        values: Optional[Union[Scalar, FunctionHandle]] = None,
        args: Optional[Dict] = None, sources: Optional[Columns] = None
    ):
        """Initialize the metadata for an insert operator.

        Parameters
        ----------
        schema: list of string
            Column names in the dataset schema.
        names: string, or list(string)
            Names of the inserted columns.
        pos: int, default=None
            Insert position for the new columns. If None, the columns will be
            appended.
        values: scalar or openclean.engine.object.func.FunctionHandle, default=None
            Single value, tuple of values, or library function that is used to
            generate the values for the inserted column(s). If no default is
            specified all columns will contain None.
        func: callable or openclean.function.eval.base.EvalFunction
            Callable that accepts a data frame row as the only argument and
            outputs a (modified) list of value(s).
        args: dict, default=None
            Additional keyword arguments that are passed to the callable together
            with the column values that are extracted from each row.
        sources: int, string, or list(int or string), default=None
            List of source columns from which the input values for the
            callable are extracted.
        """
        super(InsertOp, self).__init__(
            optype=OP_INSCOL,
            schema=schema,
            columns=names,
            func=values,
            args=args,
            sources=sources
        )
        self.pos = pos

    @property
    def names(self) -> Union[str, List[str]]:
        """Synonym for accessing the columns (which are the names of the inserted
        columns for an inscol operator).

        Returns
        -------
        string or list of string
        """
        return self.columns

    def to_dict(self) -> Dict:
        """Get a dictionary serialization for the handle.

        Returns
        -------
        dict
        """
        doc = super(InsertOp, self).to_dict()
        doc['pos'] = self.pos
        return doc

    def to_eval(self) -> EvalFunction:
        """Get an evaluation function instance that can be used to re-apply the
        represented operation on a dataset version.

        Returns
        -------
        openclean.function.eval.base.EvalFunction
        """
        # Return nothing if the associated function is None.
        if self.func is None:
            # Return nothing if the associated function is None.
            return None
            # Use the update columns as input columns if no source columns are
            # specified explicitly.
        if not isinstance(self.func, FunctionHandle):
            # If the function is not a function handle it is assumed to be
            # a scalar value. Wrap that value in a Constant evaluation function.
            return to_const_eval(self.func)
        # Return an evaluation function that wraps the callable. The input for
        # that function comes from the list of sources.
        return Eval(columns=self.sources, func=self.func, args=self.args)

class LoadOp(OpHandle):
    """Handle for a load operation."""
    def __init__(self):
        """Initialize the action type in the super class."""
        super(LoadOp, self).__init__(optype=OP_LOAD)

    def to_eval(self) -> EvalFunction:
        """The load operator cannot be converted to an evaluation function. If
        an attempt is made to do so a runtime error is raised.

        Returns
        -------
        openclean.function.eval.base.EvalFunction
        """
        raise RuntimeError('cannot re-apply load')

class SampleOp(OpHandle):
    """Handle for a dataset sample operation."""
    def __init__(self, args: Optional[Dict] = None):
        """Initialize the action type in the super class.

        Parameters
        ----------
        args: dict, default=None
            Arguments for the sample operation.
        """
        super(SampleOp, self).__init__(optype=OP_SAMPLE, args=args)

    def to_eval(self) -> EvalFunction:
        """The sample operator cannot be converted to an evaluation function.
        If an attempt is made to do so a runtime error is raised.

        Returns
        -------
        openclean.function.eval.base.EvalFunction
        """
        raise RuntimeError('cannot re-apply sample')

class UpdateOp(OpHandle):
    """Handle for an update operation."""
    def __init__(
        self, schema: DatasetSchema, columns: Columns, func: FunctionHandle,
        args: Optional[Dict] = None, sources: Optional[Columns] = None
    ):
        """Initialize the metadata for an update operator.

        Parameters
        ----------
        schema: list of string
            Column names in the dataset schema.
        columns: int, string, or list(int or string)
            Single column or list of column index positions or column names.
        func: openclean.engine.object.func.FunctionHandle
            Library function that is used to generate modified values for the
            updated column(s).
        args: dict, default=None
            Additional keyword arguments that are passed to the callable together
            with the column values that are extracted from each row.
        sources: int, string, or list(int or string), default=None
            List of source columns from which the input values for the
            callable are extracted.
        """
        super(UpdateOp, self).__init__(
            optype=OP_UPDATE,
            schema=schema,
            columns=columns,
            func=func,
            args=args,
            sources=sources
        )

    def to_eval(self) -> EvalFunction:
        """Get an evaluation function instance that can be used to re-apply the
        represented operation on a dataset version.

        Returns
        -------
        openclean.function.eval.base.EvalFunction
        """
        if self.func is None:
            # Return nothing if the associated function is None.
            return None
            # Use the update columns as input columns if no source columns are
            # specified explicitly.
        if not isinstance(self.func, FunctionHandle):
            # If the function is not a function handle it is assumed to be
            # a scalar value. Wrap that value in a Constant evaluation function.
            return to_const_eval(self.func)
        # Create an evaluation function that wraps the callable. The input
        # columns depend on whether sources are given or not.
        columns = self.sources if self.sources is not None else self.columns
        return Eval(columns=columns, func=self.func, args=self.args)


from .parser.confluence import ConfluenceParser
from .parser.confluence_ameblo import ConfluenceAmebloParser
from .parser.pukiwiki import PukiwikiParser
from .converter.confluence import ConflueceConverter
from .converter.ameblo import AmebloConverter

type2parser = {
    'pukiwiki': PukiwikiParser,
    'confluence': ConfluenceParser,
    'confluence_ameblo': ConfluenceAmebloParser,
}
type2converter = {
    'confluence': ConflueceConverter,
    'ameblo': AmebloConverter,
}

def create_parser(wiki_type, options={}, log=None):
    ParserClass = type2parser.get(wiki_type)
    if ParserClass is None:
        raise ValueError("Unknown wiki_type:" + wiki_type)
    return ParserClass(log)

def create_converter(wiki_type, options={}, log=None):
    ConverterClass = type2converter.get(wiki_type)
    if ConverterClass is None:
        raise ValueError("Unknown wiki_type:" + wiki_type)
    return ConverterClass(options, log)


import sys

class TinyStatistician:

    def __init__(self):
        pass

    def mean(lst):
        if len(lst) == 0:
            return None
            print("wesh")
        res = 0
        for elem in lst:
            res =  res + elem
        res = res / len(lst)
        return(res)

    def median(lst):
        if len(lst) == 0:
            return None
        lst.sort()
        if len(lst) % 2 == 1:
            y = (len(lst)+1 )/ 2
            res = lst[int(y -1)]

        if len(lst) % 2 == 0:
              v1 = len(lst) / 2
              res = (lst[int(v1 -1)] + lst[int(v1)]) / 2
        return(res)

    def quartiles(lst, percentile):
        if len(lst) == 0:
            return None
        i = ((percentile / 100) * len(lst))
        lst.sort()
        return(lst[int(i)])

    def var(lst):
        #if len(lst) == 0:
        #    return(None)
        res = 0

        y =TinyStatistician.mean(lst)
        for elem in lst:
            res += (elem - y) **2
        return(res/len(lst))

if __name__ == "__main__":
    t = TinyStatistician

    a = [1, 42, 300, 10, 59]
    b = [24, 23 , 25, 28, 30, 18, 26, 27]

    #print(t.mean(a))
    #print(t.median(b))
    #print(t.median(a))
    #print(t.quartiles(a, 25))
    print(t.var(a))


'''
Bohrn effective charge tensor
'''
import numpy
import jax
from pyscfad import gto, scf
from pyscfad.lib import numpy as jnp

mol = gto.Mole()
mol.atom = '''H  ,  0.   0.   0.
              F  ,  0.   0.   .917'''
mol.basis = '631g'
mol.build(trace_exp=False, trace_ctr_coeff=False)

def dip_moment(mol):
    mf = scf.RHF(mol)
    ao_dip = mol.intor_symmetric('int1e_r', comp=3)
    h1 = mf.get_hcore()
    E = numpy.zeros((3))
    mf.get_hcore = lambda *args, **kwargs: h1 + jnp.einsum('x,xij->ij', E, ao_dip)
    mf.kernel()
    return mf.dip_moment(mol, mf.make_rdm1(), unit='AU', verbose=0)

z = jax.jacrev(dip_moment)(mol).coords
print(z)


import numpy as np

inputs = 16
connections = 0
total = 0

for layer in [	("connections_0.mem", 16, 0.5), \
				("connections_1.mem", 16, 0.5), \
				("connections_2.mem",  8, 0.5) ]:

	filename = layer[0]
	neurons = layer[1]
	density = layer[2]

	sparsity = np.random.binomial(n=1, p=density, size=[neurons * inputs])

	ratio = (100.0-100.0*sum(sparsity)/len(sparsity))
	print(f"Writing connection mask to {filename}, sparsity {ratio:.2f}%, {sum(sparsity)} connections")
	with open(filename, 'w') as f:
		splits = np.array_split(sparsity, len(sparsity)//neurons)
		for s in splits:
			for i in s:
				f.write(str(i))
			f.write('\n')

	connections += sum(sparsity)
	total += len(sparsity)
	inputs = neurons

print(f"Total connections {connections} out of {total} possible")


"""
로또의 최고 순위와 최저 순위
- 문제 : https://programmers.co.kr/learn/courses/30/lessons/77484
- 입출력 예
lottos	win_nums	result
[44, 1, 0, 0, 31, 25]	[31, 10, 45, 1, 6, 19]	[3, 5]
[0, 0, 0, 0, 0, 0]	[38, 19, 20, 40, 15, 25]	[1, 6]
[45, 4, 35, 20, 3, 9]	[20, 9, 3, 45, 4, 35]	[1, 1]
[1, 2, 3, 4, 5, 6]	[7, 8, 9, 10, 11, 12]	[6, 6]
"""

def solution(lottos, win_nums):
    # 매칭 수 구하기
    zero_count, match_count = 0, 0

    for lotto in lottos:
        if lotto == 0: zero_count += 1
        elif lotto in win_nums: match_count += 1

    # 순위 구하기
    high_rank = min(7 - match_count - zero_count, 6)
    low_rank = min(7 - match_count, 6)

    return [high_rank, low_rank]

if __name__ == "__main__":
    lottos = [44, 1, 0, 0, 31, 25]
    win_nums = [31, 10, 45, 1, 6, 19]
    print(solution(lottos, win_nums))


import json
import os
import shutil
import subprocess

from textwrap import dedent
from jinja2 import Environment, FileSystemLoader

VARS = dict(
    init_app=True,
    custom_box=False,
    templates_dir=os.path.join(os.path.dirname(__file__), 'templates')
)

def falstart_print(message, error=False, prefix='[falstart] >'):
    """ Display given message with prefix"""
    bold, red, end = '\033[1m', '\033[31m', '\033[0m'
    print(''.join((
        red if error else '',
        bold, prefix, end,
        red if error else '',
        ' ', message, end,
    )).strip())

def run(command):
    """ wrapper of subprocess check_call fun """
    falstart_print('run: "{}"'.format(command))
    subprocess.check_call(command, shell=True)

def put(src, dst):
    falstart_print('copy: "{}" > "{}"'.format(src, dst))
    if os.path.exists(dst):
        shutil.rmtree(dst)
    shutil.copytree(src, dst)

def mkdir(path):
    falstart_print('make dir: "{}"'.format(path))
    try:
        os.makedirs(path)
    except OSError:
        pass

def render_template(template_name, remote_name):
    """ Render wrapper for simplify touch rendered template into target """
    if os.path.dirname(remote_name):
        mkdir(os.path.dirname(remote_name))
    # load jinja template
    jinja_env = Environment(loader=FileSystemLoader(VARS['templates_dir']))
    template = jinja_env.get_template(template_name)
    # write to remote file
    falstart_print('render "{}" > "{}"'.format(template_name, remote_name))
    with open(remote_name, 'w') as target_file:
        target_file.write(template.render(**VARS))

def common(taskname, root_dir, config=None):
    """ Run all common tasks """
    root_dir = os.path.join(os.getcwd(), root_dir)
    mkdir(root_dir)
    os.chdir(root_dir)
    # update configs
    if config is None:
        VARS.update(json.load(open('.falstart.json', 'r')))
    else:
        json.dump(config, open('.falstart.json', 'w'))
        VARS.update(config)
    VARS['root_dir'] = root_dir
    globals()[taskname]()

def start_box():
    """ Create Vagrant file and up virtual machine """
    # render templates for vagrant up
    render_template('Vagrantfile.j2', 'Vagrantfile')
    render_template('Makefile.j2', 'Makefile')
    run('chmod +x Makefile')
    # make provisioning folder
    mkdir('provision')
    render_template('provision_fabfile.j2', 'provision/fabric_provisioner.py')
    render_template('requirements.j2', 'requirements.txt')
    render_template('requirements.j2', 'requirements-remote.txt')
    render_template('lintrc.j2', '.lintrc')
    render_template('coveragerc.j2', '.coveragerc')
    render_template('py_codes/settings_local.j2', '{proj_name}/settings_local.py.example'.format(**VARS))
    if VARS.get('CELERY'):
        render_template('py_codes/celery.j2', '{proj_name}/celery.py'.format(**VARS))
    # copy templates for vagrant fabric render
    put(os.path.join(VARS['templates_dir'], 'vagrant_templates'), 'provision/templates')
    try:
        env_vars = ('NO_NFS=1 ', '')[bool(VARS.get('VAGRANT_NFS'))]
        run('{}vagrant up'.format(env_vars))
    except:
        falstart_print('Error occurred when up the vagrant machine.', error=True)
        falstart_print('You can try to manually start the Vagrant.', error=True)

    # replace template
    VARS['init_app'] = False
    render_template('provision_fabfile.j2', 'provision/fabric_provisioner.py')
    # commit changes
    falstart_commit()

def falstart_commit():
    """ Try to commit after box start """
    render_template('gitignore.j2', '.gitignore')
    extra_ignore = dedent('''
        # custom ignore'
        settings_local.py
        .vagrant
        static/
    ''')

    falstart_print('Update .gitignore')
    with open('.gitignore', 'a') as gitignore:
        gitignore.write(extra_ignore)

    for attempt in range(2):
        try:
            run('git add . && git commit -m ":rocket: falstart init commit"')
            break
        except:
            falstart_print('not a git repository', error=True)
            run('git init')

def make_custom_box():
    VARS['custom_box'] = True
    run('vagrant destroy -f')
    # render templates to no provide app and syncfolder
    render_template('Vagrantfile.j2', 'Vagrantfile')
    run('vagrant up')
    for cmd in (
            'sudo dd if=/dev/zero of=/EMPTY bs=1M', 'sudo rm -f /EMPTY',
            'cat /dev/null > ~/.bash_history && history -c'):
        run('vagrant ssh -c "{}"'.format(cmd))
    # make custom box
    run('vagrant package --output ~/{proj_name}.box'.format(**VARS))
    # return template to back
    VARS['custom_box'] = False
    render_template('Vagrantfile.j2', 'Vagrantfile')

def rmproj():
    """ Remove project """
    run('cd {root_dir} && vagrant destroy -f'.format(**VARS))
    run('rm {root_dir} -rf'.format(**VARS))


class Solution:
    def compress(self, chars: List[str]) -> int:
        putPointer=0
        consecutiveStart=0
        consecutiveEnd=0
        n=len(chars)
        while consecutiveStart<n:
            character=chars[consecutiveStart]

            consecutiveEnd=consecutiveStart+1
            while consecutiveEnd<n and chars[consecutiveEnd]==character:
                consecutiveEnd+=1
            consecutiveLength=consecutiveEnd-consecutiveStart

            chars[putPointer]=character
            putPointer+=1

            if consecutiveLength>1:
                for digit in str(consecutiveLength):
                    chars[putPointer]=digit
                    putPointer+=1

            consecutiveStart=consecutiveEnd
        return putPointer


from pathlib import Path
import sys

file = Path(__file__).resolve()
parent, root = file.parent, file.parents[2]
sys.path.append(str(root))

from fastapi import APIRouter
from fastapi.requests import Request

from IO_handler.webtoken import return_id_if_is_valid
from database.operations import get_user_tables, get_user_information
from IO_handler.responses import arrange_table_response, assembly_tables_dict
from IO_handler.responses import arrange_user_information, create_tables_response

router = APIRouter()

@router.post("/internal-page-validation")
async def return_page(request: Request):
    data = await request.json()
    user_token = data["token"]
    jwt_result = return_id_if_is_valid(user_token)
    jwt_is_valid = jwt_result["valid"]
    if jwt_is_valid:
        user_id = jwt_result["id"]
        folders_tables = get_user_tables(user_id, "folders")
        completeds_tables = get_user_tables(user_id, "completeds")
        deleteds_tables = get_user_tables(user_id, "deleteds")
        folders_list = arrange_table_response(folders_tables)
        completeds_list = arrange_table_response(completeds_tables)
        deleteds_list = arrange_table_response(deleteds_tables)
        tables_dict = assembly_tables_dict(folders_list, completeds_list, deleteds_list)
        user_raw_informations = get_user_information(user_id)
        user_arranged_informations = arrange_user_information(user_raw_informations)
        return create_tables_response(True, tables_dict, user_arranged_informations)
    else:
        return create_tables_response(False, "", "")


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

''' this is a simple skeleton code for the
simulation, which implements a hard isolation.
cacheline number: 4
app number: 2
working set size per app: 32 * cacheline
for cacheline, 0 - 1 is assigned to app1
2 - 3 is assigned to app2 '''

__author__ = ' Mingjie Zhao '

import random

# these are the global variables:
N = 5  # run the program for N times
S1 = []  # S1 represents the memory access series of app1
S2 = []  # S2 represents the memory access series of app2
LRU = [-1 for _ in range(4)] # LRU keeps track of the LRU of all cachelines
LRU_CURRENT = 0  # the current time
CL = [-1 for _ in range(4)]  # init the value  to -1
LRU_MAX = float('inf')


from pathlib import Path

from allennlp.common.testing import AllenNlpTestCase
from allennlp.common.util import ensure_list

from nbadd.dataset_reader.aoc_reader import AOCDatasetReader

class TestAOCDatasetReader(AllenNlpTestCase):

    def test_read_from_file(self):
        reader = AOCDatasetReader()
        test_fp = Path(__file__, '..', '..', 'test_data', 'aoc_test_data.json')

        instance1 = {"text": ["الف", "مليون", "مبارك", "لفريق", "الوحدات"],
                     "label": "msa"}
        instance2 = {"text": ["ف", "بلاش", "التعميم", "وتشويه", "صوره"],
                     "label": "egyptian"}
        instance3 = {"text": ["ارامكو", "تقول", "انوو", "7000", "مهوب", "6000"],
                     "label": "gulf"}
        instance4 = {"text": ["اكيد", "الطفل", "ورد", "في", "قلوب"],
                     "label": "levantine"}

        instances = ensure_list(reader.read(str(test_fp.resolve())))

        assert len(instances) == 4

        fields = instances[0].fields
        assert [t.text for t in fields["text"].tokens][:5] == instance1["text"]
        assert fields["label"].label == instance1["label"]
        fields = instances[1].fields
        assert [t.text for t in fields["text"].tokens][:5] == instance2["text"]
        assert fields["label"].label == instance2["label"]
        fields = instances[2].fields
        assert [t.text for t in fields["text"].tokens] == instance3["text"]
        assert fields["label"].label == instance3["label"]
        fields = instances[3].fields
        assert [t.text for t in fields["text"].tokens][:5] == instance4["text"]
        assert fields["label"].label == instance4["label"]


from datetime import datetime

import numpy as np
import pytest

import pandas as pd
from pandas import DataFrame, Index, MultiIndex, date_range, period_range
import pandas._testing as tm

@pytest.fixture
def frame_with_period_index():
    return DataFrame(
        data=np.arange(20).reshape(4, 5),
        columns=list("abcde"),
        index=period_range(start="2000", freq="A", periods=4),
    )

@pytest.fixture
def left():
    return DataFrame({"a": [20, 10, 0]}, index=[2, 1, 0])

@pytest.fixture
def right():
    return DataFrame({"b": [300, 100, 200]}, index=[3, 1, 2])

@pytest.mark.parametrize(
    "how, sort, expected",
    [
        ("inner", False, DataFrame({"a": [20, 10], "b": [200, 100]}, index=[2, 1])),
        ("inner", True, DataFrame({"a": [10, 20], "b": [100, 200]}, index=[1, 2])),
        (
            "left",
            False,
            DataFrame({"a": [20, 10, 0], "b": [200, 100, np.nan]}, index=[2, 1, 0]),
        ),
        (
            "left",
            True,
            DataFrame({"a": [0, 10, 20], "b": [np.nan, 100, 200]}, index=[0, 1, 2]),
        ),
        (
            "right",
            False,
            DataFrame({"a": [np.nan, 10, 20], "b": [300, 100, 200]}, index=[3, 1, 2]),
        ),
        (
            "right",
            True,
            DataFrame({"a": [10, 20, np.nan], "b": [100, 200, 300]}, index=[1, 2, 3]),
        ),
        (
            "outer",
            False,
            DataFrame(
                {"a": [0, 10, 20, np.nan], "b": [np.nan, 100, 200, 300]},
                index=[0, 1, 2, 3],
            ),
        ),
        (
            "outer",
            True,
            DataFrame(
                {"a": [0, 10, 20, np.nan], "b": [np.nan, 100, 200, 300]},
                index=[0, 1, 2, 3],
            ),
        ),
    ],
)
def test_join(left, right, how, sort, expected):

    result = left.join(right, how=how, sort=sort)
    tm.assert_frame_equal(result, expected)

def test_join_index(float_frame):
    # left / right

    f = float_frame.loc[float_frame.index[:10], ["A", "B"]]
    f2 = float_frame.loc[float_frame.index[5:], ["C", "D"]].iloc[::-1]

    joined = f.join(f2)
    tm.assert_index_equal(f.index, joined.index)
    expected_columns = Index(["A", "B", "C", "D"])
    tm.assert_index_equal(joined.columns, expected_columns)

    joined = f.join(f2, how="left")
    tm.assert_index_equal(joined.index, f.index)
    tm.assert_index_equal(joined.columns, expected_columns)

    joined = f.join(f2, how="right")
    tm.assert_index_equal(joined.index, f2.index)
    tm.assert_index_equal(joined.columns, expected_columns)

    # inner

    joined = f.join(f2, how="inner")
    tm.assert_index_equal(joined.index, f.index[5:10])
    tm.assert_index_equal(joined.columns, expected_columns)

    # outer

    joined = f.join(f2, how="outer")
    tm.assert_index_equal(joined.index, float_frame.index.sort_values())
    tm.assert_index_equal(joined.columns, expected_columns)

    with pytest.raises(ValueError, match="join method"):
        f.join(f2, how="foo")

    # corner case - overlapping columns
    msg = "columns overlap but no suffix"
    for how in ("outer", "left", "inner"):
        with pytest.raises(ValueError, match=msg):
            float_frame.join(float_frame, how=how)

def test_join_index_more(float_frame):
    af = float_frame.loc[:, ["A", "B"]]
    bf = float_frame.loc[::2, ["C", "D"]]

    expected = af.copy()
    expected["C"] = float_frame["C"][::2]
    expected["D"] = float_frame["D"][::2]

    result = af.join(bf)
    tm.assert_frame_equal(result, expected)

    result = af.join(bf, how="right")
    tm.assert_frame_equal(result, expected[::2])

    result = bf.join(af, how="right")
    tm.assert_frame_equal(result, expected.loc[:, result.columns])

def test_join_index_series(float_frame):
    df = float_frame.copy()
    s = df.pop(float_frame.columns[-1])
    joined = df.join(s)

    # TODO should this check_names ?
    tm.assert_frame_equal(joined, float_frame, check_names=False)

    s.name = None
    with pytest.raises(ValueError, match="must have a name"):
        df.join(s)

def test_join_overlap(float_frame):
    df1 = float_frame.loc[:, ["A", "B", "C"]]
    df2 = float_frame.loc[:, ["B", "C", "D"]]

    joined = df1.join(df2, lsuffix="_df1", rsuffix="_df2")
    df1_suf = df1.loc[:, ["B", "C"]].add_suffix("_df1")
    df2_suf = df2.loc[:, ["B", "C"]].add_suffix("_df2")

    no_overlap = float_frame.loc[:, ["A", "D"]]
    expected = df1_suf.join(df2_suf).join(no_overlap)

    # column order not necessarily sorted
    tm.assert_frame_equal(joined, expected.loc[:, joined.columns])

def test_join_period_index(frame_with_period_index):
    other = frame_with_period_index.rename(columns=lambda key: f"{key}{key}")

    joined_values = np.concatenate([frame_with_period_index.values] * 2, axis=1)

    joined_cols = frame_with_period_index.columns.append(other.columns)

    joined = frame_with_period_index.join(other)
    expected = DataFrame(
        data=joined_values, columns=joined_cols, index=frame_with_period_index.index
    )

    tm.assert_frame_equal(joined, expected)

def test_join_left_sequence_non_unique_index():
    # https://github.com/pandas-dev/pandas/issues/19607
    df1 = DataFrame({"a": [0, 10, 20]}, index=[1, 2, 3])
    df2 = DataFrame({"b": [100, 200, 300]}, index=[4, 3, 2])
    df3 = DataFrame({"c": [400, 500, 600]}, index=[2, 2, 4])

    joined = df1.join([df2, df3], how="left")

    expected = DataFrame(
        {
            "a": [0, 10, 10, 20],
            "b": [np.nan, 300, 300, 200],
            "c": [np.nan, 400, 500, np.nan],
        },
        index=[1, 2, 2, 3],
    )

    tm.assert_frame_equal(joined, expected)

@pytest.mark.parametrize("sort_kw", [True, False])
def test_suppress_future_warning_with_sort_kw(sort_kw):
    a = DataFrame({"col1": [1, 2]}, index=["c", "a"])

    b = DataFrame({"col2": [4, 5]}, index=["b", "a"])

    c = DataFrame({"col3": [7, 8]}, index=["a", "b"])

    expected = DataFrame(
        {
            "col1": {"a": 2.0, "b": float("nan"), "c": 1.0},
            "col2": {"a": 5.0, "b": 4.0, "c": float("nan")},
            "col3": {"a": 7.0, "b": 8.0, "c": float("nan")},
        }
    )
    if sort_kw is False:
        expected = expected.reindex(index=["c", "a", "b"])

    with tm.assert_produces_warning(None, check_stacklevel=False):
        result = a.join([b, c], how="outer", sort=sort_kw)
    tm.assert_frame_equal(result, expected)

class TestDataFrameJoin:
    def test_join(self, multiindex_dataframe_random_data):
        frame = multiindex_dataframe_random_data

        a = frame.loc[frame.index[:5], ["A"]]
        b = frame.loc[frame.index[2:], ["B", "C"]]

        joined = a.join(b, how="outer").reindex(frame.index)
        expected = frame.copy()
        expected.values[np.isnan(joined.values)] = np.nan

        assert not np.isnan(joined.values).all()

        # TODO what should join do with names ?
        tm.assert_frame_equal(joined, expected, check_names=False)

    def test_join_segfault(self):
        # GH#1532
        df1 = DataFrame({"a": [1, 1], "b": [1, 2], "x": [1, 2]})
        df2 = DataFrame({"a": [2, 2], "b": [1, 2], "y": [1, 2]})
        df1 = df1.set_index(["a", "b"])
        df2 = df2.set_index(["a", "b"])
        # it works!
        for how in ["left", "right", "outer"]:
            df1.join(df2, how=how)

    def test_join_str_datetime(self):
        str_dates = ["20120209", "20120222"]
        dt_dates = [datetime(2012, 2, 9), datetime(2012, 2, 22)]

        A = DataFrame(str_dates, index=range(2), columns=["aa"])
        C = DataFrame([[1, 2], [3, 4]], index=str_dates, columns=dt_dates)

        tst = A.join(C, on="aa")

        assert len(tst.columns) == 3

    def test_join_multiindex_leftright(self):
        # GH 10741
        df1 = DataFrame(
            [
                ["a", "x", 0.471780],
                ["a", "y", 0.774908],
                ["a", "z", 0.563634],
                ["b", "x", -0.353756],
                ["b", "y", 0.368062],
                ["b", "z", -1.721840],
                ["c", "x", 1],
                ["c", "y", 2],
                ["c", "z", 3],
            ],
            columns=["first", "second", "value1"],
        ).set_index(["first", "second"])

        df2 = DataFrame([["a", 10], ["b", 20]], columns=["first", "value2"]).set_index(
            ["first"]
        )

        exp = DataFrame(
            [
                [0.471780, 10],
                [0.774908, 10],
                [0.563634, 10],
                [-0.353756, 20],
                [0.368062, 20],
                [-1.721840, 20],
                [1.000000, np.nan],
                [2.000000, np.nan],
                [3.000000, np.nan],
            ],
            index=df1.index,
            columns=["value1", "value2"],
        )

        # these must be the same results (but columns are flipped)
        tm.assert_frame_equal(df1.join(df2, how="left"), exp)
        tm.assert_frame_equal(df2.join(df1, how="right"), exp[["value2", "value1"]])

        exp_idx = pd.MultiIndex.from_product(
            [["a", "b"], ["x", "y", "z"]], names=["first", "second"]
        )
        exp = DataFrame(
            [
                [0.471780, 10],
                [0.774908, 10],
                [0.563634, 10],
                [-0.353756, 20],
                [0.368062, 20],
                [-1.721840, 20],
            ],
            index=exp_idx,
            columns=["value1", "value2"],
        )

        tm.assert_frame_equal(df1.join(df2, how="right"), exp)
        tm.assert_frame_equal(df2.join(df1, how="left"), exp[["value2", "value1"]])

    def test_merge_join_different_levels(self):
        # GH#9455

        # first dataframe
        df1 = DataFrame(columns=["a", "b"], data=[[1, 11], [0, 22]])

        # second dataframe
        columns = MultiIndex.from_tuples([("a", ""), ("c", "c1")])
        df2 = DataFrame(columns=columns, data=[[1, 33], [0, 44]])

        # merge
        columns = ["a", "b", ("c", "c1")]
        expected = DataFrame(columns=columns, data=[[1, 11, 33], [0, 22, 44]])
        with tm.assert_produces_warning(UserWarning):
            result = pd.merge(df1, df2, on="a")
        tm.assert_frame_equal(result, expected)

        # join, see discussion in GH#12219
        columns = ["a", "b", ("a", ""), ("c", "c1")]
        expected = DataFrame(columns=columns, data=[[1, 11, 0, 44], [0, 22, 1, 33]])
        with tm.assert_produces_warning(UserWarning):
            result = df1.join(df2, on="a")
        tm.assert_frame_equal(result, expected)

    def test_frame_join_tzaware(self):
        test1 = DataFrame(
            np.zeros((6, 3)),
            index=date_range(
                "2012-11-15 00:00:00", periods=6, freq="100L", tz="US/Central"
            ),
        )
        test2 = DataFrame(
            np.zeros((3, 3)),
            index=date_range(
                "2012-11-15 00:00:00", periods=3, freq="250L", tz="US/Central"
            ),
            columns=range(3, 6),
        )

        result = test1.join(test2, how="outer")
        expected = test1.index.union(test2.index)

        tm.assert_index_equal(result.index, expected)
        assert result.index.tz.zone == "US/Central"


import os
import re
import sys
import shutil
import asyncio
import subprocess
import logging

log = logging.getLogger(__name__)

from ..base_manager import BaseManager
from .virtualbox_vm import VirtualBoxVM
from .virtualbox_error import VirtualBoxError

class VirtualBox(BaseManager):

    _NODE_CLASS = VirtualBoxVM

    def __init__(self):

        super().__init__()
        self._vboxmanage_path = None
        self._execute_lock = asyncio.Lock()

    @property
    def vboxmanage_path(self):
        """
        Returns the path to VBoxManage.

        :returns: path
        """

        return self._vboxmanage_path

    def find_vboxmanage(self):

        # look for VBoxManage
        vboxmanage_path = self.config.get_section_config("VirtualBox").get("vboxmanage_path")
        if vboxmanage_path:
            if not os.path.isabs(vboxmanage_path):
                vboxmanage_path = shutil.which(vboxmanage_path)
        else:
            log.info("A path to VBoxManage has not been configured, trying to find it...")
            if sys.platform.startswith("win"):
                if "VBOX_INSTALL_PATH" in os.environ:
                    vboxmanage_path_windows = os.path.join(os.environ["VBOX_INSTALL_PATH"], "VBoxManage.exe")
                    if os.path.exists(vboxmanage_path_windows):
                        vboxmanage_path = vboxmanage_path_windows
                elif "VBOX_MSI_INSTALL_PATH" in os.environ:
                    vboxmanage_path_windows = os.path.join(os.environ["VBOX_MSI_INSTALL_PATH"], "VBoxManage.exe")
                    if os.path.exists(vboxmanage_path_windows):
                        vboxmanage_path = vboxmanage_path_windows
            elif sys.platform.startswith("darwin"):
                vboxmanage_path_osx = "/Applications/VirtualBox.app/Contents/MacOS/VBoxManage"
                if os.path.exists(vboxmanage_path_osx):
                    vboxmanage_path = vboxmanage_path_osx
            if not vboxmanage_path:
                vboxmanage_path = shutil.which("vboxmanage")

        if vboxmanage_path and not os.path.exists(vboxmanage_path):
            log.error("VBoxManage path '{}' doesn't exist".format(vboxmanage_path))

        if not vboxmanage_path:
            raise VirtualBoxError("Could not find VBoxManage, please reboot if VirtualBox has just been installed")
        if not os.path.isfile(vboxmanage_path):
            raise VirtualBoxError("VBoxManage '{}' is not accessible".format(vboxmanage_path))
        if not os.access(vboxmanage_path, os.X_OK):
            raise VirtualBoxError("VBoxManage is not executable")
        if os.path.basename(vboxmanage_path) not in ["VBoxManage", "VBoxManage.exe", "vboxmanage"]:
            raise VirtualBoxError("Invalid VBoxManage executable name {}".format(os.path.basename(vboxmanage_path)))

        self._vboxmanage_path = vboxmanage_path
        return vboxmanage_path

    async def execute(self, subcommand, args, timeout=60):

        # We use a lock prevent parallel execution due to strange errors
        # reported by a user and reproduced by us.
        # https://github.com/GNS3/gns3-gui/issues/261
        async with self._execute_lock:
            vboxmanage_path = self.vboxmanage_path
            if not vboxmanage_path:
                vboxmanage_path = self.find_vboxmanage()
            if not vboxmanage_path:
                raise VirtualBoxError("Could not find VBoxManage")

            command = [vboxmanage_path, "--nologo", subcommand]
            command.extend(args)
            command_string = " ".join(command)
            env = os.environ.copy()
            env["LANG"] = "en"  # force english output because we rely on it to parse the output
            log.info("Executing VBoxManage with command: {}".format(command_string))
            try:
                process = await asyncio.create_subprocess_exec(
                    *command,
                    stdout=asyncio.subprocess.PIPE,
                    stderr=asyncio.subprocess.PIPE,
                    env=env
                )
            except (OSError, subprocess.SubprocessError) as e:
                raise VirtualBoxError("Could not execute VBoxManage: {}".format(e))

            try:
                stdout_data, stderr_data = await asyncio.wait_for(process.communicate(), timeout=timeout)
            except asyncio.TimeoutError:
                raise VirtualBoxError("VBoxManage has timed out after {} seconds!".format(timeout))

            if process.returncode:
                vboxmanage_error = stderr_data.decode("utf-8", errors="ignore")
                raise VirtualBoxError("VirtualBox has returned an error: {}".format(vboxmanage_error))

            return stdout_data.decode("utf-8", errors="ignore").splitlines()

    async def _find_inaccessible_hdd_files(self):
        """
        Finds inaccessible disk files (to clean up the VirtualBox media manager)
        """

        hdds = []
        try:
            properties = await self.execute("list", ["hdds"])
        # If VirtualBox is not available we have no inaccessible hdd
        except VirtualBoxError:
            return hdds

        flag_inaccessible = False
        for prop in properties:
            try:
                name, value = prop.split(':', 1)
            except ValueError:
                continue
            if name.strip() == "State" and value.strip() == "inaccessible":
                flag_inaccessible = True
            if flag_inaccessible and name.strip() == "Location":
                hdds.append(value.strip())
                flag_inaccessible = False
        return reversed(hdds)

    async def project_closed(self, project):
        """
        Called when a project is closed.

        :param project: Project instance
        """

        await super().project_closed(project)
        hdd_files_to_close = await self._find_inaccessible_hdd_files()
        for hdd_file in hdd_files_to_close:
            log.info("Closing VirtualBox VM disk file {}".format(os.path.basename(hdd_file)))
            try:
                await self.execute("closemedium", ["disk", hdd_file])
            except VirtualBoxError as e:
                log.warning("Could not close VirtualBox VM disk file {}: {}".format(os.path.basename(hdd_file), e))
                continue

    async def list_vms(self, allow_clone=False):
        """
        Gets VirtualBox VM list.
        """

        vbox_vms = []
        result = await self.execute("list", ["vms"])
        for line in result:
            if len(line) == 0 or line[0] != '"' or line[-1:] != "}":
                continue  # Broken output (perhaps a carriage return in VM name)
            match = re.search(r"\"(.*)\"\ {(.*)}", line)
            if not match:
                continue
            vmname = match.group(1)
            uuid = match.group(2)
            if vmname == "<inaccessible>":
                continue  # ignore inaccessible VMs
            extra_data = await self.execute("getextradata", [uuid, "GNS3/Clone"])
            if allow_clone or len(extra_data) == 0 or not extra_data[0].strip() == "Value: yes":
                # get the amount of RAM
                info_results = await self.execute("showvminfo", [uuid, "--machinereadable"])
                ram = 0
                for info in info_results:
                    try:
                        name, value = info.split('=', 1)
                        if name.strip() == "memory":
                            ram = int(value.strip())
                            break
                    except ValueError:
                        continue
                vbox_vms.append({"vmname": vmname, "ram": ram})
        return vbox_vms

    @staticmethod
    def get_legacy_vm_workdir(legacy_vm_id, name):
        """
        Returns the name of the legacy working directory name for a node.

        :param legacy_vm_id: legacy node identifier (not used)
        :param name: node name

        :returns: working directory name
        """

        return os.path.join("vbox", "{}".format(name))


import sys

import pygame
from fangkuai import Fang

def run_game():
    pygame.init()
    screen = pygame.display.set_mode((800, 600))#窗口大小
    pygame.display.set_caption("Moving Game")#窗口名字

    bg_color = (200, 200, 200)
    fang = Fang(screen)
    #开始游戏
    while True:
        for event in pygame.event.get():    #检测鼠标和键盘事件
            if event.type == pygame.QUIT:   #如果按下关闭
                sys.exit()                  #执行退出窗口

        fang.draw_fang()
        pygame.display.flip()               #让最近绘制的窗口可见

run_game()


import pygame,sys
from pygame.locals import*
# Variables
BLUE = (130, 202, 250)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
LIGHTPURPLE = (240,206,253)
PINK = (255,147,214)
GREY = (222,225,223)
DARKBLUE = (24,32,83)

def searchGame(gamewindow):

    # Set the name of Display
    pygame.display.set_caption("Search and Find Game")
    # Set Background - Using a picture
    gamewindow.fill(DARKBLUE)
    menuBackground = pygame.transform.scale(pygame.image.load(
        "images/hidden background.png"), (1200, 650))
    gamewindow.blit(menuBackground, (0, 0))

    # Title
    fontTitle = pygame.font.Font('freesansbold.ttf', 25)
    title = fontTitle.render('Search & Find Game', True, WHITE)
    Title = title.get_rect()
    Title.center = (660, 40)
    gamewindow.blit(title, Title)
    pygame.display.update()

    # Create this loop so that user can click on the 'x' button to exit
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

def searchFindInstructions(gamewindow):
    pygame.display.set_caption("Search & Find Game Instructions")
    gamewindow.fill(GREY)
    instructionFont = pygame.font.Font('freesansbold.ttf', 40)
    instruction = instructionFont.render('Search & Find Game Instructions', True, BLACK)
    Instruction = instruction.get_rect()
    Instruction.center = (600, 80)
    gamewindow.blit(instruction, Instruction)
    pygame.display.update()

    # Create this loop so that user can click on the 'x' button to exit
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        pygame.event.get(pygame.MOUSEBUTTONDOWN)
        mouse = pygame.mouse.get_pos()
        click = pygame.mouse.get_pressed()

        if 800 + 150 > mouse[0] > 800 and 600 + 50 > mouse[1] > 600:
            pygame.draw.rect(gamewindow, LIGHTPURPLE, (800, 600, 150, 50))
            if click[0] == 1:
                searchGame(gamewindow)
        else:
            pygame.draw.rect(gamewindow, PINK, (800, 600, 150, 50))

        mazeFont = pygame.font.Font('freesansbold.ttf', 20)
        mazeWord = mazeFont.render('START GAME', True, BLACK)
        MazeWord = mazeWord.get_rect()
        MazeWord.center = ((800 + (150 / 2)), (600 + (50 / 2)))
        gamewindow.blit(mazeWord, MazeWord)

        pygame.display.update()


# does all the calculations converting from hand positions to lighting

import math

def getIntensityFromDistance(distance):
    distance -= 40
    if distance <= 0:
        distance = 0
    elif distance >= 180:
        distance = 180
    return int(distance*127//180)

def getColorFromTilt(tilt): # fades through the rainbow
    maxm = 127
    slope = maxm/60
    if tilt >= 2.5:
        tilt = 2.5
    elif tilt <= -2:
        tilt = -2
    tilt = (tilt+2)*90
    if tilt < 60:
        r = maxm
        g = tilt*slope
        b = 0
    elif tilt < 120:
        r = maxm-(tilt-60)*slope
        g = maxm
        b = 0
    elif tilt < 180:
        r = 0
        g = maxm
        b = (tilt-120)*slope
    elif tilt < 240:
        r = 0
        g = maxm-(tilt-180)*slope
        b = maxm
    elif tilt < 300:
        r = (tilt-240)*slope
        g = 0
        b = maxm
    elif tilt < 360:
        r = maxm
        g = 0
        b = maxm-(tilt-300)*slope
    else:
        r = maxm
        g = ((tilt-360)*slope*2) % 127
        b = ((tilt-360)*slope*2) % 127
    return [int(r), int(g), int(b)]

# converts from rectangular to spherical coordinates
def getPossiblePositions(pos):
    x = pos[0]
    y = pos[1]
    z = pos[2]
    theta = 180 - math.degrees(math.acos(y/(math.sqrt(x**2 + y**2 + z**2))))
    if theta >= 135:
        theta = 135
    phi = math.degrees(math.atan2(x, z))
    return findAllPositions(phi, theta)

# finds all positions of pan and tilt that are equivalent
def findAllPositions(phi, theta):
    lst = [(phi, theta)]
    if phi + 360 <= 270:
        lst.append([phi + 360, theta])
    if phi - 360 >= -270:
        lst.append([phi - 360, theta])
    if phi + 180 <= 270:
        lst.append([phi + 180, -theta])
    if phi - 180 >= -270:
        lst.append([phi - 180, -theta])
    return lst

# finds the best pan/tilt value from the list of all possible
def getPanTilt(lst, pos):
    bestPosition = None
    bestDistance = 1000000
    for item in lst:
        currentDistance = (item[0] - pos[0])**2 + (item[1] - pos[1])**2
        if currentDistance < bestDistance:
            bestDistance = currentDistance
            bestPosition = item
    return bestPosition


import io
import os
import xml.dom.minidom
import xml.etree.ElementTree as ET
from shutil import copyfile

import lxml.etree as etree
import numpy as np

from .mjcf_utils import array_to_string
from ..utils import XMLError
from ..utils.transform_utils import quat_to_euler

class MujocoXML(object):
    """
    Base class of Mujoco xml file
    Wraps around ElementTree and provides additional functionality for merging different models.
    Specially, we keep track of <worldbody/>, <actuator/> and <asset/>
    """

    def __init__(self, fname):
        """
        Loads a mujoco xml from file.

        Args:
            fname (str): path to the MJCF xml file.
        """
        self.file = fname
        self.folder = os.path.dirname(fname)
        self.tree = None
        self.root = None
        self.name = None
        self.worldbody = None
        self.actuator = None
        self.sensor = None
        self.asset = None
        self.equality = None
        self.contact = None
        self.default = None
        self.tendon = None
        self.visual = None
        self.option = None

        self.initialize_base()

        # self.tree = ET.parse(fname)
        # self.root = self.tree.getroot()
        # self.name = self.root.get("model")
        # self.worldbody = self.create_default_element("worldbody")
        # self.actuator = self.create_default_element("actuator")
        # self.sensor = self.create_default_element("sensor")
        # self.asset = self.create_default_element("asset")
        # self.equality = self.create_default_element("equality")
        # self.contact = self.create_default_element("contact")
        # self.default = self.create_default_element("default")
        # self.tendon = self.create_default_element("tendon")
        # self.visual = self.create_default_element("visual")
        # self.option = self.create_default_element("option")
        # self.resolve_asset_dependency()

    def initialize_base(self):
        self.tree = ET.parse(self.file)
        self.root = self.tree.getroot()
        self.name = self.root.get("model")
        self.worldbody = self.create_default_element("worldbody")
        self.actuator = self.create_default_element("actuator")
        self.sensor = self.create_default_element("sensor")
        self.asset = self.create_default_element("asset")
        self.equality = self.create_default_element("equality")
        self.contact = self.create_default_element("contact")
        self.default = self.create_default_element("default")
        self.tendon = self.create_default_element("tendon")
        self.visual = self.create_default_element("visual")
        self.option = self.create_default_element("option")
        self.resolve_asset_dependency()

    def set_fname(self, fname):
        self.save_model(fname)
        self.file = fname
        self.folder = os.path.dirname(fname)
        self.asset = self.create_default_element("asset")
        self.resolve_asset_dependency()

    def resolve_asset_dependency(self):
        """
        Converts every file dependency into absolute path so when we merge we don't break things.
        """

        for node in self.asset.findall("./*[@file]"):
            file = node.get("file")
            abs_path = os.path.abspath(self.folder)
            abs_path = os.path.join(abs_path, file)
            node.set("file", abs_path)

    def create_default_element(self, name):
        """
        Creates a <@name/> tag under root if there is none.
        """

        found = self.root.find(name)
        if found is not None:
            return found
        ele = ET.Element(name)
        self.root.append(ele)
        return ele

    def merge(self, other, robot_name_list=None, merge_body=True):

        """
        Default merge method.

        Args:
            other: another MujocoXML instance
                raises XML error if @other is not a MujocoXML instance.
                merges <worldbody/>, <actuator/> and <asset/> of @other into @self
            merge_body: True if merging child bodies of @other. Defaults to True.
        """
        if not isinstance(other, MujocoXML):
            raise XMLError("{} is not a MujocoXML instance.".format(type(other)))

        # Keep hashtable with class_types for body, geom, site, joint, name

        if merge_body:
            for body in other.worldbody:
                self.worldbody.append(body)
        self.merge_asset(other)
        for one_actuator in other.actuator:
            self.actuator.append(one_actuator)
        for one_sensor in other.sensor:
            self.sensor.append(one_sensor)
        for one_equality in other.equality:
            self.equality.append(one_equality)
        for one_contact in other.contact:
            self.contact.append(one_contact)
        for one_default in other.default:
            if not robot_name_list or robot_name_list.count(other.name[2:]) > 1:
                # if default element of robot is appended once donot append again
                # if creating empty arena skip default
                pass
            else:
                self.default.append(one_default)
        for one_tendon in other.tendon:
            self.tendon.append(one_tendon)
        for one_visual in other.visual:
            self.visual.append(one_visual)

        # Update self.options.attribute from other, other has higher priority than self.
        self.option.attrib.update(other.option.attrib)

    def unmerge(self, other):
        """
        removes merged body
        """
        if not isinstance(other, MujocoXML):
            raise XMLError("{} is not a MujocoXML instance.".format(type(other)))

        # Keep hashtable with class_types for body, geom, site, joint, name

        for body in other.worldbody:
            for body_2 in self.worldbody.iter("body"):
                if body in body_2:
                    body_2.remove(body)
                    break
        self.unmerge_asset(other)
        for one_actuator in other.actuator:
            self.actuator.remove(one_actuator)
        for one_sensor in other.sensor:
            self.sensor.remove(one_sensor)
        for one_equality in other.equality:
            self.equality.remove(one_equality)
        for one_contact in other.contact:
            self.contact.remove(one_contact)
        for one_default in other.default:
            self.default.remove(one_default)
        for one_tendon in other.tendon:
            self.tendon.remove(one_tendon)
        for one_visual in other.visual:
            self.visual.remove(one_visual)

    def get_model(self, mode="mujoco_py"):
        """
        Generates a MjModel instance from the current xml tree.

        Args:
            mode (str): Mode with which to interpret xml tree

        Returns:
            MjModel: generated model from xml

        Raises:
            ValueError: [Invalid mode]
        """

        available_modes = ["mujoco_py"]

        with io.StringIO() as string:
            try:
                string.write(ET.tostring(self.root, encoding="unicode"))
                if mode == "mujoco_py":
                    model = load_model_from_xml(string.getvalue())
                    return model
                raise ValueError(
                    "Unkown model mode: {}. Available options are: {}".format(
                        mode, ",".join(available_modes)
                    )
                )
            except Exception as e:
                # print(e)
                fname = 'EXCEPTION.xml'
                # directory = os.path.dirname(os.path.abspath(fname))
                # if not os.path.exists(directory): os.mkdir(directory)
                # with open(fname, "w") as f:
                #     f.write(string.getvalue())
                xml_str = string.getvalue()
                parser = etree.XMLParser(remove_blank_text=True, encoding="UTF-8")
                elem = etree.XML(xml_str, parser=parser)
                with open(fname, "wb") as f:
                    f.write(etree.tostring(elem, pretty_print=True))

                print("Exception loading xml file. Saved exception to {}".format(os.path.abspath(fname)))

    def get_xml(self):
        """
        Returns a string of the MJCF XML file.
        """
        with io.StringIO() as string:
            string.write(ET.tostring(self.root, encoding="unicode"))
            return string.getvalue()

    def save_model(self, fname, with_stl_files=False, sim_to_save_state=None, **_):
        """
        Saves the xml to file.

        Args:
            fname: output file location
            pretty: attempts!! to pretty print the output
        """
        directory = os.path.dirname(os.path.abspath(fname))
        if not os.path.exists(directory): os.makedirs(directory)
        if sim_to_save_state is not None:
            # save all body, geom, site: pos, orientation
            for element in self.worldbody.findall(".//"):
                tag = element.tag
                element_name = element.get("name", None)
                if element_name is not None:
                    elem_id = sim_to_save_state.model.__getattribute__("{}_name2id".format(tag))(element_name)
                    if tag == "geom" and element.get("type") == "mesh":
                        # ignore mesh geoms, since mesh geom pos are processed by Mujoco, so we dont know the pos set by the user
                        continue
                    else:
                        pass
                    if "joint" in tag:
                        element.set("ref", str(sim_to_save_state.data.__getattribute__("qpos")[elem_id]))
                    else:
                        pass
                    try:
                        if tag == "body" and element.get("mocap", None) is not None:
                            element.set("pos", array_to_string(
                                sim_to_save_state.data.__getattribute__("{}_xpos".format(tag))[elem_id], precision=5))
                            element.set("quat",
                                        array_to_string(
                                            sim_to_save_state.data.__getattribute__("{}_xquat".format(tag))[elem_id],
                                            precision=4))
                        else:
                            element.set("pos", array_to_string(
                                sim_to_save_state.model.__getattribute__("{}_pos".format(tag))[elem_id], precision=5))
                            element_euler = element.get("euler", None)
                            if element_euler:
                                element.set("euler",
                                            array_to_string(quat_to_euler(
                                                sim_to_save_state.model.__getattribute__("{}_quat".format(tag))[
                                                    elem_id], degrees=False),
                                                precision=4))
                            else:
                                element.set("quat",
                                            array_to_string(
                                                sim_to_save_state.model.__getattribute__("{}_quat".format(tag))[
                                                    elem_id],
                                                precision=4))
                        size = sim_to_save_state.model.__getattribute__("{}_size".format(tag))[elem_id]
                        if np.sum(size) <= 1e-4:
                            pass
                        else:
                            element.set("size", array_to_string(size, precision=6))
                    except AttributeError as e:
                        # print(e)
                        continue
                else:
                    continue
        else:
            pass
        xml_str = ET.tostring(self.root, encoding="unicode")

        if with_stl_files:
            # copy all stl files to a location
            export_asset_dir = os.path.join(directory, "assets")
            prefix_dir = os.path.abspath(self.folder)
            sub_asset_files = list(self.asset)
            _replace_dirs = []
            for sub_asset in sub_asset_files:
                sub_asset_path = sub_asset.get("file", None)
                if sub_asset_path is None:
                    continue
                else:
                    if prefix_dir in sub_asset_path:
                        sub_export_asset_dir_ = sub_asset_path.replace(prefix_dir, export_asset_dir)
                    else:
                        sub_asset_path_temp = sub_asset_path if sub_asset_path[0] != "/" else sub_asset_path[1:]
                        _replace_dirs.append((sub_asset_path, sub_asset_path_temp))
                        sub_export_asset_dir_ = os.path.join(export_asset_dir, sub_asset_path_temp)
                    os.makedirs(os.path.dirname(sub_export_asset_dir_), exist_ok=True)
                    try:
                        copyfile(sub_asset_path, sub_export_asset_dir_)
                    except:
                        continue

            xml_str = xml_str.replace(prefix_dir + "/", "./assets/")
            for _replace_dir_name, _replace_dir_name_by in set(_replace_dirs):
                xml_str = xml_str.replace(_replace_dir_name, os.path.join("./assets", _replace_dir_name_by))

        parser = etree.XMLParser(remove_blank_text=True, encoding="UTF-8")
        elem = etree.XML(xml_str, parser=parser)
        with open(fname, "wb") as f:
            f.write(etree.tostring(elem, pretty_print=True))

        print("saved model to {}".format(fname))

    def get_model_as_string(self, pretty=True):
        """
        return the xml

        Args:
            fname: output file location
            pretty: attempts!! to pretty print the output
        """
        xml_str = ET.tostring(self.root, encoding="unicode")
        if pretty:
            # TODO: get a better pretty print library
            parsed_xml = xml.dom.minidom.parseString(xml_str)
            xml_str = parsed_xml.toprettyxml(newl="")
        # print('output xml: \current_timestep',xml_str)
        return xml_str

    def merge_asset(self, other):
        """
        Useful for merging other files in a custom logic.
        """
        for asset in other.asset:
            asset_name = asset.get("name")
            asset_type = asset.tag
            # Avoids duplication
            pattern = "./{}[@name='{}']".format(asset_type, asset_name)
            if self.asset.find(pattern) is None:
                self.asset.append(asset)

    def unmerge_asset(self, other):
        """
        Useful for unmerging other files in a custom logic.
        """
        for asset in other.asset:
            asset_name = asset.get("name")
            asset_type = asset.tag
            # Avoids duplication
            pattern = "./{}[@name='{}']".format(asset_type, asset_name)
            if self.asset.find(pattern) is not None:
                self.asset.remove(asset)

    # ---------------------------------------------
    #   Added the following from the latest robosuit
    # ---------------------------------------------
    def get_element_names(self, root, element_type):
        """
        Searches recursively through the @root and returns a list of names of the specified @element_type

        Args:
            root (ET.Element): Root of the xml element tree to start recursively searching through
                (e.g.: `self.worldbody`)
            element_type (str): Name of element to return names of. (e.g.: "site", "geom", etc.)

        Returns:
            list: names that correspond to the specified @element_type
        """
        names = []
        for child in root:
            if child.tag == element_type:
                names.append(child.get("name"))
            names += self.get_element_names(child, element_type)
        return names

    def add_prefix(self,
                   prefix,
                   tags=("body", "joint", "sensor", "site", "geom", "camera", "actuator", "tendon", "asset", "mesh",
                         "texture", "material")):
        """
        Utility method to add prefix to all body names to prevent name clashes
        TODO use this instead of rename functions in MujocoXMLObject
        Args:
            prefix (str): Prefix to be appended to all requested elements in this XML
            tags (list or tuple): Tags to be searched in the XML. All elements with specified tags will have "prefix"
                prepended to it
        """
        # Define tags as a set
        tags = set(tags)

        # Define equalities set to pass at the end
        equalities = set(tags)

        # Add joints to equalities if necessary
        if "joint" in tags:
            equalities = equalities.union(["joint1", "joint2"])

        # Handle actuator elements
        if "actuator" in tags:
            tags.discard("actuator")
            for actuator in self.actuator:
                self._add_prefix_recursively(actuator, tags, prefix)

        # Handle sensor elements
        if "sensor" in tags:
            tags.discard("sensor")
            for sensor in self.sensor:
                self._add_prefix_recursively(sensor, tags, prefix)

        # Handle tendon elements
        if "tendon" in tags:
            tags.discard("tendon")
            for tendon in self.tendon:
                self._add_prefix_recursively(tendon, tags.union(["fixed"]), prefix)
            # Also take care of any tendons in equality constraints
            equalities = equalities.union(["tendon1", "tendon2"])

        # Handle asset elements
        if "asset" in tags:
            tags.discard("asset")
            for asset in self.asset:
                if asset.tag in tags:
                    self._add_prefix_recursively(asset, tags, prefix)

        # Handle contacts and equality names for body elements
        if "body" in tags:
            for contact in self.contact:
                if "body1" in contact.attrib:
                    contact.set("body1", prefix + contact.attrib["body1"])
                if "body2" in contact.attrib:
                    contact.set("body2", prefix + contact.attrib["body2"])
            # Also take care of any bodies in equality constraints
            equalities = equalities.union(["body1", "body2"])

        # Handle all equality elements
        for equality in self.equality:
            self._add_prefix_recursively(equality, equalities, prefix)

        # Handle all remaining bodies in the element tree
        for body in self.worldbody:
            if body.tag in tags:
                self._add_prefix_recursively(body, tags, prefix)

    def _add_prefix_recursively(self, root, tags, prefix):
        """
        Iteratively searches through all children nodes in "root" element to append "prefix" to any named subelements
        with a tag in "tags"

        Args:
            root (ET.Element): Root of the xml element tree to start recursively searching through
                (e.g.: `self.worldbody`)
            tags (list or tuple): Tags to be searched in the XML. All elements with specified tags will have "prefix"
                prepended to it
            prefix (str): Prefix to be appended to all requested elements in this XML
        """
        # First re-name this element
        if "name" in root.attrib:
            root.set("name", prefix + root.attrib["name"])

        # Then loop through all tags and rename any appropriately
        for tag in tags:
            if tag in root.attrib:
                root.set(tag, prefix + root.attrib[tag])

        # Recursively go through child elements
        for child in root:
            if child.tag in tags:
                self._add_prefix_recursively(child, tags, prefix)

def load_model_from_xml(xml_str):
    """
    Loads and returns a PyMjModel model from a string containing XML markup.
    Saves the XML string used to create the returned model in `model.xml`.
    """
    from mujoco_py import load_model_from_path
    import tempfile
    with tempfile.NamedTemporaryFile(suffix=".xml", delete=False) as fp:
        fp.write(xml_str.encode())
        fp.flush()
    model = load_model_from_path(fp.name)
    os.remove(fp.name)
    return model


import os
import os.path as osp
from glob import glob

src_dir = '/private/home/yufeiy2/scratch/result/wild/'
dst_dir = '/private/home/yufeiy2/scratch/result/wild/'

folder = 'epic_video_clips_fast'

def mv_folder(folder):
    # mv all files under folder to dst_dir
    for src_folder in glob(osp.join(src_dir, folder, '*/*')):
        seqname = osp.basename(src_folder)
        dst_folder = osp.join(dst_dir, seqname)
        # os.makedirs(dst_folder, exist_ok=True)
        cmd = f'mv {src_folder} {dst_folder}'
        print(cmd)
        os.system(cmd)

# mv_folder(folder)
# mv_folder('yt_clips_fast')

def make_folder(src_dir):
    seq_list = glob(osp.join(src_dir, '*/'))
    for seq_dir in seq_list:
        # make a images/ folder and put all .jpg to that
        new_folder = osp.join(seq_dir, 'images')
        os.makedirs(new_folder, exist_ok=True)

        # for img_path in glob(osp.join(seq_dir, '*.jpg')):
        #     cmd = f'mv {img_path} {new_folder}'
        #     print(cmd)
        #     os.system(cmd)
        cmd = f'mv {new_folder}/bbox.jpg {seq_dir}'
        print(cmd)
        os.system(cmd)

make_folder(osp.join(src_dir, 'raw'))


import subprocess
import pathlib
import jinja2
from components import Variable, Statement

# jinja templates folder
jinja_env = jinja2.Environment(
    loader=jinja2.FileSystemLoader("structs"),
    trim_blocks=True,
    lstrip_blocks=True,
    autoescape=False,
)

rendered_folder = pathlib.Path("rendered")
obj_folder = pathlib.Path("obj")
exe_folder = pathlib.Path("exe")

rendered_folder.mkdir(exist_ok=True)
obj_folder.mkdir(exist_ok=True)
exe_folder.mkdir(exist_ok=True)

def create_asm(path, externals=tuple(), variables=None, statements=None):
    test = jinja_env.get_template("new_script.asm.jinja")
    test_rendered = test.render(
        externals=externals or tuple(),
        variables=variables or tuple(),
        statements=statements or tuple(),
    )
    test_path = rendered_folder / path
    test_path.write_text(test_rendered)
    return test_path

def nasm(_obj_path, _asm_path):
    sp = subprocess.Popen(["nasm", "-f", "win32", "-o", _obj_path, _asm_path])
    sp.wait()
    if sp.returncode != 0:
        raise Exception(f"nasm failed with code {sp.returncode}")

def link(_exe_path, _obj_path):
    sp = subprocess.Popen(f"gcc -o {_exe_path} {_obj_path}".split())
    sp.wait()
    if sp.returncode != 0:
        raise Exception(f"linker failed with code {sp.returncode}")

def run(_exe_path):
    sp = subprocess.Popen(
        [
            _exe_path,
        ],
        stdout=subprocess.PIPE,
    )
    while sp.poll() is None:
        line = sp.stdout.readline()
        if line:
            print(line.decode("utf-8").strip())
    print(sp.stdout.read().decode("utf-8").strip())
    if sp.returncode != 0:
        raise Exception(f"program failed with code {sp.returncode}")
    print("program exited with code 0")

def build(path: pathlib.Path):
    asm = rendered_folder / path
    obj = obj_folder / path.with_suffix(".obj").name
    exe = exe_folder / path.with_suffix(".exe").name

    try:
        nasm(obj, asm)
        link(exe, obj)
    finally:
        # asm.unlink(missing_ok = True)
        obj.unlink(missing_ok=True)
        if exe.exists():
            run(exe)

if __name__ == "__main__":
    path = pathlib.Path("test.asm")

    create_asm(
        path,
        externals=(
            "_printf",
            "_scanf",
        ),
        variables=[
                Variable(
                        "lippy_version",
                        "db",
                        '"Lippy 0.0.0.1", 0x0A, 0',
                ),
        ],
        statements=[
            Statement("print", "lippy_version"),
            Statement("mov", "eax, 0"),
            Statement("ret", None),
        ],
    )
    build(path)