#!/usr/bin/env python3
import argparse
import sys
import os
from pathlib import Path
import json
import io
import re
import tempfile
import shutil
import copy

re_has_whitespace = re.compile(r"\s+")
re_has_indent = re.compile(r"\s{4}\s+")
re_empty_line = re.compile(r"^\s*$")

def parse_args(args):
    parser = argparse.ArgumentParser()
    parser.add_argument("-p", "--package", required=False, help="the namespace of the package to process")
    parser.add_argument("-b", "--build", required=True, help="the path of the build folder")
    parser.add_argument("-f", "--force", action="store_true", required=False, help="force generation, as opposed to generating only if more recent")
    return parser.parse_args(args)

def error(msg):
    print("[ERROR] " + msg, file=sys.stderr)

def progress(msg):
    print("[PROGRESS] " + msg)

def get_package_filename(build, package):
    return str(Path(build) / "packages" / (package + ".json"))

def get_source_filename(build, source):
    unmodified = str(Path(build) / "files" / (source + ".yapl"))
    if os.path.exists(unmodified):
        return unmodified
    return str(Path(build) / "files" / "modified_locally" / (source + ".yapl"))

def validate_parsed_args(parsed_args):
    if not os.path.isdir(parsed_args.build):
        error("The build parameter must specify a directory file")
        return 1
    if parsed_args.package is not None:
        if not os.path.isfile(get_package_filename(parsed_args.build, parsed_args.package)):
            error("The parameters must specify a package file")
            return 1
    return 0

def main(parsed_args):
    progress("Starting")
    progress("Preparing output directories")
    modules_path = Path(parsed_args.build) / "modules"
    modules_path.mkdir(parents=True, exist_ok=True)
    if parsed_args.force:
        shutil.rmtree(modules_path, ignore_errors=False, onerror=None)
        modules_path.mkdir(parents=True, exist_ok=True)
    if parsed_args.package:
        process_package(parsed_args.build, parsed_args.package)
    else:
        packages_path = Path(parsed_args.build) / "packages"
        packages = list(packages_path.glob("*.json"))
        n = 1
        for package in packages:
            progress("Processing package {} ({} of {})".format(package, n, len(packages)))
            n = n + 1
            process_package(parsed_args.build, Path(package).stem)
    progress("Finished")
    return 0

def load_package(build, package):
    package_filename = get_package_filename(build, package)
    with io.open(package_filename) as json_file:
        return json.load(json_file)

def load_sourcefile(build, hash):
    source_filename = get_source_filename(build, hash)
    with io.open(source_filename, "r") as yapl_file:
        return yapl_file.read()

def dedent(l):
    if l == "":
        return l
    elif l[0] == "\t":
        return l[1:]
    elif l[:4] == "    ":
        return l[4:]
    elif l.strip() == "":
        return ""
    else:
        assert False, "expected leading whitespace, not '{}'".format(l)
        return l

def process_package(build, package):
    progress("Processing package " + package)
    package_descriptor = load_package(build, package)
    source_files = list(package_descriptor["source_files"].items())
    modules_path = Path(build) / "modules"
    n = 1
    for source_filename, sourcefile_info in source_files:
        progress("Processing sourcefile {} ({} of {})".format(source_filename, n, len(source_files)))
        n = n + 1
        revision = sourcefile_info["revision"]
        if os.path.isdir(modules_path / revision):
            # TODO: this can lead to inconsistency
            continue
        def save_modules(build, package_descriptor, source_filename, sourcefile_info):
            revision = sourcefile_info["revision"]
            source_file = load_sourcefile(build, revision)
            lines = source_file.split("\n")
            extractor = None
            parent_metadata = {
                "package":package_descriptor["identifier"],
                "identifier":package_descriptor["identifier"],
                "source": {
                    "filename": source_filename,
                    "revision": revision,
                },
                "symbols": copy.deepcopy(package_descriptor["symbols"])
            }
            for line in lines:
                if line.startswith("#!"):
                    # ignore hash-bangs
                    pass
                elif extractor is None and re_has_indent.match(line):
                    pass
                elif extractor is not None:
                    if not extractor.process_line(line):
                        extractor.save(build)
                        extractor = None
                elif ModuleExtractor.matches(line):
                    extractor = ModuleExtractor(parent_metadata, line)
        save_modules(build, package_descriptor, source_filename, sourcefile_info)

class Extractor:
    def __init__(self, parent_metadata, category):
        self._parent_metadata = parent_metadata
        self._metadata = {
            "identifier":None, # to be filled by subclasses
            "category":category,
            "source":parent_metadata["source"],
        }
        if "module" in parent_metadata:
            self._metadata["module"] = parent_metadata["module"]
        elif "package" in parent_metadata:
            self._metadata["package"] = parent_metadata["package"]
        self._lines = []

    def process_line(self, line):
        if line.startswith("}"):
            return False
        self._lines.append(dedent(line))
        return True

    def get_path(self, build):
        _filename = self.get_filename(build)
        _path = Path(_filename).parents[0]
        _path.mkdir(parents=True, exist_ok=True)
        return str(_path)

    def get_filename(self, build):
        assert False

    def save(self, build):
        _path = self.get_path(build)
        Path(_path).mkdir(parents=True, exist_ok=True)
        def strip_empty_lines(lines):
            # this is a brute force evil algorithm, fix this one day.
            while lines and re_empty_line.match(lines[0]):
                lines.pop(0)
            while lines and re_empty_line.match(lines[-1]):
                lines.pop(-1)
            lines.append("")
            return lines
        _lines = strip_empty_lines(self._lines)
        _filename = self.get_filename(build)
        with io.open(_filename + ".yapl", "w") as yapl_file:
            yapl_file.write("\n".join(strip_empty_lines(_lines)))
        with io.open(_filename + ".json", 'w') as metadata_file:
            json.dump(self._metadata, metadata_file, sort_keys=True, indent=4)

    @classmethod
    def matches(cls, line):
        m = cls._expression.match(line)
        return m is not None and m and True

class FunctionExtractor(Extractor):

    _expression = re.compile(r"^(private\s+){0,1}\s*("
                             r"((function)|(constructor)|(destructor)|(method)|(generator)|(closure))"
                             r"(\-((function)|(constructor)|(destructor)|(method)|(generator)|(closure)))*"
                             r")\s+(.+)")
    _identifier = re.compile(r"\s*([^\(]+)(.*)")

    def __init__(self, parent_metadata, line):
        super().__init__(parent_metadata, "functions")
        m = FunctionExtractor._expression.match(line)
        _private = m.group(1) is not None and m.group(1).startswith("private")
        remainder = m.group(len(m.groups()))
        m = FunctionExtractor._identifier.match(remainder)
        _name = m.group(1)
        remainder = m.group(len(m.groups()))
        self._metadata["identifier"] = parent_metadata["identifier"] + "." + _name
        self._metadata["function"] = {
            "name":_name,
            "private":_private,
        }

    def process_line(self, line):
        if line.startswith("}"):
            return False
        return True

    def save(self, build):
        return

class ModuleFunctionExtractor(FunctionExtractor):

    def __init__(self, parent, line):
        super().__init__(parent._metadata, line)
        parent.declare_symbol("functions", self._metadata["function"]["name"], self._metadata["identifier"])

class VariableExtractor(Extractor):

    _expression = re.compile(r"^(private\s+){0,1}\s*("
                             r"(\w+)\s*:\s*"
                             r"(\w+)\s*"
                             r"((:{0,1}=)\s*(.*))"
                             r")$"
                             )

    def __init__(self, parent_metadata, line):
        super().__init__(parent_metadata, "variables")
        m = VariableExtractor._expression.match(line)
        _private = m.group(1) is not None and m.group(1).startswith("private")
        _name = m.group(3)
        _type = m.group(4)
        _op = m.group(6)
        _mutable = m.group(6) is not None and _op == ":="
        _remainder = m.group(len(m.groups()))
        # TODO: extends
        self._metadata["identifier"] = parent_metadata["identifier"] + "." + _name
        self._metadata["scope"] = parent_metadata["identifier"]
        self._metadata["variable"] = {
            "type":_type,
            "name":_name,
            "private":_private,
            "mutable":_mutable
        }
        self._lines.append("{}:{} {} {}".format(_name, _type, _op, _remainder))

    def process_line(self, line):
        if re_has_indent.match(line):
            self._lines.append(dedent(line))
            return True
        return False

    def save(self, build):
        return

class ClassExtractor(Extractor):

    _expression = re.compile(r"^(private\s+){0,1}\s*("
                          r"((abstract\s+class)|(class)|(interface)|(structure))"
                          r")\s+(.+)")
    _identifier = re.compile(r"(\w+).*")

    def __init__(self, parent_metadata, line):
        super().__init__(parent_metadata, "classes")
        m = ClassExtractor._expression.match(line)
        _private = m.group(1) is not None and m.group(1).startswith("private")
        remainder = m.group(len(m.groups()))
        _name = ClassExtractor._identifier.match(remainder).group(1)
        self._metadata["identifier"] = parent_metadata["identifier"] + "." + _name
        self._metadata["class"] = {
            "name":_name,
            "private":_private,
        }

    def save(self, build):
        return

class ModuleClassExtractor(ClassExtractor):

    def __init__(self, parent, line):
        super().__init__(parent._metadata, line)
        self._parent = parent
        parent.declare_symbol("classes", self._metadata["class"]["name"], self._metadata["identifier"])

class ModuleVariableExtractor(VariableExtractor):

    def __init__(self, parent, line):
        super().__init__(parent._metadata, line)
        parent.declare_symbol("variables", self._metadata["variable"]["name"], self._metadata["identifier"])

class TypeExtractor(Extractor):

    _expression = re.compile(r"^(private\s+){0,1}\s*("
                             r"(type)|(alias)"
                             r")\s+(.+)$"
                             )

    _identifier = re.compile(r"\s*([^:\{\(\s=]+)(.*)")

    def __init__(self, parent_metadata, line):
        super().__init__(parent_metadata, "types")
        m = TypeExtractor._expression.match(line)
        _private = m.group(1) is not None and m.group(1).startswith("private")
        remainder = m.group(len(m.groups()))
        m = TypeExtractor._identifier.match(remainder)
        _name = m.group(1)
        self._metadata["identifier"] = parent_metadata["identifier"] + "." + _name
        self._metadata["type"] = {
            "name":_name,
            "private":_private
        }

    def process_line(self, line):
        super().process_line(line)
        return False

    def save(self, build):
        return

class ModuleTypeExtractor(TypeExtractor):

    def __init__(self, parent, line):
        super().__init__(parent._metadata, line)
        parent.declare_symbol("types", self._metadata["type"]["name"], self._metadata["identifier"])

class ModuleExtractor(Extractor):

    _expression = re.compile(r'^((module)|(service)|(process)|(restservice))\s+(\w+)\s*\{\s*$')
    _import = re.compile(r'^\s{4}import\s+(.+)')
    _import_from = re.compile(r'^\s{4}import\s+(.*)\sfrom\s+(.+)')

    def __init__(self, parent_metadata, line):
        super().__init__(parent_metadata, "modules")
        m = ModuleExtractor._expression.match(line)
        _name = m.group(len(m.groups()))
        assert _name == str(Path(parent_metadata["source"]["filename"]).stem)
        self._metadata["identifier"] = parent_metadata["identifier"] + "." + _name
        self._metadata["symbols"] = copy.deepcopy(parent_metadata["symbols"])

    def declare_symbol(self, symbol_category, symbol_name, symbol_identifier):
        self._metadata["symbols"][symbol_name] = symbol_identifier

    def get_filename(self, build):
        return str(Path(build) / "modules" / self._metadata["source"]["revision"] / "module")

    def process_line(self, line):
        if ModuleExtractor._import.match(line):
            m = ModuleExtractor._import.match(line)
            import_from = None
            if ModuleExtractor._import_from.match(line):
                x = ModuleExtractor._import_from.match(line)
                without_from = x.group(1)
                import_from = x.group(2)
            else:
                without_from = m.group(1)
            for symbol in without_from.split(","):
                symbol = symbol.strip()
                if re_has_whitespace.match(symbol):
                    symbol = re.split(r"\s+", symbol)[0]
                if import_from is None:
                    symbol = import_from
                    if import_from in self._metadata["symbols"]:
                        import_from = self._metadata["symbols"][import_from]
                    self.declare_symbol("imports", symbol, import_from)
                else:
                    if symbol == "*":
                        if import_from in self._metadata["symbols"]:
                            import_from = self._metadata["symbols"][import_from]
                        self.declare_symbol("imports", "*." + import_from, import_from + ".*")
                    else:
                        if import_from in self._metadata["symbols"]:
                            import_from = self._metadata["symbols"][import_from]
                        import_from = import_from + "." + symbol
                        self.declare_symbol("imports", symbol, import_from)
            return True
        return super().process_line(line)

    def save(self, build):
        extractor = None
        for line in self._lines:
            if extractor is None and re_has_indent.match(line):
                continue
            if extractor is not None:
                if not extractor.process_line(line):
                    extractor.save(build)
                    extractor = None
            elif ModuleVariableExtractor.matches(line):
                extractor = ModuleVariableExtractor(self, line)
            elif ModuleFunctionExtractor.matches(line):
                extractor = ModuleFunctionExtractor(self, line)
            elif ModuleClassExtractor.matches(line):
                extractor = ModuleClassExtractor(self, line)
            elif ModuleTypeExtractor.matches(line):
                extractor = ModuleTypeExtractor(self, line)
        if extractor is not None:
            more = extractor.process_line("")
            assert (not more), "expected the extractor to complete"
            extractor.save(build)
        super().save(build)

if __name__ == "__main__":
    parsed_args = parse_args(sys.argv[1:])
    exit_code = validate_parsed_args(parsed_args)
    if exit_code == 0:
        exit_code = main(parsed_args)
    sys.exit(exit_code)


import argparse

class HackAssembler:
    def __init__(self):
        self.__comp_code = {
            "0": "0101010",
            "1": "0111111",
            "-1": "0111010",
            "D": "0001100",
            "A": "0110000",
            "!D": "0001101",
            "!A": "0110001",
            "-D": "0001111",
            "-A": "0110011",
            "D+1": "0011111",
            "A+1": "0110111",
            "D-1": "0001110",
            "A-1": "0110010",
            "D+A": "0000010",
            "D-A": "0010011",
            "A-D": "0000111",
            "D&A": "0000000",
            "D|A": "0010101",
            "M": "1110000",
            "!M": "1110001",
            "-M": "1110011",
            "M+1": "1110111",
            "M-1": "1110010",
            "D+M": "1000010",
            "D-M": "1010011",
            "M-D": "1000111",
            "D&M": "1000000",
            "D|M": "1010101",
        }
        self.__jump_code = ["", "JGT", "JEQ", "JGE", "JLT", "JNE", "JLE", "JMP"]
        self.__defined_symbols = {
            "SP": 0,
            "LCL": 1,
            "ARG": 2,
            "THIS": 3,
            "THAT": 4,
            "R0": 0,
            "R1": 1,
            "R2": 2,
            "R3": 3,
            "R4": 4,
            "R5": 5,
            "R6": 6,
            "R7": 7,
            "R8": 8,
            "R9": 9,
            "R10": 10,
            "R11": 11,
            "R12": 12,
            "R13": 13,
            "R14": 14,
            "R15": 15,
            "SCREEN": 0x4000,
            "KBD": 0x6000,
        }

    def translate(self, lines: list[str]) -> list[str]:
        return self.__handle_instructions(
            self.__handle_symbols(self.__handle_spaces(self.__handle_comments(lines)))
        )

    def __handle_symbols(self, lines: list[str]) -> list[str]:
        symbols = self.__defined_symbols.copy()
        results: list[str] = []
        for line in lines:
            if line[0] == "(" and line[-1] == ")":
                symbols[line[1:-1]] = len(results)
            else:
                results.append(line)
        counter = 16
        for (idx, line) in enumerate(results):
            if self.__is_a_instruction(line):
                value: str = line[1:]
                if value.isdigit():
                    continue
                if value not in symbols:
                    symbols[value] = counter
                    counter += 1
                results[idx] = line[0] + str(symbols[value])
        return results

    def __translate_dest(self, line: str) -> str:
        result = 0
        if "=" in line:
            dest = line.split("=")[0]
            if "M" in dest:
                result |= 1
            if "D" in dest:
                result |= 1 << 1
            if "A" in dest:
                result |= 1 << 2
        return format(result, "03b")

    def __translate_comp(self, line: str) -> str:
        st = line.index("=") + 1 if "=" in line else 0
        nd = line.index(";") if ";" in line else len(line)
        comp = line[st:nd]
        return self.__comp_code.get(comp)

    def __translate_jump(self, line: str) -> str:
        jump = None
        if ";" in line:
            jump = line.split(";")[1]
        result = self.__jump_code.index(jump or "")
        return format(result, "03b")

    def __is_a_instruction(self, line: str) -> bool:
        return line[0] == "@"

    def __translate_a_instruction(self, line: str) -> str:
        return "0" + format(int(line[1:]), "015b")[-15:]

    def __translate_c_instruction(self, line: str) -> str:
        return (
            "111"
            + self.__translate_comp(line)
            + self.__translate_dest(line)
            + self.__translate_jump(line)
        )

    def __handle_instructions(self, lines: list[str]) -> list[str]:
        result: list[str] = []
        for line in lines:
            if self.__is_a_instruction(line):
                result.append(self.__translate_a_instruction(line))
            else:
                result.append(self.__translate_c_instruction(line))
        return result

    def __handle_spaces(self, lines: list[str]) -> list[str]:
        return ["".join(line.split()) for line in lines if line.strip()]

    def __handle_comments(self, lines: list[str]) -> list[str]:
        return [line.split("//")[0] for line in lines]

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Translate Hack assembly code to Hack binary code"
    )
    parser.add_argument("asm", help="filepath of Hack assembly code")
    args = parser.parse_args()

    filepath: str = args.asm
    assert filepath.endswith(".asm"), f"{filepath} doesn't end with .asm"

    output: str = filepath.rstrip(".asm") + ".hack"
    assembler: HackAssembler = HackAssembler()
    with open(filepath, "r") as input_file:
        code: list[str] = input_file.read().splitlines()
        with open(output, "w") as output_file:
            output_file.write("\n".join(assembler.translate(code)))


from kelimeler import sozluk

"""
eksik yada yanlış yazılan kelimeyi tespit ederek sözlükteki en yakın kelimelerin listesini döner.
"""

def duzelten(cumle):
    duzelenCumle=[]#düzeltilen kelimelerin listesini içerir.
    donenCumle=""
    cumle=cumle.split()

    for i in range(len(cumle)):

        tek=0
        sayac=0
        for j in range(len(sozluk)):

            if(tek==0):
                for k in range(len(cumle[i])):
                    if(k==0 and cumle[i]==sozluk[j][0]):
                        duzelenCumle.append(cumle[i])
                        tek=1
                        sayac=sayac+1
                    elif cumle[i][:-k]==sozluk[j][0]:
                        duzelenCumle.append(cumle[i])
                        tek=1
                        sayac=sayac+1
        if sayac==0:
            donen=istatistik(cumle[i])
            duzelenCumle.append(donen)

    for i in range(len(duzelenCumle)):
        for j in range(len(duzelenCumle[i])):
            donenCumle+=duzelenCumle[i][j]+" "
    return donenCumle

def istatistik(kelime):#eksik yada yanlış kelimeye en yakın olan kelimeleri bulur.
    sayac=[]
    duzelenler=[]#duzeltilen cumleleri tutar.
    count=0
    icerik=[]

    for i in range(len(kelime)):
        sayac+=kelime[i]

    for j in range(len(sozluk)):
        for k in range(min(len(sozluk[j][0]),len(sayac))):
            for t in range(min(len(sozluk[j][0]),len(sayac))):
                if t==k :
                    if sayac[t]==sozluk[j][0][k]:
                        count+=1

        count=(count/min(len(sozluk[j][0]),len(sayac)))*100#benzerlik oranı için yüzdelik durumu belirler.

        if (count>40 and len(sozluk[j][0])>=len(kelime)):#harflerin frekans benzerliğine göre %40 oranında benzer olanları seçer.
            if (count<100):

                duzelenler.append(sozluk[j][0])
        count=0
    icerik.append("]")
    icerik.append("!*")
    icerik.append(kelime)
    icerik.append("için onerilenler;")
    for i in range(len(duzelenler)):
        icerik.append(duzelenler[i])
        icerik.append("-")
    icerik.append("]")

    return icerik


import json
import os
import string
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
import urllib.request

options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
options.add_experimental_option("prefs", {
                                "profile.password_manager_enabled": False, "credentials_enable_service": False, 'profile.default_content_settings.popups': 0})

def initCheckPoint() -> None:
    with open('checkPoint.json', 'r') as f:
        checkPoint = json.load(f)
    for key in checkPoint:
        checkPoint[key] = False
    with open('checkPoint.json', 'w') as f:
        json.dump(checkPoint, f)
    return None

def loadCheckPoint() -> dict:
    with open('checkPoint.json', 'r') as f:
        checkPoint = json.load(f)
    return checkPoint

def saveCheckPoint(checkPoint: dict) -> None:
    with open('checkPoint.json', 'w') as f:
        json.dump(checkPoint, f)
    return None

def main():
    # initCheckPoint()

    url = 'https://judgegirl.csie.org/problems/domain/0'

    # load dict of checkPoint in json file
    checkPoint = loadCheckPoint()

    # put r in a text file
    if not checkPoint['get problemSet']:
        with open('text.txt', 'w', encoding='UTF-8') as f:
            r = requests.get(url)
            # encode r into string
            f.write(r.text)

        # read text file
        # save all text between <li class="pure-menu-item" and
 into a another text file
        with open('text.txt', 'r', encoding='UTF-8') as f:
            with open('problemSet.txt', 'w', encoding='UTF-8') as f2:
                for line in f:
                    if '<li class="pure-menu-item" data=' in line:
                        while '
' not in line:
                            f2.write(line)
                            line = f.readline()
                        f2.write(line)

        # delete text file
        os.remove('text.txt')

        # read problemSet.txt and save all problemSet id into a another text file
        with open('problemSet.txt', 'r', encoding='UTF-8') as f:
            with open('problemSetId.txt', 'w', encoding='UTF-8') as f2:
                for line in f:
                    if 'data="' in line:
                        f2.write(line[line.find('#'):-3])
                        f2.write('  ')
                        continue
                    if '
' in line:
                        # fine the first alpha index
                        start = 0
                        for i in range(len(line)):
                            if line[i].isalpha():
                                start = i
                                break
                        # replace all '/' with ''
                        target = line[start:-10]
                        target = target.replace('/', '')

                        if target.find('  ') > 4:
                            continue

                        f2.write(target)
                        f2.write('\n')

        # delete problemSet.txt
        os.remove('problemSet.txt')
        checkPoint['get problemSet'] = True
        saveCheckPoint(checkPoint)

    # read problemSetId.txt
    if not checkPoint['get problemId']:
        with open('problemSetId.txt', 'r', encoding='UTF-8') as f:
            # create a folder named the text after '  ' of each line
            for line in f:
                # test if the folder already exists

                folderName = line[line.find('  ')+2:-1]

                if not os.path.exists(folderName):
                    os.mkdir(folderName)

                driver = webdriver.Chrome(
                    'chromedriver.exe', chrome_options=options)
                driver.minimize_window()
                # create a file named Description.txt in each folder
                with open(folderName+'/Description.txt', 'w', encoding='UTF-8') as f2:
                    # goto the problemSet page
                    url = 'https://judgegirl.csie.org/problems/domain/0' + \
                        line[0:line.find('  ')]
                    driver.get(url)
                    # wait for the page to load
                    # driver.implicitly_wait(3)
                    elements = driver.find_elements(
                        By.CLASS_NAME, 'problem-item')
                    # write element into Description.txt
                    for element in elements:
                        print(element.text)
                        f2.write(element.text)
                        f2.write('\n')

                driver.close()
                driver.quit()
        checkPoint['get problemId'] = True
        saveCheckPoint(checkPoint)

    url = 'https://judgegirl.csie.org/problem/0'

    if not checkPoint['get problems']:
        # go to each problemSet folder in problemSetId.txt
        folderNames = list()
        with open('problemSetId.txt', 'r', encoding='UTF-8') as f:
            for line in f:
                folderNames.append(line[line.find('  ')+2:-1])

        problemSets = dict()
        for folderName in folderNames:
            with open(folderName + '/Description.txt', 'r', encoding='UTF-8') as f:
                problemSets[folderName] = list()
                for line in f:
                    problemSets[folderName].append(line[0:-1])

        for key in problemSets:
            for problem in problemSets[key]:
                title = problem
                id = problem[0:problem.find(' ') - 1]
                # if the last character of title is a punctuation, delete it
                if title[-1] in string.punctuation:
                    title = title[:-1]
                # replace all '/' with ' '
                title = title.replace('/', ' ')
                if title in checkPoint and checkPoint[title]:
                    continue

                print('Now downloading ' + title)

                driver = webdriver.Chrome(
                    'chromedriver.exe', chrome_options=options)
                driver.minimize_window()
                # goto the problem page
                url = 'https://judgegirl.csie.org/problem/0/' + id
                driver.get(url)
                # wait for the page to load
                # driver.implicitly_wait(3)

                if not os.path.exists(key+'/'+title):
                    os.mkdir(key+'/'+title)
                with open(key+'/'+title+'/Description.txt', 'w', encoding='UTF-8') as f:
                    f.write(driver.find_element(By.CLASS_NAME, 'content').text)

                # open the file with read and write permission
                with open(key+'/'+title+'/Description.txt', 'r', encoding='UTF-8') as f:
                    start = end = 0
                    for index, line in enumerate(f):
                        if 'Task Description' in line:
                            start = index
                        if 'Submit' in line:
                            end = index
                            break

                    # goto th top of the file
                    f.seek(0)
                    # save the line between start and end into newFile
                    newFile = f.readlines()[start:end]

                with open(key+'/'+title+'/Description.txt', 'w', encoding='UTF-8') as f2:
                    # clear the file
                    f2.truncate()
                    # write the new file
                    for line in newFile:
                        f2.write(line)

                # find the photo and save it
                photos = driver.find_elements(
                    By.CLASS_NAME, 'pure-img-responsive')
                if len(photos) != 0:
                    for index, photo in enumerate(photos):
                        link = photo.get_attribute('src')
                        # save the phot
                        if 'https://judgegirl.csie.org/images/problems/' in link:
                            urllib.request.urlretrieve(link, key+'/'+title+'/'+link[44:])

                if not os.path.exists(key+'/'+title+'/testCases'):
                    os.mkdir(key+'/'+title+'/testCases')
                # find the elements that inside text is 'Download Testdata' by XPATH
                link = 'https://judgegirl.csie.org/testdata/download/' + id
                print(title)
                print(url)
                print(link)
                # goto the testCase page
                driver.get(link)
                # wait for the page to load
                # driver.implicitly_wait(3)

                content = driver.find_element(By.CLASS_NAME, 'content')
                menu = content.find_element(By.CLASS_NAME, 'pure-g')
                cases = menu.find_elements(By.CLASS_NAME, 'pure-menu-link')

                # download each testCase
                for case in cases:
                    url = case.get_attribute('href')
                    file = requests.get(url)
                    with open(key+'/'+title+'/testCases/'+case.text, 'wb') as f:
                        f.write(file.content)

                driver.close()
                driver.quit()

                checkPoint[title] = True
                saveCheckPoint(checkPoint)
        checkPoint['get problems'] = True
        saveCheckPoint(checkPoint)

    # check if all checkPoint is True
    for key in checkPoint:
        if not checkPoint[key]:
            print(key+' is not finished')
            return None
    print('all checkPoint is finished')
    return None

if __name__ == '__main__':
    main()


w, w_unit = input("Weight : ").split()
h, h_unit = input("Height : ").split()

w, h = float(w), float(h)

# w Convert
if w_unit == "lbs":
    # Convert lbs to kg
    w /= 2.205

# h Convert
if h_unit == "ft":
    # Convert ft to m
    h /= 3.2808399
elif h_unit == "cm":
    # Convert cm to m
    h /= 100

# Calculate BMI
bmi = w / (h ** 2)

if bmi < 18.5:
    print("ผอม")
elif bmi < 23.0:
    print("รุปร่างปกติ")
elif bmi < 25.0:
    print("รูปร่างอ้วน")
elif bmi < 30.0:
    print("อ้วนระดับ 1")
else:
    print("อ้วนระดับ 2")


from django.db import models
from django.conf import settings

from ..querysets.resource import ResourceQuerySet

class ResourceManager(models.Manager):
    queryset_class = ResourceQuerySet

    def get_queryset(self):
        return self.queryset_class(self.model, using=self._db)

    def filter_by_project(self, project):
        return self.get_queryset().filter_by_project(project)

    def filter_by_assignment(self, assignment):
        return self.get_queryset().filter_by_object(assignment)

    def create_resource(
            self, user_from, root_name, name, extension, content_type, *args, **kwargs
    ):
        new_node = self.create(
            created_by=user_from,
            name=name,
            extension=extension,
            mimetype=content_type,
            _filename=root_name,
            link=kwargs.get('link'),
            description=kwargs.get('description'),
            file_size=kwargs.get('file_size', None),
        )

        return new_node

    def create_user_resource(self, user_from, team, related, **kwargs):
        new_resource = self.model(
            created_by=user_from,
            **kwargs
        )
        new_resource.save(tag_original=settings.FILES_USER_TAG)
        related.add_user_resource(user_from, team, new_resource)
        return new_resource


import os
import re
import xlwt
from tkinter import *
from tkinter.filedialog import askdirectory
from xlwt import Workbook
root=Tk()
root.withdraw()
path=askdirectory()
print(path)
file_names=os.listdir(str(path))
name_lists=[]
output=[]
for file in file_names:
    file_path=path + '/' + file
    f=open(file_path,'r',encoding='utf-8',errors='ignore')
    data=f.read()
    data=data.strip()
    mhs=re.search(r'Summary((.|\s)*)',data)
    if mhs:
        data=mhs.group(1)
        rows=data.split('\n')
        for row in rows:
            if row.strip() and row.strip()!='|':
                mhs=re.search(r'(([a-zA-Z]+\s)+)\s+.*?(\d+\.\d+)',row)
                if mhs:
                    output.append([file,mhs.group(1),mhs.group(3)])
    else:
        output.append([file,'N/A','N/A'])
book=Workbook(encoding='utf-8')
sht1=book.add_sheet('sheet1')
for i in range(len(output)):
    for j in range(len(output[1])):
        sht1.write(i,j,output[i][j])
book.save('./output_data.xls')
print("over")


# -*- coding: utf-8 -*-

def validate(f):
    names = ['narrow-bold', 'wide-bold', 'narrow-thin', 'wide-thin']
    if f is None:
        return
    for n in names:
        g = f[n]
        print(g.name, len(g.contours))
        for c in g.contours:
            print(g.name, len(c))

if __name__ == "__main__":
    f = CurrentFont()
    validate(f)


class Solution:

    def lengthOfLongestSubstring(self, s: str) -> int:
        ans = 0
        start = 0
        tracker = {}

        for end, char in enumerate(s):
            if char in tracker:
                start = max(start, tracker[char] + 1)

            tracker[char] = end

            ans = max(ans, end - start + 1)

        return ans


"""
Test the lookup_specs_chain

NOTE: this just makes sure the chain executes properly but DOES NOT assess the quality of the agent's analysis. That is done in the ipython notebooks in the evals/ folder
"""
import pytest
import json
from meche_copilot.get_equipment_results import get_spec_lookup_data, get_spec_page_validations
from meche_copilot.chains.analyze_specs_chain import AnalyzeSpecsChain
from meche_copilot.chains.helpers.specs_retriever import SpecsRetriever
from meche_copilot.schemas import *
from meche_copilot.utils.chunk_dataframe import chunk_dataframe
from meche_copilot.utils.config import load_config, find_config

# Used for verbose output of langchain prompts and responses
from langchain.callbacks import StdOutCallbackHandler

@pytest.mark.skip(reason="TODO - desiding if I want to use analyze specs chain or lookup specs chain...probably analyze specs chain")
def test_lookup_specs_chain(session:Session):
    sess = session
    config = session.config

    # a piece of equipment (idx 2: fan eq)
    eq = sess.equipments[2]

    # empty_eq_str_srcA, empty_eq_str_srcB = get_spec_lookup_data(eq)

    empty_eq_df = eq.instances_to(ScopedEquipment.IOFormats.df)
    spec_defs_df = eq.spec_defs_to(ScopedEquipment.IOFormats.df)

    concated = pd.concat([spec_defs_df.T, empty_eq_df])

    retriever = SpecsRetriever(doc_retriever=config.doc_retriever, source=eq.sourceA)
    relavent_docs = retriever.get_relevant_documents(query="")
    relavent_ref_docs_as_dicts = [doc.dict() for doc in relavent_docs]
    relavent_ref_docs_as_string = json.dumps(relavent_ref_docs_as_dicts)  # Convert to JSON string

    # lookup specs for source A
    lookup_chain = AnalyzeSpecsChain(
        doc_retriever=sess.config.doc_retriever,
        spec_reader=sess.config.spec_reader,
        callbacks=[StdOutCallbackHandler()]
    )

    result_sourceA = lookup_chain.run({
        "source": eq.sourceA,
        # "refresh_source_docs": False
        # "spec_def_df": spec_defs_df,
        "spec_res_df": concated,
    })

    from langchain.schema import AIMessage, HumanMessage, SystemMessage
    messages = [
        SystemMessage(
            content=f"For each key in results_json, find the corresponding spec in the Context using the definition and replace 'None' with correct value. Context: {relavent_ref_docs_as_string}"
        ),
        HumanMessage(
            content=f"results_json={concated.iloc[:, 0:5].to_json()}"
        ),
    ]
    lookup_chain.chat(messages)

    result_sourceA

    result_sourceA_validated = get_spec_page_validations(val_pg=result_sourceA, ref_docs=eq.sourceA.ref_docs)


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

import sys
import glob
import logging
import argparse

from ngsmetavirus.config import *
from ngsmetavirus.common import check_path, mkdir, read_tsv
from dagflow import DAG, Task, do_dag

LOG = logging.getLogger(__name__)
__version__ = "1.0.0"
__author__ = ("Xingguo Zhang",)
__email__ = "invicoun@foxmail.com"
__all__ = []

def create_merge_data_task(prefix, read1, read2, work_dir, job_type="local"):

    if len(read1)==1:
        comm1 = """\
ln -s {read1} {prefix}.raw.R1.fq.gz
ln -s {read2} {prefix}.raw.R2.fq.gz
""".format(read1=read1[0], read2=read2[0], prefix=prefix)
    else:
        comm1 = """\
cat {read1} >{prefix}.raw.R1.fq.gz
cat {read2} >{prefix}.raw.R2.fq.gz
""".format(read1=" ".join(read1), read2=" ".join(read2), prefix=prefix)

    task = Task(
        id="merge_data_%s" % prefix,
        work_dir=work_dir,
        type=job_type,
        option="-pe smp 1",
        script="""
{comm1}
""".format(comm1=comm1)
    )
    read1 = os.path.join(work_dir, "%s.raw.R1.fq.gz" % prefix)
    read2 = os.path.join(work_dir, "%s.raw.R2.fq.gz" % prefix)

    return task, read1, read2

def create_mngs_task(prefix, read1, read2, reference, nohost, dtype, atype,
                     job_type, work_dir, out_dir, trim=0, project="", id=""):

    if nohost:
        nohost = "--nohost"
    else:
        nohost = ""
    if reference:
        rx = "--reference %s" % reference
    else:
        rx = ""

    task = Task(
        id="mngs_%s" % prefix,
        work_dir=work_dir,
        type="local",
        option="-pe smp 1",
        script="""
{root}/ngsmetavirus.py all \\
  --prefix {prefix} --read1 {read1} --read2 {read2} \\
  --dtype {dtype} --atype {atype} {rx} \\
  --project {project} --id {id} \\
  --trim {trim} --thread 6 --job_type {job_type} {nohost} \\
  --work_dir {work}  --out_dir {out}
""".format(root=ROOT,
            prefix=prefix,
            read1=read1,
            read2=read2,
            rx=rx,
            nohost=nohost,
            dtype=dtype,
            atype=atype,
            trim=trim,
            project=project,
            id=id,
            job_type=job_type,
            work=work_dir,
            out=out_dir
        )
    )

    return task

def run_mngs_multi(input, reference, nohost, dtype, atype, trim, job_type,
                   concurrent, refresh, work_dir, out_dir, project="", id=""):

    input = check_path(input)
    work_dir = mkdir(work_dir)
    out_dir = mkdir(out_dir)

    if not reference:
        pass
    else:
        try:
            reference = check_path(check_path)
        except:
            reference = check_path("%s.3.ht2" % reference)
            reference = reference.strip(".3.ht2")
        else:
            raise Exception("Reference genome %s does not exist" % reference)

    data = {}

    for line in read_tsv(input):
        if line[0] not in data:
            data[line[0]] = [[], []]
        data[line[0]][0].append(check_path(line[1]))
        data[line[0]][1].append(check_path(line[2]))

    dag = DAG("mngs_multi")

    for prefix in data:

        prefix_work = mkdir(os.path.join(work_dir, prefix))
        data_task, read1, read2 = create_merge_data_task(
            prefix=prefix,
            read1=data[prefix][0],
            read2=data[prefix][1],
            work_dir=prefix_work
        )
        dag.add_task(data_task)
        task = create_mngs_task(
            prefix=prefix,
            read1=read1,
            read2=read2,
            reference=reference,
            nohost=nohost,
            dtype=dtype,
            atype=atype,
            trim=trim,
            job_type=job_type,
            project=project,
            id=id,
            work_dir=prefix_work,
            out_dir=mkdir(os.path.join(out_dir, prefix))
        )
        dag.add_task(task)
        task.set_upstream(data_task)

    do_dag(dag, concurrent, refresh)

    return 0

def mngs_multi(args):

    run_mngs_multi(
        input=args.input,
        reference=args.reference,
        nohost=args.nohost,
        dtype=args.dtype,
        atype=args.atype,
        trim=args.trim,
        work_dir=args.work_dir,
        out_dir=args.out_dir,
        concurrent=args.concurrent,
        refresh=args.refresh,
        job_type=args.job_type,
        project=args.project,
        id=args.id
    )

def add_mngs_multi_args(parser):

    parser.add_argument("input", metavar='FILE', type=str,
        help="Input the reads list.")
    parser.add_argument("-ref", "--reference", metavar="FILE", type=str, default="",
        help="Input the host's reference database.")
    parser.add_argument('--nohost', action='store_true',
        help='Input the reference database is not the host.')
    parser.add_argument("-dt", "--dtype", metavar='STR', type=str,
        choices=["mgi", "illumina", "other"], default="illumina",
        help="Set up the sequencing platform of the data, default=illumina.")
    parser.add_argument("-at", "--atype", metavar='STR', type=str,
        choices=["metagenome", "metaviral", "rnaviral"], default="metagenome",
        help="""Set the type of analysis(metagenome, metavirus, rnaviral),\
              default=metagenome.""")
    parser.add_argument("--trim", metavar="INT", type=int, default=5,
        help="Set trim length, default=5")
    parser.add_argument("--project", metavar="STR", type=str, required=True,
        help="Input project name.")
    parser.add_argument("--id", metavar="STR", type=str, required=True,
        help="Input project id.")
    parser.add_argument("--concurrent", metavar="INT", type=int, default=10,
        help="Maximum number of jobs concurrent  (default: 10).")
    parser.add_argument("--refresh", metavar="INT", type=int, default=30,
        help="Refresh time of log in seconds  (default: 30).")
    parser.add_argument("--job_type", choices=["sge", "local"], default="local",
        help="Jobs run on [sge, local]  (default: local).")
    parser.add_argument("--work_dir", metavar="DIR", type=str, default=".",
        help="Work directory (default: current directory).")
    parser.add_argument("--out_dir", metavar="DIR", type=str, default=".",
        help="Output directory (default: current directory).")

    return parser

def main():

    logging.basicConfig(
        stream=sys.stderr,
        level=logging.INFO,
        format="[%(levelname)s] %(message)s"
    )

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description="""
attention:
    ngsmetavirus.py.py multi input.list
File format：
name    R1  R2

version: %s
contact:  %s <%s>\
    """ % (__version__, " ".join(__author__), __email__))

    parser = add_mngs_multi_args(parser)
    args = parser.parse_args()
    mngs_multi(args)

if __name__ == "__main__":
    main()


# lcp Core
# iMagineLab - Living Character Program
from lcp.core.module_loader import ModuleLoader
from lcp.core.lcp_system_configurator import SystemConfigurator
import time

class LCPCore(object):
    __version = "0.1"

    def __init__(self):
        print("LCP Core - Version", self.__version)
        print(">> Initialising system...")
        self.__SystemConfig = SystemConfigurator()
        self.__SystemConfig.load_config("..\\..\\..\\resources\\config.ini")

        print(">> Loading character configuration...")
        # lcp character configuration

        print(">> Start module loader...")
        self.__MLoader = ModuleLoader(self.__SystemConfig.get_module_config('ModuleLoader'))
        self.__MLoader.load_modules(self.__SystemConfig)

    def start(self):
        print(">> Booting core...")

        print(">> Booting modules...")
        self.__MLoader.start_modules()

        time.sleep(1)

        print(">> System ready")

        while 1:
            time.sleep(1)

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


class Solution:
    def isPalindrome(self, src: int) -> bool:
        """
        处理回文，不采用字串转型的方式。
        如果小于正整数则返回 Fasle，否则透过取得不断除以 10 取得商数来判断循环是否到底。
        而获得的余数的方式放入阵列，待完成后透过阵列来做寻访 [::-1] 判断是否相符
        """
        slices = []
        if src < 0:
            return False
        while(src != 0):
            remainder = src % 10
            src = src // 10
            slices.append(remainder)
        if slices[::-1] == slices:
            return True
        return False


def main():
    cities = placeRecordsIntoList("Cities.txt")
    # Sort list by percentage population growth.
    cities.sort(key=lambda city: (city[3] - city[2])/city[2], reverse=True)
    createNewFile(cities)  # Create file of cities and their % growth.

def placeRecordsIntoList(fileName):
    infile = open(fileName, 'r')
    listOfRecords = [line.rstrip() for line in infile]
    infile.close()
    for i in range(len(listOfRecords)):
        listOfRecords[i] = listOfRecords[i].split(',')
        listOfRecords[i][2] = eval(listOfRecords[i][2])  # population in 2000
        listOfRecords[i][3] = eval(listOfRecords[i][3])  # population in 2010
    return listOfRecords

def createNewFile(cities):
     outfile = open("OrderedCities.txt", 'w')
     for city in cities:
         outfile.write(city[0] + ',' +
                   str(round(100*((city[3] - city[2])/city[2]),1)) + "\n")
     outfile.close()

main()


import itertools
import tqdm
import subprocess

def add_to_seq(seq, feature, label):
    if label[0] == 'B':
        seq.append(feature)
    elif label[0] == 'I':
        if len(seq) > 0:
            seq[-1] += feature
        else:
            seq.append(feature)
    elif label[0] == 'S':
        seq.append(feature)

def cal(predict_seq, right_seq):
    r"""
    :return: 分词正确的个数，错误个数，总单词个数，该句子是否分词正确
    """
    # flag 表示全部正确
    flag = 1
    num_right_word = 0

    if len(predict_seq) != len(right_seq):
        flag = 0

    for feat in predict_seq:
        if feat in right_seq:
            num_right_word += 1
        else:
            flag = 0

    return num_right_word, len(predict_seq) - num_right_word, len(right_seq), flag

def evaluate(model, dataset_loader, idx2feature, idx2label, device, log_file):
    r"""
    计算数据集上的F1, P, R值

    :return: F1, accuracy
    """
    model.eval()

    num_sentence = 0
    num_right_sentence = 0

    num_all_word = 0
    num_right_word = 0
    num_error_word = 0

    for _, batch in tqdm.tqdm(enumerate(itertools.chain.from_iterable(dataset_loader))):
        batch = tuple(t.to(device) for t in batch)
        features, labels, masks = batch

        scores, paths = model(features, masks)

        num_sentence += features.shape[0]
        length = features.shape[1]
        for i, (sentence, label) in enumerate(zip(features, labels)):
            predict_seq = []
            right_seq = []
            for j, tensor_feat in enumerate(sentence):
                if j == length or masks[i][j] == 0:
                    # 会有一个<eof>标志
                    nums = cal(predict_seq, right_seq)

                    num_right_word += nums[0]
                    num_error_word += nums[1]
                    num_all_word += nums[2]
                    num_right_sentence += nums[3]

                    break
                else:
                    feature = idx2feature[tensor_feat.item()]
                    predict_label = idx2label[paths[i][j].item()]
                    right_label = idx2label[label[j].item()]

                    add_to_seq(predict_seq, feature, predict_label)
                    add_to_seq(right_seq, feature, right_label)

    P = num_right_word / (num_error_word + num_right_word)
    R = num_right_word / (num_all_word)
    F1 = (2 * P * R) / (P + R)
    ER = num_error_word / num_all_word

    print(
        '标准词数：%d个，词数正确率：%f个，词数错误率：%f' % (num_all_word, num_right_word / num_all_word, num_error_word / num_all_word))
    print('标准行数：%d，行数正确率：%f' % (num_sentence, num_right_sentence / num_sentence))
    print('Recall: %f' % (R))
    print('Precision: %f' % (P))
    print('F1 MEASURE: %f' % (F1))
    print('ERR RATE: %f' % (ER))

    with open(log_file, 'a') as f:
        f.write(
            '标准词数：%d个，词数正确率：%f个，词数错误率：%f\n' % (
                num_all_word, num_right_word / num_all_word, num_error_word / num_all_word))
        f.write('标准行数：%d，行数正确率：%f\n' % (num_sentence, num_right_sentence / num_sentence))
        f.write('Recall: %f\n' % (R))
        f.write('Precision: %f\n' % (P))
        f.write('F1 MEASURE: %f\n' % (F1))
        f.write('ERR RATE: %f\n\n\n' % (ER))

    return P, R, F1, ER

def evaluate_with_perl(gold_file, predict_file, log=None, epoch=0, loss=None, dev=True):
    r"""
    这个效率高

    :param gold_file:
    :param predict_file:
    :return:
    """
    perl_path = r'/home/yxu/Seg_ner_pos/icwb2-data/scripts/score'
    word_list = r'/home/yxu/Seg_ner_pos/icwb2-data/gold/pku_training_words.utf8'
    p = subprocess.Popen(['perl', perl_path, word_list, gold_file, predict_file], stdout=subprocess.PIPE)
    output = p.stdout.read()
    output = output.decode(encoding='utf8')
    outputs = output.split('\n')
    p.kill()
    res = outputs[-15:]
    dev_R, dev_P, dev_F1 = float(res[-8].split('\t')[-1]), float(res[-7].split('\t')[-1]), float(
        res[-6].split('\t')[-1])

    if log is not None:
        with open(log, 'a') as f:
            f.write('EPOCH : %d\n' % epoch)

            if dev:
                f.write('Dev\n')
            else:
                f.write('Train\n')

            if loss is not None:
                f.write('Epoch loss : %f\n' % loss)

            for j in res:
                print(j)
                f.write(j + '\n')
    else:
        for j in res:
            print(j)

    return dev_R, dev_P, dev_F1

def predict_write(model, dataset_loader, idx2feature, idx2label, device, tmp_file='./tmp', origin_texts=None):
    r"""
    返回一个临时的预测文件

    :param model:
    :param dataset_loader:
    :param idx2feature:
    :param idx2label:
    :param device:
    :param tmp_file:
    :return:
    """
    # !!
    model.eval()

    with open(tmp_file, 'w') as f:
        for idx, batch in tqdm.tqdm(enumerate(itertools.chain.from_iterable(dataset_loader))):
            batch = tuple(t.to(device) for t in batch)
            features, labels, masks = batch
            features_v, labels_v, masks_v = features.transpose(0, 1), labels.transpose(0, 1), masks.transpose(0, 1)
            scores, predict_labels = model.predict(features_v, masks_v)
            batch_size = labels.shape[0]
            # 原始文本内容，避免最终结果出现<unk>
            if origin_texts:
                origin_text = origin_texts[idx * batch_size:(idx + 1) * batch_size]

            for j in range(batch_size):
                if origin_texts:
                    origin_line = origin_text[j]

                feature, predict_label, mask = features[j], predict_labels[j], masks[j]
                line = ''
                length = feature.shape[0]
                for k in range(length):
                    if k + 1 == length or mask[k + 1].item() == 0:
                        break
                    else:
                        if origin_texts:
                            content = origin_line[k]
                        else:
                            content = idx2feature[feature[k].item()]

                        if idx2label[predict_label[k].item()][0] in ('B', 'S') and k != 0:
                            line += ' ' + content
                        else:
                            line += content
                f.write(line + '\n')

    return tmp_file

def read_line(f):
    '''
        读取一行，并清洗空格和换行
    '''
    line = f.readline()
    return line.strip()

def evaluate_by_file(real_text_file, pred_text_file, prf_file, epoch):
    file_gold = open(real_text_file, 'r', encoding='utf8')
    file_tag = open(pred_text_file, 'r', encoding='utf8')

    line1 = read_line(file_gold)
    N_count = 0  # 将正类分为正或者将正类分为负
    e_count = 0  # 将负类分为正
    c_count = 0  # 正类分为正
    e_line_count = 0
    c_line_count = 0

    while line1:
        line2 = read_line(file_tag)

        list1 = line1.split(' ')
        list2 = line2.split(' ')

        count1 = len(list1)  # 标准分词数
        N_count += count1
        if line1 == line2:
            c_line_count += 1  # 分对的行数
            c_count += count1  # 分对的词数
        else:
            e_line_count += 1
            count2 = len(list2)

            arr1 = []
            arr2 = []

            pos = 0
            for w in list1:
                arr1.append(tuple([pos, pos + len(w)]))  # list1中各个单词的起始位置
                pos += len(w)

            pos = 0
            for w in list2:
                arr2.append(tuple([pos, pos + len(w)]))  # list2中各个单词的起始位置
                pos += len(w)

            for tp in arr2:
                if tp in arr1:
                    c_count += 1
                else:
                    e_count += 1

        line1 = read_line(file_gold)

    R = float(c_count) / N_count
    P = float(c_count) / (c_count + e_count)
    F = 2. * P * R / (P + R)
    ER = 1. * e_count / N_count

    print("result:")
    print('标准词数：%d个，词数正确率：%f个，词数错误率：%f' % (N_count, c_count / N_count, e_count / N_count))
    print('标准行数：%d，行数正确率：%f，行数错误率：%f' % (c_line_count + e_line_count, c_line_count / (c_line_count + e_line_count),
                                         e_line_count / (c_line_count + e_line_count)))
    print('Recall: %f' % (R))
    print('Precision: %f' % (P))
    print('F MEASURE: %f' % (F))
    print('ERR RATE: %f' % (ER))

    # print P,R,F

    f = open(prf_file, 'a', encoding='utf-8')
    f.write('result-(epoch:%s):\n' % epoch)
    f.write('标准词数：%d，词数正确率：%f，词数错误率：%f \n' % (N_count, c_count / N_count, e_count / N_count))
    f.write('标准行数：%d，行数正确率：%f，行数错误率：%f \n' % (c_line_count + e_line_count, c_line_count / (c_line_count + e_line_count),
                                              e_line_count / (c_line_count + e_line_count)))
    f.write('Recall: %f\n' % (R))
    f.write('Precision: %f\n' % (P))
    f.write('F MEASURE: %f\n' % (F))
    f.write('ERR RATE: %f\n' % (ER))
    f.write('====================================\n')

    return P, R, F


times = int(input())

a, d =[],[]

counta = 100
countd = 100

for i in range(times):
    ap,dp = input().split(" ")
    a.append(int(ap))
    d.append(int(dp))
    if int(a[i]) > int(d[i]):
        countd -= int(a[i])
        counta = counta
    elif int(a[i]) < int(d[i]):
        countd = countd
        counta -= int(d[i])
    elif int(a[i]) < int(d[i]):
        counta = counta
        countd = countd

print (counta)
print (countd)


'''
ME 598 CUDA
Homework 2
Author: Hien (Ryan) Nguyen
Last modified: 01/28/2018
'''

import numpy as np  # import scientific computing library
import matplotlib.pyplot as plt  # import plotting library
from numba import cuda
import math
import time
from mpl_toolkits import mplot3d

''' Question 2 functions '''
def f2D (x, y):
    return math.sin ( np.pi *x)* math.sinh ( np.pi *y)/ math.sinh ( np.pi )

def fArray2D (x, y):
    nx = x.size
    ny = y.size
    f = np.empty ((nx ,ny), dtype = np.float32)
    for i in range (nx):
        for j in range (ny):
            f[i,j] = f2D (x[i], y[j])
        return f

@cuda.jit ( device = True )
def pf2D (x, y):
    return math.sin ( np.pi *x)* math.sinh ( np.pi *y)/ math.sinh ( np.pi )

@cuda.jit ('void (f4 [:] , f4 [:] , f4 [: ,:])')
def pfKernel2D (d_x , d_y , d_f):
    i , j = cuda.grid (2)
    nx , ny = d_f.shape
    if i < nx and j < ny:
        d_f[i,j] = pf2D (d_x[i], d_y[j])

def pfArray2D (x, y, TPBX, TPBY):

    nx = x.size
    ny = y.size
    d_x = cuda.to_device(x)
    d_y = cuda.to_device(y)
    d_f = cuda.device_array((nx, ny), dtype=np.float32)
    gridDims = ((nx + TPBX - 1) // TPBX,
                (ny + TPBY - 1) // TPBY)
    blockDims = (TPBX, TPBY)

    startTime = time.time()
    pfKernel2D[gridDims, blockDims](d_x, d_y, d_f)
    kTime = (time.time() - startTime) * 1000
    print ("Kernal call time is: ", kTime)
    return d_f.copy_to_host()

def question2():
    print ()
    print ("---------- Question 2 ----------")

    TPBX = 8
    TPBY = 32
    NX = np.linspace(100, 1000, 10)
    NY = np.linspace(100, 1000, 10)

    sTime = [0]*len(NX)
    pTime = [0]*len(NX)
    accel = [0]*len(NX)

    for i in range(len(NX)):
        print ("Array size: ", NX[i])
        x = np.linspace (0,1,NX[i] , dtype = np.float32)
        y = np.linspace (0,1,NY[i] , dtype = np.float32)
        startTime = time.time()
        fs = fArray2D (x, y)
        sTime[i] = (time.time() - startTime) * 1000
        print ("Series processing time: ", sTime[i])

        startTime = time.time()
        fp = pfArray2D(x, y, TPBX, TPBY)
        pTime[i] = (time.time() - startTime) * 1000
        print ("Parallel processing time: ", pTime[i])

        accel[i] = sTime[i]/pTime[i]
        print ("Accel is: ", accel[i])

    plt.figure(1)
    plt.subplot(211)
    plt.plot(NX, sTime, 'r--', label='series runtime')
    plt.plot(NX, pTime, 'g^', label='parallel_runtime')
    plt.legend()
    plt.title("Series and Parallel Runtime vs Array Size")

    plt.subplot(212)
    plt.plot(NX, accel)
    plt.title("Acceleration vs Array Size")
    plt.show()

''' Question 3 functions '''
def question3():
    print ()
    print ("---------- Question 3 ----------")

    TPBX = 32
    TPBY = 32
    NX = 255
    NY = 255

    x = np.linspace(0, 1, NX, dtype=np.float32)
    y = np.linspace(0, 1, NY, dtype=np.float32)

    fp = pfArray2D(x, y, TPBX, TPBY)
    print ("32 is the largest number of thread a block can have."
        " Anything larger than that will produce the following error:"
        " numba.cuda.cudadrv.driver.CudaAPIError: [1] Call to"
        " cuLaunchKernel results in CUDA_ERROR_INVALID_VALUE")

''' Question 4 functions '''
def question4():
    print ()
    print ("---------- Question 4 ----------")

    print ("Change in aspect ratio has very little affect on the kernel"
        " execution time or kernal call")

''' Question 5 functions '''
def question5():
    print ()
    print ("---------- Question 5 ----------")

    arrayDimX = 255
    arrayDimY = 255

    array = [[0]*arrayDimX] * arrayDimY
    x = np.linspace(0, 2*math.pi, arrayDimX)
    y = np.linspace(0, 2*math.pi, arrayDimY)

    array = make_matrix(x, y)

    X, Y = np.meshgrid(x, y)
    plt.contourf(X, Y, array)
    plt.show()

    print ("Compute L2:")
    res = pnorm(array, 2)
    print ("Result is: ", res)

    print ("Compute L4:")
    res = pnorm(array, 4)
    print ("Result is: ", res)

    print ("Compute L6:")
    res = pnorm(array, 6)
    print ("Result is: ", res)

    print ("Compute L1000:")
    res = pnorm(array, 1000)
    print ("Result is: ", res)

    print ("The value of norm approaches 1 which is norm infinity as p increases")

def make_matrix(x, y):
    TPBX = 8
    TPBY = 8

    nx = np.array(x).shape[0]
    ny = np.array(y).shape[0]

    d_x = cuda.to_device(np.array(x))
    d_y = cuda.to_device(np.array(y))
    d_out = cuda.device_array((nx, ny))

    gridDims = ((nx + TPBX - 1) // TPBX,
                (ny + TPBY - 1) // TPBY)
    blockDims = (TPBX, TPBY)

    make_matrix_kerneld[gridDims, blockDims](d_x, d_y, d_out)
    return d_out.copy_to_host()

@cuda.jit
def make_matrix_kerneld(d_x, d_y, d_out):
    i , j = cuda.grid (2)
    nx = d_x.shape[0]
    ny = d_y.shape[0]
    if i < nx and j < ny:
        d_out[i, j] = math.sin(2*math.pi*d_x[i])*math.sin(2*math.pi*d_y[j])

@cuda.jit
def norm_kernel(d_array, p):
    i , j = cuda.grid (2)
    nx , ny = d_array.shape
    if i < nx and j < ny:
        d_array[i,j] = (d_array[i,j] ** p)

def pnorm(array, p):

    TPBX = 8
    TPBY = 8

    nx, ny = np.array(array).shape

    d_array = cuda.to_device(np.array(array))

    gridDims = ((nx + TPBX - 1) // TPBX,
                (ny + TPBY - 1) // TPBY)
    blockDims = (TPBX, TPBY)

    norm_kernel[gridDims, blockDims](d_array, p)
    res = 0
    d_arrayFlat = d_array.copy_to_host().flatten()
    for i in range(d_arrayFlat.shape[0]):
        res += d_arrayFlat[i]
    return res ** (1/p)

''' Question 6 '''
def question6():
    print ()
    print ("---------- Question 6 ----------")

    print ("For IVPs problems, there is no direct way to parallelize "
        "the computation over a grid of time intervals because current "
        "value depends on previous values of each states and thus to get "
        "value at time k, we need to already compute value of all states "
        "at time k-1")

    print ("For IVPs problems, there is a way to parallelize over a "
        "grid of initial conditions because the iteration process for "
        "each group of initial conditions are independent")

    nt = 1000
    t = np.linspace(0, 10, nt)
    dt = 1/nt
    x_i = np.linspace(-3, 3, 50)
    v_i = np.linspace(-3, 3, 50)

    X,V = np.meshgrid(x_i, v_i)

    for subprob in ["6c", "6d", "6e"]:
        print ("Subproblem ", subprob)
        r = iterate(x_i, v_i, dt, nt, subprob)

        fig = plt.figure(6)
        ax = plt.axes(projection='3d')

        ax.scatter3D(X, V, r)
        ax.set_xlabel('x')
        ax.set_ylabel('y')
        ax.set_zlabel('r')
        plt.show()

# 6c
def iterate(x_i, v_i, dt, nt, prob):
    TPBX = 16
    TPBV = 16

    nx = np.array(x_i).shape[0]
    nv = np.array(v_i).shape[0]

    d_xi = cuda.to_device(np.array(x_i))
    d_vi = cuda.to_device(np.array(v_i))
    d_x = cuda.device_array((nx, nv, nt))
    d_v = cuda.device_array((nx, nv, nt))
    d_r = cuda.device_array((nx, nv))

    gridDims = ((nx + TPBX - 1) // TPBX,
                (nv + TPBV - 1) // TPBV)
    blockDims = (TPBX, TPBV)

    if prob == "6c":
        iterate_kernel_6c[gridDims, blockDims](d_xi, d_vi, d_x, d_v, dt, nt, d_r)
    elif prob == "6d":
        iterate_kernel_6d[gridDims, blockDims](d_xi, d_vi, d_x, d_v, dt, nt, d_r)
    elif prob == "6e":
        iterate_kernel_6e[gridDims, blockDims](d_xi, d_vi, d_x, d_v, dt, nt, d_r)
    return d_r.copy_to_host()

# 6d
@cuda.jit
def iterate_kernel_6d(d_xi, d_vi, d_x, d_v, dt, nt, d_r):
    i, j = cuda.grid(2)
    nx = d_xi.shape[0]
    nv = d_vi.shape[0]

    if i < nx and j < nv:
        d_x[i, j, 0] = d_xi[i]
        d_v[i, j, 0] = d_vi[j]
        for k in range(nt-1):
            d_v[i, j, k+1] = d_v[i, j, k] + (- d_x[i, j, k] - 0.1 * d_v[i, j, k]) * dt
            d_x[i, j, k+1] = d_x[i, j, k] + d_v[i, j, k] * dt

        d_r[i,j] = (d_v[i, j, nt-1] ** 2 + d_x[i, j, nt-1] **2) ** 0.5 /((d_xi[i]**2 + d_vi[j]**2)**0.5)

# 6c
@cuda.jit
def iterate_kernel_6c(d_xi, d_vi, d_x, d_v, dt, nt, d_r):
    i, j = cuda.grid(2)
    nx = d_xi.shape[0]
    nv = d_vi.shape[0]

    if i < nx and j < nv:
        d_x[i, j, 0] = d_xi[i]
        d_v[i, j, 0] = d_vi[j]
        for k in range(nt-1):
            d_v[i, j, k+1] = d_v[i, j, k] - d_x[i, j, k] * dt
            d_x[i, j, k+1] = d_x[i, j, k] + d_v[i, j, k] * dt

        d_r[i,j] = (d_v[i, j, nt-1] ** 2 + d_x[i, j, nt-1] **2) ** 0.5 /((d_xi[i]**2 + d_vi[j]**2)**0.5)

# 6e
@cuda.jit
def iterate_kernel_6e(d_xi, d_vi, d_x, d_v, dt, nt, d_r):
    i, j = cuda.grid(2)
    nx = d_xi.shape[0]
    nv = d_vi.shape[0]

    if i < nx and j < nv:
        d_x[i, j, 0] = d_xi[i]
        d_v[i, j, 0] = d_vi[j]
        for k in range(nt-1):
            d_v[i, j, k+1] = d_v[i, j, k] + (- d_x[i, j, k] + 0.1*(1-d_x[i, j, k]**2) * d_v[i, j, k]) * dt
            d_x[i, j, k+1] = d_x[i, j, k] + d_v[i, j, k] * dt

        d_r[i,j] = (d_v[i, j, nt-1] ** 2 + d_x[i, j, nt-1] **2) ** 0.5 /((d_xi[i]**2 + d_vi[j]**2)**0.5)

def main():
    question2()
    question3()
    question4()
    question5()
    question6()

# call to execute main
if __name__ == '__main__':
    main()


# encoding=utf8
import requests
from lxml import etree

class cityAreaCode():
    def __init__(self):
        self.url = "http://www.ip33.com/area/2019.html"

    def get(self):
        page = requests.get(self.url)
        page.encoding = 'utf-8'
        _element = etree.HTML(page.text)
        divs = _element.xpath('//div[@class="ip"]')[1:]
        for div in divs:
            divtext = etree.tostring(div, encoding="utf-8", pretty_print=False).decode("utf-8")
            _element1 = etree.HTML(divtext)
            h4s = _element1.xpath('//div/h4')
            lis = _element1.xpath('//div/ul/li')
            for li in lis:
                litext = etree.tostring(li, encoding="utf-8", pretty_print=False).decode("utf-8")
                _element2 = etree.HTML(litext)
                h5s = _element2.xpath('//li/h5')
                lilis = _element2.xpath('//li/ul/li')
                for lili in lilis:
                    print('（省名称）',h4s[0].text.replace(' ','（省代码）'), '（市/区名称）', h5s[0].text.replace(' ','（市/区代码）'), "（地区名称）", lili.text.replace(' ','（地区代码）'))

if __name__ == '__main__':
    cityAreaCode = cityAreaCode()
    cityAreaCode.get()


'''
Created on 07/02/2018

@author: Carolina
'''
import unittest
from shapes import Shape, Rectangle

class Test(unittest.TestCase):

    def test_shape(self):
        shape = Shape ((0,0,0), 'wood')
        self.assertEqual('Color: (0,0,0) Material: wood Max_Temp: 20')
        shape2 = Shape ((0,0,0), 'wood')
        self.assertEqual (shape, shape2)
        shape3 = Shape ((0,23,0), 'woods')
        self.assertNotEqual (shape, shape3)
    def test_rectangle (self):
        rectangle = Rectangle(10, 20, (0,0,0), 'wood')
        self.assertEqual('Rectangle -> Comp. 10 lag. 20 Color: (0,0,0) Material: wood Max_Temp: 20'), str(rectangle)
        self.assertEqual('', str(rectangle))
        self.assertEqual(200, rectangle.get_area())
        rectangle2 = Rectangle(10, 30, (0,0,0), 'wood')
        self.assertEqual(300, rectangle.get_area())
        self.assertNotEqual(rectangle2, rectangle)
        rectangle3 = Rectangle (10, 20,(0,0,0), 'wood')
        self.assertEqual(rectangle3, rectangle)

        pass

if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()


from timeit import timeit

def runLengthEncoding(string):
    # Write your code here.
    res = []
    fp = 0
    sp = 1
    ln = 1
    while sp <= len(string):
        if sp == len(string) or string[sp] != string[fp] or ln == 9:
            res.append(f'{ln}{string[fp]}')
            fp = sp
            sp += 1
            ln = 1
        else:
            sp += 1
            ln += 1
    return "".join(res)

def runLengthEncoding_list(string):
    # Write your code here.
    s_list = list(string)
    res = []
    fp = 0
    sp = 1
    ln = 1
    while sp <= len(s_list):
        if sp == len(s_list) or s_list[sp] != s_list[fp] or ln == 9:
            res.append(f'{ln}{s_list[fp]}')
            fp = sp
            sp += 1
            ln = 1
        else:
            sp += 1
            ln += 1
    return "".join(res)

# print(runLengthEncoding("AAAAAABBCCCDDDDDDDDRRRRADS"))
string = ("AAAAAABBCCCDDDDDDDDRRRRADSAAAAAABBCCCDDDDDDDDRRRRADSAAAA" +
          "AABBCCCDDDDDDDDRRRRADSAAAAAABBCCCDDDDDDDDRRRRADSAAAAAABB" +
          "CCCDDDDDDDDRRRRADSAAAAAABBCCCDDDDDDDDRRRRADSAAAAAABBCCCD" +
          "DDDDDDDRRRRADSAAAAAABBCCCDDDDDDDDRRRRADSAAAAAABBCCCDDDDD" +
          "DDDRRRRADSAAAAAABBCCCDDDDDDDDRRRRADSDDDDDDDRRRRADSDDDDDD")
itr = 10_000

for foo in [runLengthEncoding, runLengthEncoding_list]:
    t = timeit(stmt="foo(string)", number=itr, globals=globals())
    print(f"{foo.__name__} runed in {t:.6f} seconds")


import numpy as np
from scipy.constants import G
from scipy.interpolate import interp1d
from astropy.constants import kpc

import general as ge

class zhao(object):
    """ Class for generating a potential for a spherical dark matter halo,
        using the data generated by the model of Zhao (2009).

        Attributes:

            fName:  The name of the file containing the data generated by the
                    model of Zhao. The data should be generated using the code
                    provided at: http://202.127.29.4/dhzhao/mandc.html

            data:   The loaded data from the text file; the data is stored in
                    a 2D numpy array. For more information on which data is
                    stored, see the README file generated using the code.

            h0:     Little h, hubble parameter at z=0 divided by 100, unitless.
                    Value from the Planck collaboration (2020).

            red:    The redshift values at which the properties of the dark
                    matter halo are computed.

            mass:   The virial mass of the dark matter halo in units of solar
                    masses, computed at the redshifts given by red.

            conc:   The concentration of the halo (r_vir / r_s) at the given
                    redshifts.

            virR:   The virial radius at the redshift values of the dark
                    matter halo in meters.

            rhoS:   The density at the scale radius in kg/m^3.

            rS:     The scale radius of the dark matter halo in meters.

            time:   The lookback time corresponding to the redshift values in
                    years.
    """

    def __init__(self, fName):
        """ Initializing the potential according to the model of Zhao

            Input:
                fName   (string)

            Returns:
                zhao    (object)
        """

        self.fName = fName                      # File name

        data = self.load_data()
        h0 = 0.6766
        t0 = data[:,-1][0] / h0

            # Unpacking data
        self.red = data[:,0]                            # Redshift
        self.mass = data[:,1] / h0                      # Virial mass
        self.conc = data[:,2]                           # Concentration
        self.virR = 1e3 * kpc.value * data[:,4] / h0    # Virial radius
        self.rhoS = ge.conv_inv_dens(data[:,7]/1e18) * h0 * h0   # rho_s
        self.rS = 1e3 * kpc.value * data[:,8] / h0      # r_s
        self.time = t0 - data[:,-1] / h0                # Age of Universe

    def load_data(self):
        """ Loading data from a generated data file

            Input:
                -

            Returns:
                data:   array containing the properties of the dark matter
                        halo (2D numpy array).
        """
        with open(self.fName) as f:
            data = np.loadtxt((x.replace('   ', '  ') for x in f), skiprows=1)
        return data

    def find_z_ind(self, zV):
        """ Input a redshift and find the indices corresponding to the closest
            redshift value(s) of the generated data. If zV is an array then
            the closest indices for all the redshift values are determined and
            returned.

            Input:
                zV:     The redshift value(s) for which the closest index has
                        to be found (float or numpy array).

            Returns:
                The indices corresponding to the closest redshift values
                (integer or numpy array).
        """

        if type(zV) != np.ndarray and type(zV) != list and type(zV) != tuple:
            return ge.find_closest(self.red, zV)[0]

        return np.asarray([ge.find_closest(self.red, z)[0] for z in zV])

    def rs_rhos_at_z(self, zV):
        """ Find the scale radius (r_s) and the density at the scale radius
            (rho_s) for a given redshift value. This is done by finding the
            closest redshift value to the input redshift value(s), NOT by
            interpolating.

            Input:
                zV:     redshift(s) at which r_s and rho_s will be determined
                        (float or numpy array).

            Returns:
                Value of r_s at zV (float or numpy array).
                Value of rho_s at zV (float or numpy array).
        """
        zInd = self.find_z_ind(zV)                      # Correct z index
        return self.rS[zInd], self.rhoS[zInd]

    def mass_at_r(self, zV, r):
        """ The mass of the dark matter halo as function of distance from the
            center of the dark matter halo at a given redshift.

            Input:
                zV:     redshift(s) at which the mass as function of radius
                        is determined (float or numpy array).
                r:      the distances from the center of the halo at which
                        the mass will be calculated (float or numpy array).

            Returns:
                mass as function of r and z (float or numpy array (1D or 2D))
        """

        rS, rhoS = self.rs_rhos_at_z(zV)                # r_s and rho_s

        mass = [rhoS[i] * rS[i] * (np.log(1+r/rS[i]) - r / (rS[i] + r))
                for i in range(len(rS))]

        return 16 * np.pi * np.asarray(mass)

    def simp_profile(self, x):
        """ The NFW profile density profile for the dark matter halo. This
            function gives rho/rho_s as function of r/r_s. Therefore you do
            not need to specify the parameters r_s and rho_s. Moreover, this
            profile is time independent.

            Input:
                x:      r/r_s values, dimensionless (numpy array).

            Returns:
                rho/rho_s for the given x values (numpy array).
        """
        return 4 / (x * np.power(1+x, 2))

    def nfw_profile(self, zV, r):
        """ A time dependent NFW density profile. With the input of the
            desired redshift value(s), a time dependent density profile
            as function of radius is output. r_s and rho_s are determined
            using the model of van den Bosch.

            Input:
                zV:     the redshift values at which the density profile
                        is computed (float or numpy array).
                r:      distance from the center of the halo (float or
                        numpy array).

            Returns:
                time dependent NFW profile (float or numpy array(1D or 2D))
        """

        zInd = self.find_z_ind(zV)                          # Selecting z ind

        rS = self.rS                                        # r_s
        rhoS = self.rhoS                                    # rho_s

        if type(zInd) != np.ndarray:                        # Single z value
            denom = r * np.power(1 + r/rS[zInd], 2) / rS[zInd]
            return 4 * rhoS[zInd] / denom

        selrS, selrhoS = rS[zInd], rhoS[zInd]               # Slicing lists

            # Multiple z values
        frac = [selrhoS[ind] / (r * np.power(1 + r/selrS[ind], 2) / selrS[ind])
                for ind in range(len(selrS))]

        return 4 * np.asarray(frac)

    def pot_nfw(self, zV, r):
        """ The gravitational potential corresponding to the NFW
            density profile. This is obtained by solving the Poisson
            equation. For the NFW profile there exists an analytical
            solution.

            Input:
                zV:     the redshift values at which the potential is
                        computed (float or numpy array).
                r:      distance from the center of the halo (float or
                        numpy array).

            Returns:
                gravitational potential (float or numpy array(1D or 2D))
        """

        rhoS = self.rhoS                                    # rho_s
        rS = self.rS                                        # r_s

        zInd = self.find_z_ind(zV)                          # Finding correct z

        if type(zInd) != np.ndarray:                        # Single z value

               # Need to interpolate due to coarse grid
            interpRS = interp1d(self.red, self.rS)      # Creating r_s int. object
            selrS = interpRS(zV)                        # Interpolating r_s

            interpRhoS = interp1d(self.red, self.rhoS)  # Creating rho_s int. object
            selrhoS = interpRhoS(zV)                    # Interpolating rho_s

            part1 = -16 * np.pi * G * selrhoS * selrS * selrS
            part2 = np.log(1 + r/selrS) / (r/selrS)

            return part1 * part2

            # Multiple z values
        selrS, selrhoS = rS[zInd], rhoS[zInd]                   # Slicing lists

        part1 = -16 * np.pi * G * selrhoS * selrS * selrS       # First part
        part2 = [np.log(1 + r/rsV) / (r/rsV) for rsV in selrS]  # Second part

        phi = [part1[ind] * part2[ind] for ind in range(len(zInd))] # Potential

        return np.asarray(phi)


import random
from random import randint
import pygame

from essais.essai_dijkstra_damier import title
from lib_dijkstra import DijkstraManager, Point, pyrect_to_point, point_to_pyrect

verbose = False

class Entity(pygame.sprite.Sprite):

    def __init__(self, name, x, y, screen=None):
        super().__init__()
        self.name = name
        self.sprite_sheet = pygame.image.load(f'../sprites/{name}.png')
        self.image = self.get_image(0, 0)
        self.image.set_colorkey([0, 0, 0])
        self.rect = self.image.get_rect()  # position du sprite
        self.position = [x, y]
        self.screen = screen if screen else None

        # Mon sprite mesure 32 * 32
        self.images = {
            'down': self.get_image(0, 0),
            'left': self.get_image(0, 32),
            'right': self.get_image(0, 64),
            'up': self.get_image(0, 96)
        }
        self.feet = pygame.Rect(0, 0, self.rect.width * 0.5, 16)
        self.old_position = self.position.copy()
        self.speed = 2

    def save_location(self):
        self.old_position = self.position.copy()

    def change_animation(self, attitude):
        # ('up', 'down', 'left', 'right')
        self.image = self.images[attitude]
        self.image.set_colorkey((0, 0, 0))

    def move_right(self):
        self.position[0] += self.speed

    def move_left(self):
        self.position[0] -= self.speed

    def move_up(self):
        self.position[1] -= self.speed

    def move_down(self):
        self.position[1] += self.speed

    def update(self):
        self.rect.topleft = self.position
        self.feet.midbottom = self.rect.midbottom

    def move_back(self):
        self.position = self.old_position
        self.rect.topleft = self.position
        self.feet.midbottom = self.rect.midbottom

    def get_image(self, x, y):
        image = pygame.Surface([32, 32])
        image.blit(self.sprite_sheet, (0, 0), (x, y, 32, 32))
        return image

class Player(Entity):
    def __init__(self, x, y):
        super().__init__('player', x, y)

class NPC(Entity):
    def __init__(self, name, map_manager, map_name, screen=None):

        super().__init__(name, 500, 550, screen)
        self.name = name  #
        self.change_animation("left")
        self.map_manager = map_manager
        self.map_name = map_name
        self.debug_count =0
        self.move_direction = None

        # Les zones issues de la carte tmx. Elles sont désignées par un nom de type robin_path1.
        # J'appelle cette zone une area. Elle est de type pygame.Rect
        self.areas = []  # Les areas : liste de pygame.Rect
        self.areas_nb = None
        self.current_area_idx = None  # ndint(0, self.nb_areas-1)  # index de area
        self.next_area_idx = None

        # Entre 2 zones, on définit une promenade / walk. Le chemin de la promenade est trouvé selon un algorithme
        # simple ou un algorithme de Dijkstra.
        self.use_dijkstra = True

        # les points de la carte simplifiée pour résoudre la promenade/ walk.
        self.djik = None  # Objet pour résoudre le chemin selon Dijkstra.
        # Les points ci dessous sont utilisé pour guider le mouvement dans la promenade.
        self.prev_point = None  # Le Point d'où lon vient. Sera initialisé par init_dijkstra
        self.next_point = None  # Le Point où l'on va
        self.next_point_rect: pygame.Rect = None  # Son équivalent en pygame.rect
        self.next_dir = None
        # Il faut penser à lancer les méthodes de début après création de NPC:
        # par exemple define_first_target()

    def calculate_next_area_idx(self):
        while True:
            rnd = randint(0, self.areas_nb - 1)
            if rnd != self.current_area_idx:
                self.next_area_idx = rnd
                break

    def modify_speed(self):
        self.speed = self.speed + randint(-1, 1)
        if self.speed == 0:
            self.speed = 1
        elif self.speed == 4:
            self.speed = 3

    def calculate_move_direction(self):
        """Algorithme très primaire. Il a besoin de déterminer la direction générale à prendre."""
        target_point = self.areas[self.next_area_idx].center
        feet_point = self.feet.center

        rect = pygame.Rect(feet_point[0], feet_point[1],
                           target_point[0] - feet_point[0], target_point[1] - feet_point[1])
        x, y, w, h = rect
        if w > 0:
            if h > 0:
                self.move_direction = 'SE'
            else:
                self.move_direction = 'NE'
        else:  # W est neg
            if h > 0:
                self.move_direction = 'SW'
            else:
                self.move_direction = 'NW'
        print(f"Nouvelle cible : {self.next_area_idx}, direction : {self.move_direction}")

    def calculate_dijkstra(self, verbose=False):
        """Lit la carte simplifiée.
        L'algorithme utilise une version réduite de la carte. La réduction est de 1 ou 2 fois la taille des
        tuiles.
        Convertit une zone (area) en un Point de la carte simplifiée.
        Donc, on convertit ce que j'appelais area (zone) en Point
        """
        map = self.map_manager.maps[self.map_name].simple_map
        self.dijk = DijkstraManager(map)

        start_area = self.areas[self.current_area_idx]
        start_point = pyrect_to_point(self.map_manager.maps[self.map_name], start_area, 32)

        next_area = self.areas[self.next_area_idx]
        map_name = self.map_manager.maps[self.map_name]
        end_point = pyrect_to_point(map_name, next_area, 32)

        if verbose:
            print(f"Il faut aller du point {start_point} au point {end_point}")
        self.dijk.dijkstra(start_point, verbose=0)

        self.dijk.format_path(start_point, end_point, verbose=True)

        self.prev_point = start_point
        self.dijk.give_next_instruction()    # IMPORTANT : on élimine la dernière valeur
        self.next_point, self.next_dir = self.dijk.give_next_instruction()
        self.next_point_rect = pygame.Rect(point_to_pyrect(map_name, self.next_point))
        print("Fin de calcul du Dijkstra")
        print(f"{self.next_dir} point_actuel: {self.rect} next_point: {self.next_point} ; next_point_rect : {self.next_point_rect}")

    def define_first_target(self):
        self.current_area_idx = 0  # index de area
        # Pour le run, utiliser ces lignes
        self.calculate_next_area_idx()
        # self.calculate_move_direction()
        # Pour une mise au point, utiliser ces lignes
        # self.next_pyrect_idx = 2
        # self.move_direction = 'SE'

    def teleport_npc(self):
        first_area = self.areas[self.current_area_idx]
        self.position[0] = first_area.x
        self.position[1] = first_area.y
        self.save_location()

    def move(self):
        self.save_location()  # Tentative de résolution d'un GROS BUG
        self.debug_count += 1
        if self.use_dijkstra:
            self.move_dij()
        else:
            self.move_classical()

    def move_dij(self):
        """Mouvement automatique. Algorithme type Djikstra à ma façon.
        Cette fonction est en cours d'écriture"""
        sens = self.next_dir
        if sens == 'R':
            self.move_right()
        elif sens == 'L':
            self.move_left()
        elif sens == 'B':
            self.move_down()
        elif sens == 'T':
            self.move_up()
        elif sens is None:
            pass
        else:
            raise ValueError(f"{sens} : error code letter")

        if self.rect.colliderect(self.next_point_rect):
            print("  ***************         COLISION       **************")
            self.prev_point = self.next_point  # ne sert à rien pour l'instant
            self.next_point, self.next_dir = self.dijk.give_next_instruction()
            if self.next_point:
                self.next_point_rect = pygame.Rect(point_to_pyrect(self.map_name, self.next_point))
            else:
                print("********** Arrivé ! ************")
                # Trouver une nouvelle cible au NPC
                self.current_area_idx = self.next_area_idx
                self.calculate_next_area_idx()
                self.calculate_dijkstra()

        print(f"{self.debug_count}, {sens} actuel : point_actuel: {self.prev_point} rect: {self.rect} next_point: {self.next_point} ; next_point_rect : {self.next_point_rect}")
        print(f"next_dir devient {self.next_dir}")
        pass

    def move_classical(self):
        """Mouvement automatique. Algorithme primaire."""
        feet_rect = self.feet
        target_rect = self.areas[self.next_area_idx]
        feet_to_target_rect = pygame.Rect(feet_rect.x, feet_rect.y,
                                          target_rect.x - feet_rect.x, target_rect.y - feet_rect.y)
        move_vert = None
        move_horz = None
        if self.move_direction == 'SE':
            move_horz = self.move_right
            move_vert = self.move_down
            self.change_animation("right")

        elif self.move_direction == 'NW':
            move_horz = self.move_left
            move_vert = self.move_up
            self.change_animation("left")

        elif self.move_direction == 'SW':
            move_horz = self.move_left
            move_vert = self.move_down
            self.change_animation("left")

        elif self.move_direction == 'NE':
            move_horz = self.move_right
            move_vert = self.move_up
            self.change_animation("right")

        if feet_to_target_rect.height == 0:
            feet_to_target_rect.height = 5
            move_vert()
        else:
            # odd n'est sans doute pas le bon terme.
            try:
                odd_horiz_mvt = feet_to_target_rect.width / (feet_to_target_rect.height + feet_to_target_rect.width)
            except ZeroDivisionError:
                odd_horiz_mvt = 0.95

            if verbose:
                print(f"{feet_to_target_rect}, {self.name} Odd ratio : {odd_horiz_mvt}")

            if odd_horiz_mvt == 0:
                move_vert()
            else:
                rnd = random.random()
                # print(f"La valeur aléatoire est {rnd} ; limite de probabilité vaut {odd_horiz_mvt} : ", end = '')
                if rnd > odd_horiz_mvt:
                    move_vert()
                else:
                    move_horz()

        if self.rect.colliderect(target_rect):
            self.current_area_idx = self.next_area_idx
            self.calculate_next_area_idx()
            self.calculate_move_direction()


from functools import wraps
from flask import url_for, redirect, session

# 登陆限制装饰器
# 用于需要登陆的页面，如果没有登陆则要求登陆(跳转至登陆页面)
def login_required(func):
    @wraps(func)
    def wapper(*args, **kwargs):
        if session.get('user_id'):
            return func(*args, **kwargs)
        else:
            return redirect(url_for('login'))

    return wapper


def repeatedStringMatch (A: str, B: str) -> int:
    # lenA = len(A)
    # lenB = len(B)
    #
    #
    #
    # if lenA > lenB:
    #     if B in A:
    #         return 1
    # else:
    #     a = A
    #     count = 1
    #     FLAG = True
    #     while lenA < 1000:
    #         if FLAG:
    #             a = a + A
    #             FLAG = False
    #         else:
    #             a = A + a
    #             FLAG = True
    #         count += 1
    #         lenA = len(a)
    #         if B in a:
    #             return count
    #
    #     return -1
    for i in range (int(len (B) / len (A)), int(len (B) / len (A)) + 3):
        if B in i * A:
            return i
    return -1

print(repeatedStringMatch('a*1000000000000000000','aaaaaaaaaaaaaaaaaaaaaaaa'))
#repeatedStringMatch('abaabaa','abaababaab')


import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.layers.experimental import preprocessing
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import tensorflowjs as tfjs

url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data'
column_names = ['MPG', 'Cylinders', 'Displacement', 'Horsepower', 'Weight',
                'Acceleration', 'Model Year', 'Origin']

raw_dataset = pd.read_csv(url, names=column_names,
                          na_values='?', comment='\t',
                          sep=' ', skipinitialspace=True)

dataset = raw_dataset.copy()
dataset.tail()

dataset.isna().sum()
dataset = dataset.dropna()

dataset['Origin'] = dataset['Origin'].map({1: 'USA', 2: 'Europe', 3: 'Japan'})
dataset = pd.get_dummies(dataset, prefix='', prefix_sep='')
dataset.tail()

train_dataset = dataset.sample(frac=0.8, random_state=0)
test_dataset = dataset.drop(train_dataset.index)

train_features = train_dataset.copy()
test_features = test_dataset.copy()

train_labels = train_features.pop('MPG')
test_labels = test_features.pop('MPG')

normalizer = preprocessing.Normalization()
normalizer.adapt(np.array(train_features))

first = np.array(train_features[:1])

with np.printoptions(precision=2, suppress=True):
  print('First example:', first)
  print()
  print('Normalized:', normalizer(first).numpy())

horsepower_model = keras.Sequential([

tf.keras.layers.LayerNormalization(
    axis=-1, dtype='float64', epsilon=0.001, input_shape=[1]
),

    layers.Dense(2, activation='relu'),

    layers.Dense(1)
])

horsepower_model.compile(
    optimizer=tf.optimizers.Adam(learning_rate=0.1),
    loss='mean_absolute_error')

history = horsepower_model.fit(
    train_features['Horsepower'], train_labels,
    epochs=100,
    # suppress logging
    verbose=1,
    # Calculate validation results on 20% of the training data
    validation_split = 0.2)


import time, os, boto3, json, decimal
from boto3.dynamodb.conditions import  Key
from helpers import send_to_datastream
from helpers import _get_body
from helpers import _get_response
from helpers import DecimalEncoder

try:
    dynamodb = boto3.resource('dynamodb')
    phase_status_table = dynamodb.Table(os.getenv('PHASE_STATUS_TABLE'))
except Exception as e:
    print(e)

def post_phase_status(event, context):
    body = _get_body(event)

    try:
        site = body['site']
        message = body['message']
    except Exception as e:
        return _get_response(400, 'Unable to parse all required arguments. ')

    timestamp = time.time()
    payload = {
        "site": site,
        "timestamp": timestamp,
        "message": message,
    }

    # Send to datastream
    topic = "phase_status"
    send_to_datastream(site, payload, topic)

    # save in database
    # Convert floats into decimals for dynamodb
    payload["ttl"] = timestamp + 86400  # ttl = one day
    dynamodb_entry = json.loads(json.dumps(payload, cls=DecimalEncoder), parse_float=decimal.Decimal)
    table_response = phase_status_table.put_item(Item=dynamodb_entry)

    return _get_response(200, 'Phase status broadcasted to sites successfully.')

def get_phase_status(event, context):
    try:
        site = event['pathParameters']['site']
    except Exception as e:
        return _get_response(400, 'Missing path parameter site')

    max_age_seconds = event.get('queryStringParameters', {}).get('max_age_seconds', 3600)  # default max age is 1 hour

    timestamp_cutoff = int(time.time() - int(max_age_seconds))
    phase_status = phase_status_table.query(
        Limit=3,
        ScanIndexForward=False,  # sort by most recent first
        KeyConditionExpression=Key('site').eq(site) & Key('timestamp').gt(timestamp_cutoff)
    )
    return _get_response(200, phase_status['Items'])

if __name__=="__main__":

    phase_status_table = dynamodb.Table('phase-status-dev')
    payload = json.dumps({
        "site": "tst",
        "message": "a phase message 2",
    })
    #post_phase_status({"body": payload}, {})
    event = {
        "pathParameters": {
            "site": "tst"
        },
        "queryStringParameters": {
            "max_age_seconds": "3600"
        }
    }
    context = {}
    ps = get_phase_status(event, context)
    print(ps['body'])


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.stats
import wbgapi as wb
import seaborn as sns

def world(ind, code, years):
    '''
    this function returns original data, transposed data and world data for above indicators

    Parameters
    ----------
    ind : index
    code : country code
    years : total number of years

    Returns
    -------
    data : original data
    data_t : transposed data
    worlddata : complete world data

    '''
    data = wb.data.DataFrame(ind, code, mrv=years)
    data_t = data.T
    worlddata = wb.data.DataFrame(ind, mrv=years)
    return data, data_t, worlddata

def modify(data):
    '''
    this method can be used to clean up and generate modified data

    Parameters
    ----------
    data : the data to be modified

    Returns
    -------
    data_mod1 : modified data with mean
    data_mod3 : modified data after indexing and renaming

    '''
    data_mod1 = data.mean()
    data_mod2 = pd.DataFrame(data_mod1)
    data_mod2.reset_index(level=0, inplace=True)
    data_mod3 = data_mod2.rename(columns={"index": "year", 0: "mean"})
    return data_mod1, data_mod3

def box(x, y):
    '''
    box plot comparing the countries- INDIA, UNITED KINGDOM, CHINA with world

    Parameters
    ----------
    x : data for x-axis
    y : Tdata for y-axis

    Returns
    -------
    None.

    '''
    fig = plt.figure(figsize=(4, 3))
    ax = fig.add_axes([0, 0, 1, 1])
    cc = ax.boxplot(x)
    ax.set_xlabel("countries")
    ax.set_ylabel("CO2 EMISIONS(% change)")
    ax.set_title("CO2 EMMISIONS COMPARISIONS")
    ax.set_xticks([1, 2, 3, 4])
    ax.set_xticklabels(y)
    plt.show()
    return

country_codes = ["PAK", "GBR", "CHN", "NAC", "IND"]  # country codes
wb.series.info('EN.ATM.GHGT.KT.CE')  # getting info from world bank api
indicator_id = {"EN.ATM.GHGT.KT.CE", "EN.ATM.CO2E.KT",
                "AG.LND.ARBL.ZS", "AG.LND.AGRI.ZS"}  # indicators to access data

#creating dictionary to access indicators.
AG = {"AG.LND.AGRI.ZS": "AGRICULTURAL LAND(%)"}
ABL = {"AG.LND.ARBL.ZS": "ARABLE LAND (%)"}
CO2 = {"EN.ATM.CO2E.KT": "CO2 EMISSIONS(KT)"}
GHG = {"EN.ATM.GHGT.KT.CE": "TOTAL GREENHOUSE GAS EMISSIONS(KT)"}

wb.series.info(indicator_id)

#accessing data by calling "world" function
AG, AG_T, AG_world = world(AG.keys(), country_codes, 30)
AG_T.describe()

#accessing data by calling "world" function
Co2, CO2_T, CO2_world = world(CO2.keys(), country_codes, 30)
CO2_T.describe()

#accessing data by calling "world" function
ABL, ABL_T, ABL_world = world(ABL.keys(), country_codes, 30)
ABL_T.describe()

#accessing data by calling "world" function
GHG, GHG_T, GHG_world = world(GHG.keys(), country_codes, 30)
GHG_T.describe()

#modified data for Co2
co2_mod, co2_W_mod = modify(CO2_world)
Ghg_mod, Ghg_W_mod = modify(GHG_world)
ag_mod, ag_W_mod = modify(AG_world)
abl_mod, abl_W_mod = modify(ABL_world)
abl_W_mod.describe()
c = CO2_T.rename(columns={"index": "year", 0: "mean"})
co2_t = c.rename_axis("year")
a = AG_T.rename(columns={"index": "year", 0: "mean"})
ag_t = a.rename_axis("year")
ag = ABL_T.rename(columns={"index": "year", 0: "mean"})
agl_t = ag.rename_axis("year")
g = GHG_T.rename(columns={"index": "year", 0: "mean"})
ghg_t = g.rename_axis("year")

# generate line plot of foreast cover over arable land for whole world
fig, ax = plt.subplots(figsize=[7, 3])
ax.plot(abl_W_mod["year"], abl_W_mod["mean"], marker="*")
ax.set_ylabel("Arable land (% of land area)", fontsize=7)
ax.set_xlabel("Year", fontsize=16)
plt.xticks(rotation=90)
ax1 = ax.twinx()
ax1.plot(ag_W_mod["year"], ag_W_mod["mean"], color="RED", marker="o")
ax1.set_ylabel("Agricultural land (% of land area)",
               fontsize=7)
plt.title("Time series plot of ARABLE LAND and AGRICULTURAL LAND (% of total land)")
plt.show()

#geberate box plot
data = [CO2_T["IND"], CO2_T["NAC"], CO2_T["CHN"], co2_W_mod["mean"]]
coun = ["INDIA", "UNITED KINGDOM", "CHINA", "world"]
box(data, coun)

#violin plot for Green house gas emissian for countries, INDIA, UNITED KINGDOM, CHINA
fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3)
ax1.violinplot(GHG_T["IND"], showmedians=True, points=10)
ax1.set_xticks([1])
ax1.set_ylabel("GREEN HOUSE GAS EMISSION")
ax1.set_xticklabels(["INDIA"])
ax2.violinplot(GHG_T["GBR"], showmedians=True, points=100)
ax2.set_xticks([1])
ax2.set_xticklabels(["UK"])
ax3.violinplot(GHG_T["CHN"], showmedians=True, points=500)
ax3.set_xticks([1])
ax3.set_xticklabels(["CHINA"])
plt.show()

#Heat map of greenhouse gases
rs = np.random.RandomState(0)
FORW = pd.DataFrame(rs.rand(8, 8))
corr = GHG_T.corr()
plt.figure(figsize=(6, 7))
sns.heatmap(corr, annot=True)
plt.show()