# Exercícios LISTA DE TAREFAS
import os
import json

tarefas = []
apagados = []

def ler(tarefas):
    temporarios = []
    try:
        with open('lista_de_tarefas.json', 'r', encoding='utf8') as file:
            temporarios = json.load(file)
        if tarefas != []:
            while True:
                resposta = input('Deseja adicionar os itens carregados aos itens existentes na lista? [S/N]').upper()
                if resposta not in 'SsNn':
                    print('RESPOSTA INVÁLIDA')
                    print()
                else:
                    break
            if resposta == 'N':
                for c in range(len(tarefas)):
                    tarefas.pop()
        for temporario in temporarios:
            tarefas.append(temporario)
        return tarefas

    except FileNotFoundError:
        print('Nenhum Arquivo .json encontrado para carregar.')

def salvar(tarefas):
    with open('lista_de_tarefas.json', 'w', encoding='utf8') as file:
        json.dump(tarefas, file,ensure_ascii=False, indent=2)

def adicionar(tarefas, acao):
    if acao == 'sair':
        return
    tarefas.append(acao)
    print(f'Tarefa {acao} adicionada na lista de tarefas.')

def listar(tarefas):
    print()
    if not tarefas:
        try:
            with open('lista_de_tarefas.json', 'r', encoding='utf8') as file:
                tarefas = json.load(file)
        except FileNotFoundError:
            print('LISTA DE TAREFAS ESTÁ VAZIA')
            print()
            return
    print('-'*13)
    print(f'{"   TAREFAS"}')
    print('-'*13)
    for tarefa in tarefas:
        print(f'- {tarefa}')
    print()

def desfazer(tarefas):
    print()
    if not tarefas:
        print('-' * 27)
        print('Nada mais para ser desfeito'.upper())
        print('-' * 27)
        return

    ultimo = tarefas[-1]
    apagados.append(ultimo)
    print(f'Tarefa {ultimo} removida da lista de tarefas.')
    tarefas.pop()
    print()

def refazer(tarefas, apagados):
    if not apagados:
        print('-' * 21)
        print('Nada para ser refeito'.upper())
        print('-' * 21)
        return
    tarefas.append(apagados[-1])
    print(f'Tarefa {apagados[-1]} retornada a lista de tarefas.')
    apagados.pop(-1)
    print()

while True:
    print()
    print('Comandos: listar, desfazer, refazer, sair(para sair), ler, salvar.', )
    acao = input('Digite uma tarefa ou um comando:').lower().strip()
    print()
    if acao == 'sair':
        break
    comandos = {
        'listar' : lambda : listar(tarefas),
        'desfazer' : lambda : desfazer(tarefas),
        'refazer' : lambda : refazer(tarefas, apagados),
        'listar' : lambda : listar(tarefas),
        'clear' : lambda : os.system('cls'),
        'adicionar' : lambda : adicionar(tarefas, acao),
        'salvar' : lambda : salvar(tarefas),
        'ler' : lambda : ler(tarefas),

    }

    comando = comandos.get(acao) if comandos.get(acao) is not None else comandos['adicionar']
    comando()


# coding=utf-8
"""
@Time : 2020/6/9 17:49
@Author: zhangqian
"""

import asyncio
import json
from os import makedirs
from os.path import exists

from pyppeteer import launch
import logging
from pyppeteer.errors import TimeoutError

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s')
# INDEX_URL = 'https://dynamic5.scrape.cuiqingcai.com/api/book/?limit=18&offset={offset}'
INDEX_URL = 'https://dynamic2.scrape.cuiqingcai.com/page/{page}'
DETAIL_URL = 'https://dynamic5.scrape.cuiqingcai.com/api/book/{id}'
MAX_PAGE = 3
PAGE_SIZE = 18
WINDOW_WIDTH, WINDOW_HEIGHT = 1366, 768
HEADLESS = False
browser, tab = None, None
TIMEOUT = 15
HEADLESS = True
RESULTS_DIR = 'results'
exists(RESULTS_DIR) or makedirs(RESULTS_DIR)

async def init():
    '''
    根据selector判断该页面元素是否可操作
    :return:
    '''
    global browser, tab
    browser = await launch(headless=HEADLESS,
                           args=['--disable-infobars',
                                 f'--window-size={WINDOW_WIDTH},{WINDOW_HEIGHT}'])
    tab = await browser.newPage()
    await tab.setViewport({'width': WINDOW_WIDTH, 'height': WINDOW_HEIGHT})

async def scrape_page(url, selector):
    '''
    根据selector判断该页面元素是否可操作
    :param url:
    :param selector:
    :return:
    '''
    logging.info('scrape page %s', url)
    try:
        await tab.goto(url)
        await tab.waitForSelector(selector, options={'timeout': TIMEOUT * 1000})  # 会出现timeout 15000ms exceeds
        # await asyncio.wait([tab.waitForNavigation(), tab.querySelector(selector)])
    except TimeoutError:
        logging.error('error occurred while scraping %s', url, exc_info=True)

async def scrape_index(page):
    '''
    根据页码生成的列表url、元素选择器判断是否可操作
    :param page:
    :return:
    '''
    url = INDEX_URL.format(page=page)
    await scrape_page(url, '.item .name')

async def parse_index():
    '''
    解析列表页，返回详情页链接
    :return:
    '''
    return await tab.querySelectorAllEval('.item .name', 'nodes => nodes.map(node => node.href)')

async def scrape_detail(url):
    '''
    判断详情页是否可操作
    :param url:
    :return:
    '''
    await scrape_page(url, 'h2')

async def parse_detail():
    '''
    解析详情页，返回json
    :return:
    '''
    url = tab.url
    name = await tab.querySelectorEval('.m-b-sm', 'node => node.innerText')
    categories = await tab.querySelectorAllEval('.categories button span', 'nodes => nodes.map(node => node.innerText)')
    score = await tab.querySelectorEval('.score', 'node => node.innerText')
    cover = await tab.querySelectorEval('.cover', 'node => node.src')
    drama = await tab.querySelectorEval('.drama p', 'node => node.innerText')
    return {
        'url': url,
        'name': name,
        'score': score,
        'categories': categories,
        'cover': cover,
        'drama': drama
    }

async def save_data(data):
    name = data.get('name')
    data_path = f'{RESULTS_DIR}/{name}.json'
    json.dump(data, open(data_path, 'w', encoding='utf-8'), ensure_ascii=False, indent=2)

async def main():
    await init()
    try:
        for page in range(1, MAX_PAGE+1):
            await scrape_index(page)
            detail_urls = await parse_index()
            logging.info('detailUrls %s', detail_urls)
            for detail_url in detail_urls:
                await scrape_detail(detail_url)
                res = await parse_detail()
                logging.info('data : %s', res)
                await save_data(res)
                logging.info('save data.')
    finally:
        await browser.close()

if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())


#!/usr/bin/env python

try:
    from smbus2 import SMBus
except ImportError:
    from smbus import SMBus
from bme280 import BME280

print("""dump-calibration.py - Dumps calibration data.

Press Ctrl+C to exit!

""")

# Initialise the BME280
bme280 = BME280(i2c_dev=SMBus(1))
bme280.setup()

for key in dir(bme280.calibration):
    if key.startswith('dig_'):
        value = getattr(bme280.calibration, key)
        print('{} = {}'.format(key, value))


from PIL import Image
import glob, os

size = 256, 256

if __name__ == '__main__':
    for infile in glob.glob("*.jpg") + glob.glob("*.jpeg"):
        file, ext = os.path.splitext(infile)
        im = Image.open(infile)
        im.thumbnail(size)
        im.save(f'Thumbnails/{file}{ext}', "JPEG")

    for infile in glob.glob("*.png"):
        file, ext = os.path.splitext(infile)
        im = Image.open(infile)
        im.thumbnail(size)
        im.save(f'Thumbnails/{file}{ext}', "PNG")


from Game import stars_ambient
from Game.button import *
from Game.stars_ambient import *

class Main_Menu:

    gui = None
    Play = None
    Mode = None
    Ranking = None
    Exit = None
    Stars_Amb = None

    def __init__(self, gui):
        self.gui = gui
        self.Play = Btn("Assets/BTN.png", "Play", gui, gui.width / 2 - 200, gui.height / 2)
        self.Mode = Btn("Assets/BTN.png", "Mode", gui, gui.width / 2 - 200, gui.height / 2 + 100)
        self.Ranking = Btn("Assets/BTN.png", "Rank", gui, gui.width / 2 - 200, gui.height / 2 + 200)
        self.Exit = Btn("Assets/BTN.png", "Exit", gui, gui.width / 2 - 200, gui.height / 2 + 300)
        self.Stars_Amb = Stars(gui)

    def draw(self, level, mode):
        self.gui.set_background_color((0, 0, 0))
        #self.Stars_Amb.draw()
        if self.Play.draw():
            level[0] = 3
        if self.Mode.draw():
            level[0] = 1
        if self.Ranking.draw():
            level[0] = 2
        if self.Exit.draw():
            exit(0)


"""
Ejercicio 3.3.6¶

Dado el conjunto de letras:
vocales = {'a', 'e', 'i', 'o', 'u'}

 - Crea un conjunto consonantes que contenga las letras del alfabeto que no son vocales.
 - Crea un conjunto letras_comunes que contenga las letras que están tanto en el conjunto vocales como en el conjunto
 consonantes.
"""

def interseccion(set1: set, set2: set) -> set:
    comun = set1 & set2
    return comun

if __name__ == "__main__":
    vocales = {'a', 'e', 'i', 'o', 'u'}
    cadena_consonates = "qwrtypsdfghjklñzxcvbnm"
    lista_consonantes = list(cadena_consonates)
    consonantes = set(lista_consonantes)
    letras_comunes = interseccion(vocales, consonantes)
    print(f"Las letras comunes entre las vocales y las consonantes son:{letras_comunes}")


"""
Matplotlib based plotting utilities
"""
import math
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import art3d
from matplotlib.patches import FancyArrowPatch
from mpl_toolkits.mplot3d.proj3d import proj_transform
from mpl_toolkits.mplot3d import Axes3D

from utils.angle import rot_mat_2d

def plot_covariance_ellipse(x, y, cov, chi2=3.0, color="-r", ax=None):
    """
    This function plots an ellipse that represents a covariance matrix. The ellipse is centered at (x, y) and its shape, size and rotation are determined by the covariance matrix.

    Parameters:
    x : (float) The x-coordinate of the center of the ellipse.
    y : (float) The y-coordinate of the center of the ellipse.
    cov : (numpy.ndarray) A 2x2 covariance matrix that determines the shape, size, and rotation of the ellipse.
    chi2 : (float, optional) A scalar value that scales the ellipse size. This value is typically set based on chi-squared distribution quantiles to achieve certain confidence levels (e.g., 3.0 corresponds to ~95% confidence for a 2D Gaussian). Defaults to 3.0.
    color : (str, optional) The color and line style of the ellipse plot, following matplotlib conventions. Defaults to "-r" (a red solid line).
    ax : (matplotlib.axes.Axes, optional) The Axes object to draw the ellipse on. If None (default), a new figure and axes are created.

    Returns:
    None. This function plots the covariance ellipse on the specified axes.
    """
    eig_val, eig_vec = np.linalg.eig(cov)

    if eig_val[0] >= eig_val[1]:
        big_ind = 0
        small_ind = 1
    else:
        big_ind = 1
        small_ind = 0
    a = math.sqrt(chi2 * eig_val[big_ind])
    b = math.sqrt(chi2 * eig_val[small_ind])
    angle = math.atan2(eig_vec[1, big_ind], eig_vec[0, big_ind])
    plot_ellipse(x, y, a, b, angle, color=color, ax=ax)

def plot_ellipse(x, y, a, b, angle, color="-r", ax=None, **kwargs):
    """
    This function plots an ellipse based on the given parameters.

    Parameters
    ----------
    x : (float) The x-coordinate of the center of the ellipse.
    y : (float) The y-coordinate of the center of the ellipse.
    a : (float) The length of the semi-major axis of the ellipse.
    b : (float) The length of the semi-minor axis of the ellipse.
    angle : (float) The rotation angle of the ellipse, in radians.
    color : (str, optional) The color and line style of the ellipse plot, following matplotlib conventions. Defaults to "-r" (a red solid line).
    ax : (matplotlib.axes.Axes, optional) The Axes object to draw the ellipse on. If None (default), a new figure and axes are created.
    **kwargs: Additional keyword arguments to pass to plt.plot or ax.plot.

    Returns
    ---------
    None. This function plots the ellipse based on the specified parameters.
    """

    t = np.arange(0, 2 * math.pi + 0.1, 0.1)
    px = [a * math.cos(it) for it in t]
    py = [b * math.sin(it) for it in t]
    fx = rot_mat_2d(angle) @ (np.array([px, py]))
    px = np.array(fx[0, :] + x).flatten()
    py = np.array(fx[1, :] + y).flatten()
    if ax is None:
        plt.plot(px, py, color, **kwargs)
    else:
        ax.plot(px, py, color, **kwargs)

def plot_arrow(x, y, yaw, arrow_length=1.0,
               origin_point_plot_style="xr",
               head_width=0.1, fc="r", ec="k", **kwargs):
    """
    Plot an arrow or arrows based on 2D state (x, y, yaw)

    All optional settings of matplotlib.pyplot.arrow can be used.
    - matplotlib.pyplot.arrow:
    https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.arrow.html

    Parameters
    ----------
    x : a float or array_like
        a value or a list of arrow origin x position.
    y : a float or array_like
        a value or a list of arrow origin y position.
    yaw : a float or array_like
        a value or a list of arrow yaw angle (orientation).
    arrow_length : a float (optional)
        arrow length. default is 1.0
    origin_point_plot_style : str (optional)
        origin point plot style. If None, not plotting.
    head_width : a float (optional)
        arrow head width. default is 0.1
    fc : string (optional)
        face color
    ec : string (optional)
        edge color
    """
    if not isinstance(x, float):
        for (i_x, i_y, i_yaw) in zip(x, y, yaw):
            plot_arrow(i_x, i_y, i_yaw, head_width=head_width,
                       fc=fc, ec=ec, **kwargs)
    else:
        plt.arrow(x, y,
                  arrow_length * math.cos(yaw),
                  arrow_length * math.sin(yaw),
                  head_width=head_width,
                  fc=fc, ec=ec,
                  **kwargs)
        if origin_point_plot_style is not None:
            plt.plot(x, y, origin_point_plot_style)

def plot_curvature(x_list, y_list, heading_list, curvature,
                   k=0.01, c="-c", label="Curvature"):
    """
    Plot curvature on 2D path. This plot is a line from the original path,
    the lateral distance from the original path shows curvature magnitude.
    Left turning shows right side plot, right turning shows left side plot.
    For straight path, the curvature plot will be on the path, because
    curvature is 0 on the straight path.

    Parameters
    ----------
    x_list : array_like
        x position list of the path
    y_list : array_like
        y position list of the path
    heading_list : array_like
        heading list of the path
    curvature : array_like
        curvature list of the path
    k : float
        curvature scale factor to calculate distance from the original path
    c : string
        color of the plot
    label : string
        label of the plot
    """
    cx = [x + d * k * np.cos(yaw - np.pi / 2.0) for x, y, yaw, d in
          zip(x_list, y_list, heading_list, curvature)]
    cy = [y + d * k * np.sin(yaw - np.pi / 2.0) for x, y, yaw, d in
          zip(x_list, y_list, heading_list, curvature)]

    plt.plot(cx, cy, c, label=label)
    for ix, iy, icx, icy in zip(x_list, y_list, cx, cy):
        plt.plot([ix, icx], [iy, icy], c)

class Arrow3D(FancyArrowPatch):

    def __init__(self, x, y, z, dx, dy, dz, *args, **kwargs):
        super().__init__((0, 0), (0, 0), *args, **kwargs)
        self._xyz = (x, y, z)
        self._dxdydz = (dx, dy, dz)

    def draw(self, renderer):
        x1, y1, z1 = self._xyz
        dx, dy, dz = self._dxdydz
        x2, y2, z2 = (x1 + dx, y1 + dy, z1 + dz)

        xs, ys, zs = proj_transform((x1, x2), (y1, y2), (z1, z2), self.axes.M)
        self.set_positions((xs[0], ys[0]), (xs[1], ys[1]))
        super().draw(renderer)

    def do_3d_projection(self, renderer=None):
        x1, y1, z1 = self._xyz
        dx, dy, dz = self._dxdydz
        x2, y2, z2 = (x1 + dx, y1 + dy, z1 + dz)

        xs, ys, zs = proj_transform((x1, x2), (y1, y2), (z1, z2), self.axes.M)
        self.set_positions((xs[0], ys[0]), (xs[1], ys[1]))

        return np.min(zs)

def _arrow3D(ax, x, y, z, dx, dy, dz, *args, **kwargs):
    '''Add an 3d arrow to an `Axes3D` instance.'''
    arrow = Arrow3D(x, y, z, dx, dy, dz, *args, **kwargs)
    ax.add_artist(arrow)

def plot_3d_vector_arrow(ax, p1, p2):
    setattr(Axes3D, 'arrow3D', _arrow3D)
    ax.arrow3D(p1[0], p1[1], p1[2],
               p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2],
               mutation_scale=20,
               arrowstyle="-|>",
               )

def plot_triangle(p1, p2, p3, ax):
    ax.add_collection3d(art3d.Poly3DCollection([[p1, p2, p3]], color='b'))

def set_equal_3d_axis(ax, x_lims, y_lims, z_lims):
    """Helper function to set equal axis

    Args:
        ax (Axes3DSubplot): matplotlib 3D axis, created by
        `ax = fig.add_subplot(projection='3d')`
        x_lims (np.array): array containing min and max value of x
        y_lims (np.array): array containing min and max value of y
        z_lims (np.array): array containing min and max value of z
    """
    x_lims = np.asarray(x_lims)
    y_lims = np.asarray(y_lims)
    z_lims = np.asarray(z_lims)
    # compute max required range
    max_range = np.array([x_lims.max() - x_lims.min(),
                          y_lims.max() - y_lims.min(),
                          z_lims.max() - z_lims.min()]).max() / 2.0
    # compute mid-point along each axis
    mid_x = (x_lims.max() + x_lims.min()) * 0.5
    mid_y = (y_lims.max() + y_lims.min()) * 0.5
    mid_z = (z_lims.max() + z_lims.min()) * 0.5

    # set limits to axis
    ax.set_xlim(mid_x - max_range, mid_x + max_range)
    ax.set_ylim(mid_y - max_range, mid_y + max_range)
    ax.set_zlim(mid_z - max_range, mid_z + max_range)

if __name__ == '__main__':
    plot_ellipse(0, 0, 1, 2, np.deg2rad(15))
    plt.axis('equal')
    plt.show()


# 코드로 실제 이미지 저장하는 법
import requests
import csv

# 변수 선언
movie_img_url = []
movie_codes = []

with open('movie_naver.csv', 'r', encoding='utf-8') as f:
    reader = csv.DictReader(f)
    for row in reader:
        movie_img_url.append(row['이미지URL']) # 인터넷 상의 이미지파일 리스터 저장
        movie_codes.append(row['영화 대표코드'])

# 요청 -> 파일 저장
for url, movieCd in zip(movie_img_url, movie_codes):
    with open(f'images/{movieCd}.jpg', 'wb') as f: # wb : 바이너리 파일을 쓰겠다.
        response = requests.get(url)
        f.write(response.content) # 텍스트형식(json, html, xml....)이 아닌 형식을 받을 때는 .content


import base64 # library for decoding base64
import pyperclip  # library for copying to clipboard

def decodeInput():
    encoded = input("please put text to decode: ")
    decoded = base64.b64decode(encoded)
    decoded = decoded.decode("utf-8")
    print("your text is: {0} \n".format(decoded))
    copy2clip(decoded)

def copy2clip(txt):
    pyperclip.copy(txt)

def main():

    exit = False

    while not exit:
        flag = input("Want to decode some text? (y/n): ")

        if flag.lower() == "y":
            decodeInput()
        elif flag.lower() == "n":
            exit = True
            print("Goodbye! \n")
        else:
            print("Please enter y or n \n")

if __name__ == '__main__':
    main()


# 238. Product of Array Except Self
# https://leetcode.com/problems/product-of-array-except-self/

class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        to_left_prod, to_right_prod = [1] * len(nums), [1] * len(nums)

        for i in range (1, len(nums)):
            to_left_prod[i] = to_left_prod[i-1] * nums[i-1]
            to_right_prod[-i - 1] = to_right_prod[-i - 1 +1] * nums[-i - 1 +1]

        return [to_left_prod[i] * to_right_prod[i] for i in range(len(nums))]

python/[20-12-04] Product of Array Except Self.py.py


from cornifer.errors import NOT_ABSOLUTE_ERROR_MESSAGE
from cornifer._utilities import BASE52

REG_FILENAME           = "register"
VERSION_FILEPATH       = f"{REG_FILENAME}/version.txt"
SHORTHAND_FILEPATH     = f"{REG_FILENAME}/shorthand.txt"
MSG_FILEPATH           = f"{REG_FILENAME}/message.txt"
CLS_FILEPATH           = f"{REG_FILENAME}/class.txt"
DATABASE_FILEPATH      = f"{REG_FILENAME}/database"
MAP_SIZE_FILEPATH      = f"{REG_FILENAME}/mapsize.txt"

LOCAL_DIR_CHARS        = BASE52
COMPRESSED_FILE_SUFFIX = ".zip"

def check_reg_structure(local_dir):
    """
    :param local_dir: (type `pathlib.Path`) Absolute.
    :raise FileNotFoundError
    """

    if not local_dir.is_absolute():
        raise ValueError(NOT_ABSOLUTE_ERROR_MESSAGE.format(str(local_dir)))

    problems = []

    if not local_dir.is_dir():
        problems.append(str(local_dir))

    for path in [VERSION_FILEPATH, MSG_FILEPATH, CLS_FILEPATH, MAP_SIZE_FILEPATH]:
        if not (local_dir / path).is_file():
            problems.append(str(local_dir / path))

    for path in [DATABASE_FILEPATH]:
        if not (local_dir / path).is_dir():
            problems.append(str(local_dir / path))

    if len(problems) > 0:
        raise FileNotFoundError(
            "Could not find the following files or directories: "
            ", ".join(problems)
        )


import logging
import os

# Logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

if not logger.hasHandlers():
    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)
    ch.setFormatter(logging.Formatter(
        '%(levelname)s: %(name)s - %(message)s'
    ))
    logger.addHandler(ch)

def create_new_logger(new_logger, name):
    name = filename_to_loggingname(name)
    new_logger.setLevel(logging.INFO)
    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)
    ch.setFormatter(logging.Formatter(
        '%(levelname)s: {} - %(message)s'.format(name)
    ))
    new_logger.addHandler(ch)
    return new_logger

def filename_to_loggingname(filename):
    # assumption is that asr_standardized_combined occurs 2x in path e.g. .../asr_standardized_combined/asr_standardized_combined/standardize/standardize_nbtale12.py
    package_name = 'asr_standardized_combined'
    # get everything after the first package name
    filename = os.path.normpath(filename)
    return '.'.join([part for part in filename[filename.index(package_name) + len(package_name):].strip('.py').split(os.sep) if part])


import sys
n = int(sys.stdin.readline())
cnt = 0
temp = 1
for i in range(1, n+1):
    temp *= i
while True:
    if temp % 10 == 0:
        cnt += 1
    else:
        break
    temp //= 10

print(cnt)


line = input()

l = len(line)
d = 1
i = 1

print("{")
while i < l-1:
    if line[i] == "{":
        msg = "  "*d + "{"
        d += 1
    elif line[i] == "}":
        d -= 1
        msg = "  "*d + "}"
    else:
        msg = "  "*d + line[i]

        while line[i+1] not in ",}":
            msg += line[i+1]
            i += 1

    if line[i+1] == ",":
        msg += ","
        i += 1

    print(msg)
    i += 1

print("}")


from collections import Counter, OrderedDict, defaultdict
from finedial.utils.logging.logger_helper import logger
from torchtext.vocab import Vocab

def load_vocab(vocab_path, special_tokens=[], placeholder_tokens=0, enable_duplication=False, reset_unk=None):
    """
     创建词表，
        Args:
            vocab_path: 需要给定的是已经排序好，确定好词表的文件，这里仅增加特殊符号
            special_tokens: 哪些特殊符号
            placeholder_tokens: 哪些需要创建的特殊符号，以及对应的最大数量。
            enable_duplication: 多个词表之间是否允许重复
    """
    counter = Counter()
    assert vocab_path is not None
    if isinstance(vocab_path, str):
        with open(vocab_path, 'r+', encoding='utf-8') as fin:
            vocabs = [x.strip('\r\n') for x in fin.readlines()]
            assert len(vocabs) == len(set(vocabs))
    elif isinstance(vocab_path, list):
        vocabs = []
        vocab_set = set()
        for sub_vocab_path in vocab_path:
            with open(sub_vocab_path, 'r+', encoding='utf-8') as fin:
                sub_vocabs = [x.strip('\r\n') for x in fin.readlines()]
                if not enable_duplication:
                    assert len(vocab_set - set(sub_vocabs)) == 0
                    assert len(set(sub_vocabs)) == len(sub_vocabs)
                vocabs += sub_vocabs
    else:
        raise NotImplementedError()

    vocabs += ['<%s_%d>' % ('dmc', x) for x in range(placeholder_tokens)]
    vocab_size = len(vocabs)
    for idx, token in enumerate(vocabs):
        counter[token] = vocab_size - idx

    specials = list(OrderedDict.fromkeys(tok for tok in special_tokens if tok is not None))
    vocab = Vocab(counter, specials=specials)
    if reset_unk is None:
        return vocab
    # 增加
    unk_index = vocab.stoi[reset_unk]
    new_stoi = defaultdict(lambda :unk_index)
    for k, v in vocab.stoi.items():
        new_stoi[k] = v
    vocab.stoi = new_stoi
    return vocab

def load_vocab_from_list(vocabs, sp_tokens=None):
    """
     创建词表，
        Args:
            vocab: 已经确定好的词表
    """
    counter = Counter()
    vocab_size = len(vocabs)
    vocabs = list(vocabs)
    if sp_tokens is not None:
        vocab_set = set(vocabs)
        vocab_dict = dict()
        for word in vocabs:
            vocab_dict[word] = len(vocab_dict)
        unused_id = 0
        res = ''
        for sp_token in sp_tokens:
            if sp_token not in vocab_set:
                unused_id += 1
                uid = '[unused%d]' % unused_id
                assert uid in vocab_dict, 'unused id is not enough : %s, vocablist=%s' % (uid, str(vocab_dict))
                vocabs[vocab_dict[uid]] = sp_token
                vocab_dict[sp_token] = unused_id
                res += '%s->%s ' % (uid, sp_token)
                vocab_set.add(sp_token)
        logger.info('[SP_TOKEN MAP] %s' % res)
    for idx, token in enumerate(vocabs):
        counter[token] = vocab_size - idx
    return Vocab(counter, specials=[])


# -*- coding: utf-8 -*-
# snapshottest: v1 - https://goo.gl/zC4yUc
from __future__ import unicode_literals

from snapshottest import Snapshot

snapshots = Snapshot()

snapshots['CategoryTestCase::test_can_fetch_all_categories 1'] = {
    'data': {
        'categoryList': {
            'edges': [
                {
                    'node': {
                        'description': 'For people who want to be happy.',
                        'featuredImage': 'https://cdn.eleganttheme.com/1',
                        'id': 'Q2F0ZWdvcnlOb2RlOjI3',
                        'name': 'Swimming Meetup 1'
                    }
                },
                {
                    'node': {
                        'description': 'For people who want to be happy.',
                        'featuredImage': 'https://cdn.eleganttheme.com/2',
                        'id': 'Q2F0ZWdvcnlOb2RlOjI4',
                        'name': 'Swimming Meetup 2'
                    }
                },
                {
                    'node': {
                        'description': 'For people who want to be happy.',
                        'featuredImage': 'https://cdn.eleganttheme.com/3',
                        'id': 'Q2F0ZWdvcnlOb2RlOjI5',
                        'name': 'Swimming Meetup 3'
                    }
                },
                {
                    'node': {
                        'description': 'For people who want to be happy.',
                        'featuredImage': 'https://cdn.eleganttheme.com/4',
                        'id': 'Q2F0ZWdvcnlOb2RlOjMw',
                        'name': 'Swimming Meetup 4'
                    }
                },
                {
                    'node': {
                        'description': 'For people who want to be happy.',
                        'featuredImage': 'https://cdn.eleganttheme.com/5',
                        'id': 'Q2F0ZWdvcnlOb2RlOjMx',
                        'name': 'Swimming Meetup 5'
                    }
                }
            ]
        }
    }
}

snapshots['CategoryTestCase::test_can_fetch_single_category 1'] = {
    'data': {
        'category': {
            'description': 'For people who want to be happy.',
            'featuredImage': 'https://cdn.eleganttheme.com/5',
            'id': 'Q2F0ZWdvcnlOb2RlOjM2',
            'name': 'Swimming Meetup 5'
        }
    }
}


import string as st
from tkinter import *
from tkinter import messagebox
from tkinter.filedialog import askopenfile, asksaveasfilename
import os
import sys

CWDPATH = os.path.abspath(os.path.dirname(sys.argv[0]))

allASCII = st.printable

theKey = '''Congue comprehensam eam id, utroque forensibus ad quo, pertinax sensibus dissentias vim at. Cu brute reprimique dissentiunt duo. Nullam platonem intellegam ea eam. Quo ei numquam qualisque consetetur, hinc mediocrem cu pri. Sea id paulo facilisis iracundia, sea ad civibus principes splendide, nam oportere contentiones signiferumque te. Te per semper intellegam. Ex vis unum elitr aperiam.
Pro at vidit vocibus, an laboramus reprimique efficiantur nec. His ignota vivendum recteque ut, ad eam paulo recteque. Nominavi iracundia quo te, eu sit viderer assentior? Sed at torquatos mediocritatem, diam quodsi et mea, mollis oblique scripserit ut per! Quando incorrupte pri ex, eruditi sententiae sit an! Eum ex natum consul dolorem!
Qui et accusamus definitiones, nam dicat quodsi et, liber iracundia has in. At mea eleifend petentium, eu quodsi nostrud reprimique vix. Per ludus prompta consequuntur et, ei sit ludus evertitur, atqui electram pri no. Discere percipitur ne pri! Delenit accusam facilisi eum no, in mea malis suscipit!
Mel alii purto viris ut, nostrum incorrupte vituperatoribus eu usu, eu petentium conclusionemque nec. Omnes honestatis an vis, eros posse eu est, no mei solet democritum interpretaris. Vix vero forensibus te, nostrum convenire adolescens eu vim! Vim te ignota vituperata consequuntur.
Error aperiri adversarium an est, vel id dicat denique. Ei nec ipsum mediocritatem, detraxit posidonium nec ea! Duis iuvaret admodum est eu, sea at partem periculis dignissim! Te mel ullum persequeris! Graeci eleifend vel ad, cu facilisi rationibus est. Pro ex facilis indoctum.
Ea vim nostrud suavitate, reque quando consequat eu vim. Nam mnesarchum complectitur cu, cum ne elit argumentum, fabulas ullamcorper vim ad. Vis tation graece eripuit ex, dolor vocent at usu. Veniam doctus legendos ea cum. In eos unum contentiones, ea duo sale harum soluta.
Amet modus ceteros eam an. Te amet esse mel, vim vero appareat ex. Pri ex modo scripta indoctum. Splendide sadipscing no pro, eripuit splendide te sed. Per legimus partiendo ei, erat epicuri ad vim! Veritus suscipiantur te vel.
Vidit natum delenit mea ad, ex pro maiorum platonem! Dolorem assueverit efficiantur eu vim. Eum id probatus disputationi, duo molestie qualisque no. Nam vide rationibus cu. Illum facer verterem ei has!
Et appetere complectitur quo. Ex magna utroque efficiendi pro. Sed ei partem persequeris, eu amet graecis vivendo ius. Enim suscipit efficiantur pro te, iisque argumentum quo ex! Ut noster impetus pri. Vix an sumo errem atomorum! Id tale error vel.
Alienum persecuti id eum, et eum enim autem molestie. Vulputate theophrastus delicatissimi ei his, ei pro odio putent pertinacia? Vim eu posse verear. Cu quo enim voluptatum appellantur, eos et volumus eligendi, alia legere menandri his ut! Cu pro etiam mazim petentium, est ex exerci scripserit.'''

def complete_Key(keystring):
	'''
	Returns a list of characters contained in the keystring so the program raises exceptions whenever you try to encode a message containing unmapped characters.
	If some ascii characters are missing, they are added at the end of the string.
	'''
	origChars = set(keystring)

	if any(char not in allASCII for char in origChars):
		messagebox.showerror("Error","currentKey.txt contains non ASCII characters. Program will terminate.")
		sys.exit()

	charsToAdd = [char for char in allASCII if char not in origChars]
	stringToAdd = ''.join(charsToAdd)
	finalKey = keystring + stringToAdd
	return finalKey

def count_Frequency(keystring):
    '''
    Returns a sorted dictionary containing all ASCII characters and their frequencies in the keystring.
    '''
    completeKey = complete_Key(keystring)
    freqDict = {}
    for char in set(completeKey):
        freqDict[char] = completeKey.count(char)
    freqDict = sort_FreqDict(freqDict)
    return freqDict

def sort_FreqDict(dic):
	'''
	Sorts chars dictionary by frequency. Ties are broken by 'alphabetical' order to ensure sorting consistency.
	'''
	if type(dic) is list:
		toDict = dict(dic)
		sortedDict = sorted(toDict.items(), key=lambda x: x[1], reverse=True)
	else:
		sortedDict = dict(sorted(dic.items(), key=lambda x: (x[1],x[0]), reverse=True))
	return sortedDict

def code_Gen(tree):
	'''
	Generates the code mapping and returns a dictionary
	'''
	root = max(tree.keys(),key=lambda x: len(x)) #gets the root key of the tree
	codeDict = {}
	for char in root:
		code = ''
		for child in tree.values():
			if child:
				if char in child[0]:
					code = '0' + code
				elif char in child[1]:
					code = '1' + code
			else:
				continue
		codeDict[char] = code
	return codeDict

def create_Tree(dic):
	'''
	Creates the tree and nodes.
	'''
	pqueue = list(dic.items())
	newNode = {}
	for char in dic.keys(): #initializes leaf nodes
		newNode[char] = []
	while len(pqueue) > 1:
		newKey = pqueue[-1][0] + pqueue[-2][0]
		newFreq = pqueue[-1][1] + pqueue[-2][1]
		reinsertedNode = (newKey,newFreq) #creates a node for reinsertion into pqueue
		newNode[newKey] = [pqueue[-1][0], pqueue[-2][0]] #adds a pair of child nodes to each new node

		pqueue = pqueue[:-2]  #removes child nodes from pqueue
		pqueue.append(reinsertedNode)
		pqueue = sort_FreqDict(pqueue)
	treeDict = newNode
	return treeDict

def zigzag_Split(seq):
	'''
	Splits a sequence into two, alternating the values. Expects a sorted list or dict as input.
	'''
	if type(seq) is dict:
		seq = list(seq.items())
		dic1, dic2 = seq[::2], seq[1::2]
		dic1, dic2 = dict(dic1), dict(dic2)
		return dic1, dic2
	else:
		return seq[::2], seq[1::2]

def map_Code(keystring):
	'''
	Puts all the above functions into one box. Returns the code map.
	The frequency dictionary is split into 4 smaller dictionaries. Generates cleaner tree and shorter codes.
	'''
	freqDict = count_Frequency(keystring)
	freq0, freq1 = zigzag_Split(freqDict)
	freq00, freq01 = zigzag_Split(freq0)
	freq10, freq11 = zigzag_Split(freq1)
	tree00, tree01, tree10, tree11 = create_Tree(freq00), create_Tree(freq01), create_Tree(freq10), create_Tree(freq11)
	code00, code01, code10, code11 = code_Gen(tree00), code_Gen(tree01), code_Gen(tree10), code_Gen(tree11)
	for k, v in code00.items():
		code00[k] = '00'+v
	for k, v in code01.items():
		code01[k] = '01'+v
	for k, v in code10.items():
		code10[k] = '10'+v
	for k, v in code11.items():
		code11[k] = '11'+v
	mergedCode = {**code00, **code01, **code10, **code11}
	return mergedCode

def encode_Text(text, codedict):
	'''
	Encodes a given text using code map generated by code_Gen (or map_Code)
	'''
	encText = ''
	for char in text:
		try:
			encText += codedict[char]
		except KeyError:
			print('Only ASCII characters are accepted for now')
			return
	return encText

def decode_Text(text, codedict):
	'''
	Decodes a previously encoded text provided the both encryption and decryption used the right key.
	'''
	text = text.strip()
	if any(char not in '01' for char in text):
		print('Error: expected string of 0s and 1s.')
		return
	reversedDict = {v:k for k,v in codedict.items()}
	decText = ''
	fullCharCode = ''
	for digit in text:
		fullCharCode += digit
		try:
			decText += reversedDict[fullCharCode]
			fullCharCode = ''
		except KeyError:
			continue
	return decText

def enc_Button():
	toencode = inputText.get('1.0', END)
	toencode = toencode[:-1]
	try:
		enctext = encode_Text(toencode,theCode)
		outputText.delete('1.0',END)
		outputText.insert(END, enctext)
	except:
		messagebox.showerror("Error","Only ASCII characters are currently valid.")
		return
	return

def dec_Button():
	todecode = outputText.get('1.0', END)
	todecode = todecode[:-1]
	try:
		dectext = decode_Text(todecode,theCode)
		inputText.delete('1.0',END)
		inputText.insert(END, dectext)
	except:
		messagebox.showerror("Error","Only 0s and 1s allowed.")
		return
	return

def viewset_Key():
	global theKey, theCode
	answer = messagebox.askyesno('Change encryption key?', f'The current encryption key is:\n\n{theKey}\n\nDo you want to set a new key?', default='no', icon='question', parent=root)
	if answer == False:
		return
	else:
		file = askopenfile(mode = 'r', filetypes=[("Text","*.txt")], title="Select a text file...")
		if file:
			newKey = file.read()
			newKeySet = set(newKey)
			if any(char not in allASCII for char in newKeySet) or not newKey:
				messagebox.showerror("Error","Selected file contains non ASCII characters or is blank. Key not changed.")
				return
			if len(newKeySet) < 27:
				answer = messagebox.askyesno('Data set too small', "The selected file doesn't contain enough unique ASCII characters. Encoded messages will be longer than usual, but encryption/decryption will still work. Do you want to continue?", default='no', icon='question', parent=root)
				if answer == False:
					return

			answer = messagebox.askyesno('Back up current key?', 'Do you want to save the current key to a backup txt file?', default='no', icon='question', parent=root)
			if answer == True:
				filename = asksaveasfilename(defaultextension=".txt", filetypes=[("Text","*.txt")], title="Save file as")
				if filename:
					with open(filename, "w") as output_file:
						output_file.write(theKey)

			theKey = newKey
			theCode = map_Code(theKey)

			set_defaultKeyFile(theKey)
			file.close()
			messagebox.showinfo('Done!','Key successfully updated!')

def set_defaultKeyFile(keystring):
	defaultKeyFile = open('currentKey.txt', 'w')
	defaultKeyFile.write(keystring)
	defaultKeyFile.close()

def get_defaultKeyFile():
	defaultKeyFile = open('currentKey.txt', 'r')
	newKey = defaultKeyFile.read()
	defaultKeyFile.close()
	return newKey

if __name__ == '__main__':
	root = Tk()
	root.title("Message encyptor/decryptor - by Bernardo Tonasse")
	try:
		root.iconbitmap("EncDec.ico")
	except:
		pass

	# Initializing keystring and code mapping-------------
	try:
		theKey = get_defaultKeyFile()
	except:
		set_defaultKeyFile(theKey)
		root.withdraw()
		messagebox.showinfo('Warning',"Default key 'currentKey.txt' not found. Initializing placeholder key.")
		root.deiconify()
	theCode = map_Code(theKey)
	# ----------------------------------------------------

	inputScroll = Scrollbar(root)
	outputScroll = Scrollbar(root)
	inputText = Text(root, selectbackground = 'gray', yscrollcommand = inputScroll.set)
	outputText = Text(root, bg = 'black', fg = 'white', insertbackground = 'white', selectbackground = 'gray', yscrollcommand = outputScroll.set)
	inputScroll.config(command=inputText.yview)
	outputScroll.config(command=outputText.yview)

	encBtn = Button(root, text='ENCODE-->', command=enc_Button)
	decBtn = Button(root, text='<--DECODE', command=dec_Button)
	keyBtn = Button(root, text='VIEW/SET KEY', command=viewset_Key)

	root.grid_rowconfigure(0, weight=1)
	root.grid_columnconfigure(0, weight=1)
	root.grid_columnconfigure(2, weight=1)
	inputText.grid   (row = 0, column = 0, padx = (4,0), pady = 4, sticky=N+E+W+S)
	inputScroll.grid (row = 0, column = 1, padx = (0,4), pady = 4, sticky=N+S)
	outputText.grid  (row = 0, column = 2, padx = (0,0), pady = 4, sticky=N+E+W+S)
	outputScroll.grid(row = 0, column = 3, padx = (0,4), pady = 4, sticky=N+S)
	encBtn.grid      (row = 1, column = 0, padx = (4,0), pady = (0,4), columnspan = 2, sticky = E+W)
	decBtn.grid      (row = 1, column = 2, padx = (0,4), pady = (0,4), columnspan = 2, sticky = E+W)
	keyBtn.grid      (row = 2, column = 0, padx = 4, columnspan = 4, sticky = E+W)

	root.mainloop()


import os
import logging
from osgeo import gdalconst
from osgeo import ogr
from osgeo import osr

from .version import __program__

class OgrDatasource:
    def __init__(self, translation, source_proj4=None, source_epsg=None, gisorder=False, \
                       source_encoding='utf-8'):
        self.logger = logging.getLogger(__program__)
        self.datasource = None
        self.is_database_source = False
        self.query = None
        self.translation = translation
        self.source_proj4 = source_proj4
        self.source_epsg = source_epsg
        self.gisorder = gisorder
        self.source_encoding = source_encoding

    def open_datasource(self, ogrpath, prefer_mem_copy=True):
        full_ogrpath = None

        # database source ?
        if ogrpath.startswith('PG:'):
            self.is_database_source = True
            full_ogrpath = ogrpath
        else:
            # unsupported access method ?
            ogr_unsupported = [ "vsimem", "vsistdout" ]
            has_unsup = [ m for m in ogr_unsupported if m in ogrpath.split('/') ]
            if has_unsup:
                self.logger.error("Unsupported OGR access method(s) found: %s.", \
                                  ', '.join(has_unsup))

            # using ogr access methods ?
            ogr_accessmethods = [ "vsicurl", "vsicurl_streaming", "vsisubfile", "vsistdin" ]
            if any([ m in ogrpath.split('/') for m in ogr_accessmethods ]):
                full_ogrpath = ogrpath
            else:
                filename = ogrpath

                # filter out file access method if present
                ogr_filemethods = [ "/vsisparse/", "/vsigzip/", "/vsitar/", "/vsizip/" ]
                for fm in ogr_filemethods:
                    if ogrpath.find(fm) == 0:
                        filename = ogrpath[len(fm):]
                        break

                if not os.path.exists(filename):
                    self.logger.error("The file '%s' does not exist.", filename)
                elif ogrpath == filename:
                    if filename.endswith('.tar') or \
                       filename.endswith('.tgz') or \
                       filename.endswith('.tar.gz'):
                        full_ogrpath = '/vsitar/' + filename
                    elif filename.endswith('.gz'):
                        full_ogrpath = '/vsigzip/' + filename
                    elif filename.endswith('.zip'):
                        full_ogrpath = '/vsizip/' + filename
                    else:
                        full_ogrpath = filename
                else:
                    full_ogrpath = filename

        if full_ogrpath:
            file_datasource = None
            if not self.is_database_source and prefer_mem_copy:
                file_datasource = ogr.Open(full_ogrpath, gdalconst.GA_ReadOnly)
            else:
                self.datasource = ogr.Open(full_ogrpath, gdalconst.GA_ReadOnly)

            if self.is_database_source and not self.datasource:
                self.logger.error("OGR failed to open connection to %s.", full_ogrpath)
            elif not self.is_database_source and not self.datasource and not file_datasource:
                self.logger.error("OGR failed to open '%s', format may be unsupported.", \
                                  full_ogrpath)
            elif not self.is_database_source and file_datasource and prefer_mem_copy:
                mem_driver = ogr.GetDriverByName('Memory')
                self.datasource = mem_driver.CopyDataSource(file_datasource, 'memoryCopy')

    def set_query(self, query):
        self.query = query

    def __get_source_reprojection_func(self, layer):
        layer_spatial_ref = layer.GetSpatialRef()

        spatial_ref = None
        if self.source_proj4:
            spatial_ref = osr.SpatialReference()
            if self.gisorder:
                spatial_ref.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
            spatial_ref.ImportFromProj4(self.source_proj4)
        elif self.source_epsg:
            spatial_ref = osr.SpatialReference()
            if self.gisorder:
                spatial_ref.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
            spatial_ref.ImportFromEPSG(self.source_epsg)
        elif layer_spatial_ref:
            spatial_ref = layer_spatial_ref
            self.logger.info("Detected projection metadata:\n%s", str(layer_spatial_ref))
        else:
            self.logger.info("Layer has no projection metadata, falling back to EPSG:4326")
            if not self.gisorder:
                spatial_ref = osr.SpatialReference()
                spatial_ref.ImportFromEPSG(4326)

        # No source proj specified yet? Then default to do no reprojection.
        # Some python magic: skip reprojection altogether by using a dummy
        # lamdba funcion. Otherwise, the lambda will be a call to the OGR
        # reprojection stuff.
        reproject = lambda geometry: None

        if spatial_ref:
            # Destionation projection will *always* be EPSG:4326, WGS84 lat-lon
            dest_spatial_ref = osr.SpatialReference()
            dest_spatial_ref.SetAxisMappingStrategy(osr.OAMS_TRADITIONAL_GIS_ORDER)
            dest_spatial_ref.ImportFromEPSG(4326)
            coord_trans = osr.CoordinateTransformation(spatial_ref, dest_spatial_ref)
            reproject = lambda geometry: geometry.Transform(coord_trans)

        return reproject

    def get_layer_count(self):
        if self.is_database_source:
            return 1
        else:
            return self.datasource.GetLayerCount()

    def get_layer(self, index):
        layer = None
        if self.is_database_source:
            if self.query:
                # TODO: avoid executing the query more than once
                layer = self.datasource.ExecuteSQL(self.query)
                layer.ResetReading()
            else:
                self.logger.error("Query must be set first when the datasource is a database.")
        else:
            layer = self.datasource.GetLayer(index)
            layer.ResetReading()

        filteredlayer = self.translation.filter_layer(layer)
        return (filteredlayer, self.__get_source_reprojection_func(filteredlayer))


from distutils import dist
from io import StringIO
from json import dumps
from pkg_resources import DistributionNotFound, get_distribution

from fastapi.responses import HTMLResponse
from jinja2 import Template

from microcosm_fastapi.templates.landing import template

def configure_landing(graph):  # noqa: C901
    def get_properties_and_version():
        """
        Parse the properties from the package information
        """
        try:
            distribution = get_distribution(graph.metadata.name)
            metadata_str = distribution.get_metadata(distribution.PKG_INFO)
            package_info = dist.DistributionMetadata()
            package_info.read_pkg_file(StringIO(metadata_str))
            return package_info
        except DistributionNotFound:
            return None

    def iter_endpoints(graph, match_func):
        for route in graph.app.routes:
            if match_func(route.path):
                yield route

    def get_swagger_versions():
        """
        Finds all swagger conventions that are bound to the graph

        """
        versions = []

        def is_swagger_endpoint(path):
            """
            Defines a condition to determine which endpoints are swagger type

            """
            return graph.config.swagger_convention.name in path

        for route in iter_endpoints(graph, is_swagger_endpoint):
            # route comes in as /api/v2/swagger
            # so we split to get this -> ['', 'api', 'v2', 'swagger']
            # and then get the version value from the array
            versions.append(route.path.split("/")[2])

        return versions

    def pretty_dict(dict_):
        return dumps(dict_, sort_keys=True, indent=2, separators=(",", ": "))

    def get_env_file_commands(config, conf_key, conf_string=None):
        if conf_string is None:
            conf_string = []
        for key, value in config.items():
            if isinstance(value, dict):
                get_env_file_commands(value, "{}__{}".format(conf_key, key), conf_string)
            else:
                conf_string.append(
                    "export {}__{}='{}'".format(conf_key.upper(), key.upper(), value)
                )
        return conf_string

    def get_links(swagger_versions, properties):
        # add links set in config
        links = {
            key: value
            for (key, value) in graph.config.landing_convention.get("links", {}).items()
        }

        # add links for each swagger version
        for swagger_version in swagger_versions:
            links["swagger {}".format(swagger_version)] = "api/{}/swagger".format(swagger_version)

        # add link to home page
        if hasattr(properties, "url"):
            links["home page"] = properties.url

        return links

    @graph.app.get("/")
    async def render_landing_page():
        """
        Render landing page

        """
        config = graph.config_convention.to_dict()
        env = get_env_file_commands(config, graph.metadata.name)

        health = await graph.health_convention.to_object()
        health = health.dict()

        properties = get_properties_and_version()
        swagger_versions = get_swagger_versions()

        html = Template(template).render(
            config=pretty_dict(config),
            description=properties.description if properties else None,
            env=env,
            health=pretty_dict(health),
            links=get_links(swagger_versions, properties),
            service_name=graph.metadata.name,
            version=getattr(properties, "version", None),
        )

        return HTMLResponse(html)


# -*- coding: utf-8 -*-
"""
Created on Thu Nov 14 18:08:06 2019

@author: shirley
"""

import pandas as pd
import numpy as np
data = pd.read_csv("dataset.csv", header = None)
data1 = data.rename(columns = {0:'Alt',1:'Bar',2:'Fri',3:'Hun',4:'Pat',5:'Price',6:'Rain',7:'Res',8:'Type',9:'Est',10:'Target'})
Idx_infer ={'Alt':0,'Bar':1,'Fri':2,'Hun':3,'Pat':4,'Price':5,'Rain':6,'Res':7,'Type':8,'Est':9,'Target':10}
data_name = data1.columns.values.tolist()
data_copy = data.copy()
# data_name.pop(2)
data_name
data1['Type']
data_copy

Alt = data.iloc[:,0]
Bar = data.iloc[:,1]
Fri = data.iloc[:,2]
Hun = data.iloc[:,3]
Pat = data.iloc[:,4]
Price = data.iloc[:,5]
Rain = data.iloc[:,6]
Res = data.iloc[:,7]
Type = data.iloc[:,8]
Est = data.iloc[:,9]
Target = data.iloc[:,10]

from math import log
def B(x):
    if x != 0 and x!= 1:
        return -(x * log(x,2) + (1-x) * log(1-x,2))
    elif x == 0:
        return 0
    elif x == 1:
        return 0

def Gani(X,parent_examples):

    parent_examples_T = 0
    for i in parent_examples.index.tolist():
        if Target.loc[i] == ' T':
            parent_examples_T += 1

    Gani_parents = B(parent_examples_T/len(parent_examples))

    value_cnt = {}
    for value in X:
        value_cnt[value] = value_cnt.get(value, 0) + 1

    keys = []
    for key in value_cnt.keys():
        keys.append(key)

    if len(keys) == 1:
        return 0

    if len(keys) == 2:

        num_1 = 0#the number of 'T'
        num_2 = 0
        sum_value_1_target_T = 0
        sum_value_2_target_T = 0
        for i in parent_examples.index.tolist():#here is some problem that the idx should be the number of row of parent_examples
            if X[i] == keys[0]:
                num_1 +=1
                if Target.loc[i] == ' T':
                     sum_value_1_target_T += 1
            else:
                num_2 += 1
                if Target.loc[i] == ' T':
                    sum_value_2_target_T += 1
        a = num_1/len(parent_examples)
        c = num_2/len(parent_examples)

        if num_1 != 0:
            b = sum_value_1_target_T/num_1
        else:
             b = 0

        if num_2 != 0:
            d = sum_value_2_target_T/num_2
        else:
            d = 0

        return Gani_parents-(a*B(b)+c*B(d))

    if len(keys) == 4:

        num_1 = 0#the number of 'T'
        num_2 = 0
        num_3 = 0#the number of 'T'
        num_4 = 0
        sum_value_1_target_T = 0
        sum_value_2_target_T = 0
        sum_value_3_target_T = 0
        sum_value_4_target_T = 0
        for i in parent_examples.index.tolist():#here is some problem that the idx should be the number of row of parent_examples
            if X[i] == keys[0]:
                num_1 +=1
                if Target.loc[i] == ' T':
                     sum_value_1_target_T += 1
            elif X[i] == keys[1]:
                num_2 += 1
                if Target.loc[i] == ' T':
                    sum_value_2_target_T += 1

            elif X[i] == keys[2]:
                num_3 += 1
                if Target.loc[i] == ' T':
                    sum_value_3_target_T += 1

            elif X[i] == keys[3]:
                num_4 += 1
                if Target.loc[i] == ' T':
                    sum_value_4_target_T += 1

        a = num_1/len(parent_examples)
        c = num_2/len(parent_examples)
        e = num_3/len(parent_examples)
        g = num_4/len(parent_examples)

        if num_1 != 0:
            b = sum_value_1_target_T/num_1
        else:
             b = 0

        if num_2 != 0:
            d = sum_value_2_target_T/num_2
        else:
            d = 0

        if num_3 != 0:
            f = sum_value_3_target_T/num_3
        else:
            f = 0

        if num_4 != 0:
            h = sum_value_4_target_T/num_4
        else:
            h = 0

        return Gani_parents-(a*B(b)+c*B(d)+e*B(f)+g*B(h))

#         return Gani_parents-((num_1/len(parent_examples))*B(sum_value_1_target_T/num_1)+(num_2/len(parent_examples))*B(sum_value_2_target_T/num_2)+(num_3/len(parent_examples))*B(sum_value_3_target_T/num_3)+(num_4/len(parent_examples))*B(sum_value_4_target_T/num_4))

    if len(keys) == 3:

        num_1 = 0#the number of 'T'
        num_2 = 0
        num_3 = 0
        sum_value_1_target_T = 0
        sum_value_2_target_T = 0
        sum_value_3_target_T = 0
        for i in parent_examples.index.tolist():#here is some problem that the idx should be the number of row of parent_examples
            if X[i] == keys[0]:
                num_1 +=1
                if Target.loc[i] == ' T':
                    sum_value_1_target_T += 1

            elif X[i] == keys[1]:
                num_2 += 1
                if Target.loc[i] == ' T':
                    sum_value_2_target_T += 1

            else:
                num_3 += 1
                if Target.loc[i] == ' T':
                    sum_value_3_target_T += 1

        a = num_1/len(parent_examples)
        c = num_2/len(parent_examples)
        e = num_3/len(parent_examples)

        if num_1 != 0:
            b = sum_value_1_target_T/num_1
        else:
             b = 0

        if num_2 != 0:
            d = sum_value_2_target_T/num_2
        else:
            d = 0

        if num_3 != 0:
            f = sum_value_3_target_T/num_3
        else:
            f = 0

        return Gani_parents-(a*B(b)+c*B(d)+e*B(f))

def importance(examples):

    importance = dict()

    for i in range(examples.shape[1]-1):
        importance[i] = Gani(examples.iloc[:,i], examples)

    return importance
#     return examples.iloc[:,max(importance(examples), key=lambda x: importance(examples)[x])]

def leaf_decision(examples):

    if len(examples) == 0:
        return 'without example'

    else:
        num_T = 0
        num_F = 0
        n = examples.shape[1]-1
        for idx, value in examples.iloc[:,n]:
            if value == 'T':
                num_T += 1

            if value == 'F':
                num_F += 1

    #     print(num_T)
    #     print(num_F)
        if num_T == len(examples):
            return 'T'

        elif num_F == len(examples):
            return 'F'

        else:
            return examples

def Plurality_Value(examples):
    num_T = 0
    num_F = 0
    T = Target[0]
    F = Target[1]
    n = examples.shape[1]-1
    for idx, value in examples.iloc[:,n]:
        if value == 'T':
            num_T += 1

        elif value == 'F':
            num_F += 1

    if num_T > num_F:
        return 'T'

    elif num_T < num_F:
        return 'F'

    elif num_T == num_F:
        rd = np.random.rand(1)
        if rd<0.5:
            return 'T'
        else:
            return 'F'

def get_sub_value_example(X, parent_examples):
    # for Alt, Bar, Fri, Hun, Rain, Res

    for i in range(data_copy.shape[1]):
        for key in np.unique(X).tolist():
            if data_copy.iloc[1,i] == key:
                k = i
                break

    keys = np.unique(data_copy.iloc[:,k]).tolist()

    if len(keys) == 2:
        idx_1 = []
        idx_2 = []
        for i in parent_examples.index.tolist():#here is some problem that the idx should be the number of row of parent_examples
            if X[i] == keys[0]:
                idx_1.append(i)
            else:
                idx_2.append(i)

        examples_1 = parent_examples.loc[idx_1,:]
        examples_2 = parent_examples.loc[idx_2,:]
        return examples_1,examples_2

    if len(keys) == 3:
        idx_1 = []
        idx_2 = []
        idx_3 = []
        for i in parent_examples.index.tolist():#here is some problem that the idx should be the number of row of parent_examples
            if X[i] == keys[0]:
                idx_1.append(i)
            elif X[i] == keys[1]:
                idx_2.append(i)
            else:
                idx_3.append(i)

        examples_1 = parent_examples.loc[idx_1,:]
        examples_2 = parent_examples.loc[idx_2,:]
        examples_3 = parent_examples.loc[idx_3,:]
        return examples_1,examples_2,examples_3

    if len(keys) == 4:
        idx_1 = []
        idx_2 = []
        idx_3 = []
        idx_4 = []
        for i in parent_examples.index.tolist():#here is some problem that the idx should be the number of row of parent_examples
            if X[i] == keys[0]:
                idx_1.append(i)
            elif X[i] == keys[1]:
                idx_2.append(i)
            elif X[i] == keys[2]:
                idx_3.append(i)
            else:
                idx_4.append(i)

        examples_1 = parent_examples.loc[idx_1,:]
        examples_2 = parent_examples.loc[idx_2,:]
        examples_3 = parent_examples.loc[idx_3,:]
        examples_4 = parent_examples.loc[idx_4,:]
        return examples_1,examples_2,examples_3,examples_4

tree1 = {'root':{},'leaf':{}, 'node':{}}
tree2 = {'root':{},'leaf':{}, 'node':{}}
tree3 = {'root':{},'leaf':{}, 'node':{}}
tree4 = {'root':{},'leaf':{}, 'node':{}}

def build_subtree(data, tree):
    tree = {'root':{},'leaf':{}, 'node':{}}
    importance(data)
    #find the most important one's # of column
    Id_most_important = max(importance(data), key=lambda x: importance(data)[x])
    #get this attribute
    attribute_name = data_name[Id_most_important]
    #delete this attribute when finish use it
    data_name.pop(Id_most_important)
#   attribute_name = data1.loc[Id_most_important].columns.values
    tree['root'] = attribute_name
    Attri_most_imortant = data.iloc[:,Id_most_important]
    examples_new = 0
   #Then according to its values separate it
   #after I run the code, I know there are 3 parts

#     value_cnt = {}
#     for value in Attri_most_imortant:
#         value_cnt[value] = value_cnt.get(value, 0) + 1

#     keys = []
#     for key in value_cnt.keys():
#         keys.append(key)
    for i in range(data_copy.shape[1]):
        for key in np.unique(Attri_most_imortant).tolist():
            if data_copy.iloc[1,i] == key:
                kk = i
                break

    keys = np.unique(data_copy.iloc[:,kk]).tolist()

    if len(keys) == 3:

        a1, a2, a3 = get_sub_value_example(Attri_most_imortant, data)

       #for every part run the function
        for a in [a1, a2, a3]:
            colu_idx = a.columns.values.tolist()[Id_most_important]

            if len(a) == 0:
                tree['leaf']['no example'] = Plurality_Value(data)

            elif len(leaf_decision(a)) == 1:
                Idx = a.index.tolist()[0]
                leaf = a.loc[Idx, colu_idx]
                tree['leaf'][leaf] = leaf_decision(a)

            else:
                Idx1 = a.index.tolist()[0]
                node = a.loc[Idx1, colu_idx]
                tree['node'][node] = leaf_decision(a)
                examples = tree['node'][node]
                examples_new = examples.drop(Id_most_important, axis=1)

    if len(keys) == 2:

        a1, a2 = get_sub_value_example(Attri_most_imortant, data)
       #for every part run the function

        for a in [a1, a2]:
            colu_idx = a.columns.values.tolist()[Id_most_important]

            if len(a) == 0:
                tree['leaf']['no example'] = Plurality_Value(data)

            elif len(leaf_decision(a)) == 1:
                Idx = a.index.tolist()[0]
                leaf = a.loc[Idx, colu_idx]
                tree['leaf'][leaf] = leaf_decision(a)

            else:
                Idx1 = a.index.tolist()[0]
                node = a.loc[Idx1, colu_idx]
                tree['node'][node] = leaf_decision(a)
                examples = tree['node'][node]
                examples_new = examples.drop(Id_most_important, axis=1)

    if len(keys) == 4:

        a1, a2, a3, a4 = get_sub_value_example(Attri_most_imortant, data)

       #for every part run the function

        for a in [a1, a2, a3, a4]:
            colu_idx = a.columns.values.tolist()[Id_most_important]

            if len(a) == 0:
                tree['leaf']['no example'] = Plurality_Value(data)

            elif len(leaf_decision(a)) == 1:
                Idx = a.index.tolist()[0]
                leaf = a.loc[Idx, colu_idx]
                tree['leaf'][leaf] = leaf_decision(a)

            else:
                Idx1 = a.index.tolist()[0]
                node = a.loc[Idx1, colu_idx]
                tree['node'][node] = leaf_decision(a)
                examples = tree['node'][node]
                examples_new = examples.drop(Id_most_important, axis=1)
#     examples = examples.drop('column_name', Id_most_important)

    #therefore we can get the first subtree

#     print(delt_row)
#     for i,d in enumerate(delt_row):
#         for e,f in enumerate(d):
#             examples_new = examples.drop([d], inplace = False)
    return tree, examples_new

data = pd.read_csv("dataset.csv", header = None)
#data1 = data.iloc[0:8,:]
data1 = data.rename(columns = {0:'Alt',1:'Bar',2:'Fri',3:'Hun',4:'Pat',5:'Price',6:'Rain',7:'Res',8:'Type',9:'Est',10:'Target'})
data_name = data1.columns.values.tolist()

def tree(data):

    new_tree, new_example= build_subtree(data, tree1)
    new_new_tree, new_new_example = build_subtree(new_example, tree2)
    new_new_new_tree, new_new_new_example = build_subtree(new_new_example, tree3)
    new_new_new__new_tree, new_new_new_new_example = build_subtree(new_new_new_example, tree4)
    tree_1 = new_tree
    tree_2 = new_new_tree
    tree_3 = new_new_new_tree
    tree_4 = new_new_new__new_tree
    tree_3['node'] = tree_4
    tree_2['node'] = tree_3
    tree_1['node'] = tree_2

    return tree_1

#define a function to predict the target from data using decision tree
def predict(tree_new, data):

    if data[Idx_infer[tree_new['root']]] in tree_new['leaf']:
        for key in tree_new['leaf']:
            if data[Idx_infer[tree_new['root']]] == key:
                return tree_new['leaf'][key]

    elif data[Idx_infer[tree_new['node']['root']]] in tree_new['node']['leaf']:
        for key in tree_new['node']['leaf']:
            if data[Idx_infer[tree_new['node']['root']]] == key:
                return tree_new['node']['leaf'][key]

    elif data[Idx_infer[tree_new['node']['node']['root']]] in tree_new['node']['node']['leaf']:
        for key in tree_new['node']['node']['leaf']:
            if data[Idx_infer[tree_new['node']['node']['root']]] == key:
                return tree_new['node']['node']['leaf'][key]

    elif data[Idx_infer[tree_new['node']['node']['node']['root']]] in tree_new['node']['node']['node']['leaf']:
        for key in tree_new['node']['node']['node']['leaf']:
            if data[Idx_infer[tree_new['node']['node']['node']['root']]] == key:
                return tree_new['node']['node']['node']['leaf'][key]

def error_rate(data, tree):
    pre = []
    for i in range(data.shape[0]):
        pre.append(predict(tree, data.iloc[i,:]))

    for i in range(len(pre)):
        if pre[i] == 'T':
            pre[i] = 1
        else:
            pre[i] = 0

    orig_target = []
    for i in range(len(data.iloc[:,10])):
        if data.iloc[:,10][i] == ' T':
            orig_target.append(1)
        else:
            orig_target.append(0)

    num_wrong = 0
    for i in range(len(pre)):
        if pre[i] != orig_target[i]:
            num_wrong+=1

    return num_wrong/len(pre)

tree_train = tree(data)
print('This is the decision tree I get.')
print(tree_train)

print('Here is the predict result of trainning data.')
for i in range(data.shape[0]):
        print(predict(tree_train, data.iloc[i,:]))

print('This the error rate on the training set of the learned decision tree:')
print(error_rate(data, tree_train))

#below is the code to get LOOCV:
def tree_for_2(data):
    tree1 = {'root':{},'leaf':{}, 'node':{}}
    tree2 = {'root':{},'leaf':{}, 'node':{}}
    tree3 = {'root':{},'leaf':{}, 'node':{}}
    tree4 = {'root':{},'leaf':{}, 'node':{}}
    new_tree, new_example= build_subtree(data, tree1)
    new_new_tree, new_new_example = build_subtree(new_example, tree2)
    tree_1 = new_tree
    tree_2 = new_new_tree

    tree_1['node'] = tree_2

    return tree_1

def predict_for_2(tree_new, data):

    if data[Idx_infer[tree_new['root']]] in tree_new['leaf']:
        for key in tree_new['leaf']:
            if data[Idx_infer[tree_new['root']]] == key:
                return tree_new['leaf'][key]

    elif data[Idx_infer[tree_new['node']['root']]] in tree_new['node']['leaf']:
        for key in tree_new['node']['leaf']:
            if data[Idx_infer[tree_new['node']['root']]] == key:
                return tree_new['node']['leaf'][key]

train = []
data1 = data.rename(columns = {0:'Alt',1:'Bar',2:'Fri',3:'Hun',4:'Pat',5:'Price',6:'Rain',7:'Res',8:'Type',9:'Est',10:'Target'})
Idx_infer ={'Alt':0,'Bar':1,'Fri':2,'Hun':3,'Pat':4,'Price':5,'Rain':6,'Res':7,'Type':8,'Est':9,'Target':10}
data_name = data1.columns.values.tolist()
for i in [1,2,3,4,5,6,7,8,9,10,11,12]:

    frontPart = data.iloc[:i-1, :]
    rearPart = data.iloc[i:, :]
    tarinData = np.concatenate([np.array(frontPart), np.array(rearPart)], axis=0)
    traindata = pd.DataFrame(tarinData)
    train.append(traindata)

'''
k=11
data_name = data1.columns.values.tolist()
tree_o = tree(train[k]) or tree_for_2(train[k])
print(predict(tree_o, data.iloc[k,:])) or use predict_for_2()
'''


import subprocess
from pathlib import Path
from joblib import Parallel, delayed

gpu_script = Path("./gpus.py")

cmdline = f"cd {gpu_script.parent.absolute()}; pipenv run python3 {gpu_script.absolute()}"
print(cmdline)

def check_host(host: str):
    print("Checking", host)
    proc = subprocess.run(["ssh", host, cmdline], capture_output=True, encoding="UTF-8")

    print(host, ":", proc.stdout) #, proc.stderr)

hosts = ["hyperion", "hyperion3", "turing1", "turing2", "turing3", "turing4", "hyperturing1", "hyperturing2"]

Parallel(n_jobs=8, backend="threading")(
             map(delayed(check_host), hosts))


#CONFIG
import re
import pytz
from datetime import *
LOCAL_TIMEZONE = pytz.timezone("Australia/Perth")
SLOT_LENGTH_MINUTES = 30

DAYS = [  'Monday',
          'Tuesday',
          'Wednesday',
          'Thursday',
          'Friday',
          'Saturday',
          'Sunday']

from html.parser import HTMLParser

class HtmlResolver(HTMLParser):
    def __init__(self):
        super().__init__()
        self.result=""

    def handle_starttag(self, tag, attrs):
        pass

    def handle_endtag(self, tag):
        pass

    def handle_data(self, data):
        self.result+=data

def resolve_html(html_frag):
    oldtext = ""
    text = html_frag
    while text!=oldtext: #keep resolving HTML til no change
        oldtext = text
        res = HtmlResolver()
        res.feed(text)
        text = res.result
    return text

def normalise(string):
    string = resolve_html(string)
    string = resolve_html(string)
    string = string.replace("\r",'')
    string = string.replace("\xa0", " ")

    string = re.sub(r"\n\s*\n", "\n", string)

    return string.strip()

def strip_titles(string):
    return re.sub(r"\b(mr|mrs|dr|ms|mx)\b\s*","",string, flags=re.I)

def load_list(csl):
    ldlst=[]
    if type(csl) is list:
        ldlst=csl
    else:
        ldlst = str.split(csl, ',')

    ldlst=[normalise(ll).strip().replace("\n", " ") for ll in ldlst]
    return [ll for ll in ldlst if len(ll)>0]

def parse_datetime(datetime_str):
    if type(datetime_str) is datetime:
        return datetime_str

    import dateutil.parser

    raw = dateutil.parser.parse(datetime_str)
    return raw.astimezone(LOCAL_TIMEZONE)

class session(object):
    def __init__(self, id,
                 start_time_str,end_time_str,
                 title,tags_str,people_str,
                 venues_str,description):
        self.id = int(id)
        self.start = parse_datetime(start_time_str)
        self.end = parse_datetime(end_time_str)
        self.title = normalise(title)
        self.tags = set(load_list(tags_str))
        self.people = list(map(strip_titles, load_list(people_str)))
        self.venues = set(load_list(venues_str))
        self.description = normalise(description)

    @property
    def day(self):
        week_days   = DAYS
        daynum = self.start.weekday()
        return week_days[daynum]

    @property
    def start_time(self):
        return self.start.strftime("%H:%M")

    @property
    def end_time(self):
        return self.end.strftime("%H:%M")

    @property
    def duration(self):
        return self.end - self.start

    def __str__(self):
        str(self.__dict__)

def load_sessions_csv(csvpath):
    import csv
    sessions = []
    with open(csvpath, 'r') as csvfile:
        con_csv = csv.reader(csvfile)
        next(con_csv) #Skip heading
        sessions = [session(*row) for row in con_csv]
    return sessions


#a script that downloads cracked games from STEAMRIP / GOG.

import requests
from bs4 import BeautifulSoup
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from webdriver_manager.chrome import ChromeDriverManager
from time import sleep
import webbrowser
from constants import *

def main():

  def search_in_gog(game_name = None, page = 1):

    game_name = game_name.replace(' ', '-').lower()

    response = requests.get(f'{gog_list}{game_name}/{page}{gog_addon}')
    soup = BeautifulSoup(response.content, 'html.parser')
    game_html_line = soup.find_all('a', {'class': 'block'})

    if len(game_html_line) > 1:

      for i, game in enumerate(game_html_line):

        title = game.text
        title = re.sub(r'\s*Last Update.*', '', title).strip()
        print(f'{i+1}. {title}')

        if (i+1) % 28 == 0:

          question = input('Do you want to continue to the next page? Answer with y / n. ')

          if question == 'y':

            print(f'question = {question}')
            page += 1
            search_in_gog(game_name, page)

          else:
            break

      question = int(input('\nYou have multiple options, please pick the one you want: \nif the game you want is not in the list type \'999\':\n')) - 1

      if question == 998:
        game_url = search_in_steamrip(game_name)

        return game_url

      elif question >= len(game_html_line):
        question = int(input('\nThe number you chose was not in the list, Please choose again: \n')) - 1

      href_value = game_html_line[question].get('href')
      game_url = f'https://gog-games.com{href_value}'

      return game_url

    elif len(game_html_line) == 0:
      game_url = search_in_steamrip(game_name)

      return game_url

    href_value = game_html_line[0].get('href')
    game_url = f'https://gog-games.com{href_value}'

    return game_url

  def search_in_steamrip(game_name = None):

    if game_name == None:
      game_name = input('Please input the game\'s name: \n')

    game_name = game_name.replace(' ', '-').lower()

    response = requests.get(gamelist1)
    soup = BeautifulSoup(response.content, 'html.parser')
    game_html_line = soup.find_all('a', href=re.compile(game_name))

    if len(game_html_line) > 1:
      i = 0

      for i, game in enumerate(game_html_line):
        title = game.text
        print(f'{i+1}. {title}')

      question = int(input('\nYou have multiple options, please pick the one you want: ')) - 1

      if question >= len(game_html_line):
          question = int(input('\nThe number you chose was not in the list, Please choose again: \n')) - 1

      href_value = game_html_line[question].get('href')
      game_url = f'https://webcache.googleusercontent.com/search?q=cache:https://steamrip.com{href_value}'

      return game_url

    elif len(game_html_line) == 0:
      print('Couldn\'t find the game you asked for, Please try again.')

      return None

    href_value = game_html_line[0].get('href')
    game_url = f'https://webcache.googleusercontent.com/search?q=cache:https://steamrip.com{href_value}'

    return game_url

  def find_and_download(game_url):

    if game_url == None:
      return None

    response = requests.get(game_url)
    soup = BeautifulSoup(response.content, 'html.parser')

    if game_url.find('steamrip.com') > 0:
      download_html_line = soup.find('a', class_="shortc-button medium purple")

      if download_html_line == None:
        index_cash = game_url.find('cache:') + 6
        actual_url = game_url[index_cash:]

        print('Failed to find the link to the download in ' + actual_url)
        return None

      url = download_html_line.get('href')[2:]
      formatted_url = f'https://{url}'
      webbrowser.open(formatted_url)

    else:
      driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
      driver.get(game_url)
      driver.find_element(By.CLASS_NAME, "g-recaptcha").click()
      wait = WebDriverWait(driver, 50)
      wait.until(ec.visibility_of_element_located((By.XPATH, '//*[@id="game-details"]/div/div[2]/div[1]/div[1]')))
      html = driver.page_source
      download_link = re.search(r'(filecrypt\.cc\/Container\/\w+)', html)

      if download_link:
        formatted_url = f'https://{download_link.group(1)}'
        driver.get(formatted_url)
        wait.until(ec.visibility_of_element_located((By.XPATH, '//*[@id="cnl_btn"]')))
        driver.find_element(By.XPATH, '//*[@id="cnl_btn"]').click()
        sleep(55)

      else:
        download_link = re.search(r'(?:title=")(https:\/\/1fichier\..*)(?:" href)', html)
        if download_link:
          formatted_url = f'https://{download_link.group(1)}'

  game_name = input('Please input the game\'s name: \n')

  find_and_download(search_in_gog(game_name))

if __name__ == '__main__':
  main()


import sys

from train.args import args

autolaunch = False
if len(sys.argv) > 1:
    autolaunch = "-autolaunch" in sys.argv
server_name = ''
if len(server_name) < 1:
    server_name = None
server_port = 9999
if server_port <= 0:
    server_port = None
server_share = False

output_folder_path = 'outputs'

app_title = "brark 语音克隆"

#block_theme = 'freddyaboulton/dracula_revamped'
block_theme = 'freddyaboulton/dracula_revamped'
initial_clone_name = "./bark/prompts/custom_prompts/custom_langeuage_en_1"

language_type_list = ["pl", "en", "zh", "ja"]

train_dataset_path = args.train_dataset

train_process_path = args.process

train_path = args.train


"""
* 이진 검색
정렬된 nums를 입력받아 이진 검색으로 target에 해당하는 인덱스를 찾아라.
Input: nums = [-1, 0, 3, 5, 9, 12], target = 9
Output: 4
"""
import bisect
from typing import List

class Solution:
    # 이진 검색 모듈
    def search(self, nums: List[int], target: int) -> int:
        index = bisect.bisect_left(nums, target)

        if index < len(nums) and nums[index] == target:
            return index
        else:
            return -1

if __name__ == '__main__':
    nums = [-1, 0, 3, 5, 9, 12]
    target = 9
    print(Solution().search(nums, target))


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
Add dependencies to dummy macosx64 tasks.
"""

from taskgraph.transforms.base import TransformSequence

transforms = TransformSequence()

@transforms.add
def add_dependencies(config, jobs):
    for job in jobs:
        dependencies = {}

        platform = job.get("attributes", {}).get("build_platform")
        if not platform:
            continue
        arm = platform.replace("macosx64", "macosx64-aarch64")
        intel = platform.replace("macosx64", "macosx64-x64")
        for dep_task in config.kind_dependencies_tasks.values():
            # Weed out unwanted tasks.
            if dep_task.attributes.get("build_platform"):
                if dep_task.attributes["build_platform"] not in (platform, arm, intel):
                    continue
            # Add matching tasks to deps
            dependencies[dep_task.label] = dep_task.label
            # Pick one task to copy run-on-projects from
            if (
                dep_task.kind == "build"
                and dep_task.attributes["build_platform"] == platform
            ):
                job["run-on-projects"] = dep_task.attributes.get("run_on_projects")

        job.setdefault("dependencies", {}).update(dependencies)
        job["if-dependencies"] = list(dependencies)

        yield job


from marshmallow import ValidationError
from marshmallow.fields import String
from pyramid.httpexceptions import HTTPNotFound
from pyramid.request import Request
from pyramid.response import Response
from sqlalchemy.exc import IntegrityError

from tildes.enums import LogEventType
from tildes.models.group import Group
from tildes.models.log import LogTopic
from tildes.models.topic import Topic, TopicBookmark, TopicIgnore, TopicVote
from tildes.schemas.group import GroupSchema
from tildes.schemas.topic import TopicSchema
from tildes.views import IC_NOOP
from tildes.views.decorators import ic_view_config, use_kwargs

@ic_view_config(
    route_name="topic",
    request_method="GET",
    request_param="ic-trigger-name=edit",
    renderer="topic_edit.jinja2",
    permission="edit",
)
def get_topic_edit(request: Request) -> dict:
    """Get the edit form for a topic with Intercooler."""
    return {"topic": request.context}

@ic_view_config(
    route_name="topic",
    request_method="GET",
    renderer="topic_contents.jinja2",
    permission="view",
)
def get_topic_contents(request: Request) -> dict:
    """Get a topic's body with Intercooler."""
    return {"topic": request.context}

@ic_view_config(
    route_name="topic",
    request_method="PATCH",
    renderer="topic_contents.jinja2",
    permission="edit",
)
@use_kwargs(TopicSchema(only=("markdown",)), location="form")
def patch_topic(request: Request, markdown: str) -> dict:
    """Update a topic with Intercooler."""
    topic = request.context

    topic.markdown = markdown

    return {"topic": topic}

@ic_view_config(route_name="topic", request_method="DELETE", permission="delete")
def delete_topic(request: Request) -> Response:
    """Delete a topic with Intercooler and redirect to its group."""
    topic = request.context
    topic.is_deleted = True

    response = Response()
    response.headers["X-IC-Redirect"] = request.route_url(
        "group", path=topic.group.path
    )

    return response

@ic_view_config(
    route_name="topic_vote",
    request_method="PUT",
    renderer="topic_voting.jinja2",
    permission="vote",
)
def put_topic_vote(request: Request) -> Response:
    """Vote on a topic with Intercooler."""
    topic = request.context

    savepoint = request.tm.savepoint()

    new_vote = TopicVote(request.user, topic)
    request.db_session.add(new_vote)

    request.db_session.add(LogTopic(LogEventType.TOPIC_VOTE, request, topic))

    try:
        # manually flush before attempting to commit, to avoid having all objects
        # detached from the session in case of an error
        request.db_session.flush()
        request.tm.commit()
    except IntegrityError:
        # the user has already voted on this topic
        savepoint.rollback()

    # re-query the topic to get complete data
    topic = (
        request.query(Topic)
        .join_all_relationships()
        .filter_by(topic_id=topic.topic_id)
        .one()
    )

    return {"topic": topic}

@ic_view_config(
    route_name="topic_vote",
    request_method="DELETE",
    renderer="topic_voting.jinja2",
    permission="vote",
)
def delete_topic_vote(request: Request) -> Response:
    """Remove the user's vote from a topic with Intercooler."""
    topic = request.context

    request.query(TopicVote).filter(
        TopicVote.topic == topic, TopicVote.user == request.user
    ).delete(synchronize_session=False)

    request.db_session.add(LogTopic(LogEventType.TOPIC_UNVOTE, request, topic))

    # manually commit the transaction so triggers will execute
    request.tm.commit()

    # re-query the topic to get complete data
    topic = (
        request.query(Topic)
        .join_all_relationships()
        .filter_by(topic_id=topic.topic_id)
        .one()
    )

    return {"topic": topic}

@ic_view_config(
    route_name="topic_tags",
    request_method="GET",
    renderer="topic_tags_edit.jinja2",
    permission="tag",
)
def get_topic_tags(request: Request) -> dict:
    """Get the tagging form for a topic with Intercooler."""
    return {"topic": request.context}

@ic_view_config(
    route_name="topic_tags",
    request_method="PUT",
    renderer="topic_tags.jinja2",
    permission="tag",
)
@use_kwargs(
    {"tags": String(missing=""), "conflict_check": String(missing="")}, location="form"
)
def put_tag_topic(request: Request, tags: str, conflict_check: str) -> dict:
    """Apply tags to a topic with Intercooler."""
    topic = request.context

    # check for edit conflict by verifying tags didn't change after they loaded the form
    if conflict_check:
        conflict_check_tags = conflict_check.split(",")
    else:
        conflict_check_tags = []

    if conflict_check_tags != topic.tags:
        raise ValidationError(
            {"tags": ["Someone else edited simultaneously, please cancel and retry"]}
        )

    if tags:
        # split the tag string on commas
        new_tags = tags.split(",")
    else:
        new_tags = []

    old_tags = topic.tags

    try:
        topic.tags = new_tags
    except ValidationError as exc:
        raise ValidationError({"tags": ["Invalid tags"]}) from exc

    # if tags weren't changed, don't add a log entry or update page
    if set(topic.tags) == set(old_tags):
        return IC_NOOP

    request.db_session.add(
        LogTopic(
            LogEventType.TOPIC_TAG,
            request,
            topic,
            info={"old": old_tags, "new": topic.tags},
        )
    )

    # show the tag field by default in the future when the tagger is posting a new topic
    if not request.user.show_tags_on_new_topic:
        request.user.show_tags_on_new_topic = True
        request.db_session.add(request.user)

    return {"topic": topic}

@ic_view_config(
    route_name="topic_group",
    request_method="GET",
    renderer="topic_group_edit.jinja2",
    permission="move",
)
def get_topic_group(request: Request) -> dict:
    """Get the form for moving a topic with Intercooler."""
    return {"topic": request.context}

@ic_view_config(
    route_name="topic",
    request_param="ic-trigger-name=topic-move",
    request_method="PATCH",
    permission="move",
)
@use_kwargs(GroupSchema(only=("path",)), location="form")
def patch_move_topic(request: Request, path: str) -> dict:
    """Move a topic to a different group with Intercooler."""
    topic = request.context

    new_group = request.query(Group).filter(Group.path == path).one_or_none()
    if not new_group:
        raise HTTPNotFound("Group not found")

    old_group = topic.group

    if new_group == old_group:
        return IC_NOOP

    topic.group = new_group

    request.db_session.add(
        LogTopic(
            LogEventType.TOPIC_MOVE,
            request,
            topic,
            info={"old": str(old_group.path), "new": str(topic.group.path)},
        )
    )

    return Response("Moved")

@ic_view_config(
    route_name="topic_remove",
    request_method="PUT",
    permission="remove",
    renderer="post_action_toggle_button.jinja2",
)
def put_topic_remove(request: Request) -> dict:
    """Remove a topic with Intercooler."""
    topic = request.context

    topic.is_removed = True
    request.db_session.add(LogTopic(LogEventType.TOPIC_REMOVE, request, topic))

    return {"name": "remove", "subject": topic, "is_toggled": True}

@ic_view_config(
    route_name="topic_remove",
    request_method="DELETE",
    permission="remove",
    renderer="post_action_toggle_button.jinja2",
)
def delete_topic_remove(request: Request) -> dict:
    """Un-remove a topic with Intercooler."""
    topic = request.context

    topic.is_removed = False
    request.db_session.add(LogTopic(LogEventType.TOPIC_UNREMOVE, request, topic))

    return {"name": "remove", "subject": topic, "is_toggled": False}

@ic_view_config(
    route_name="topic_lock",
    request_method="PUT",
    permission="lock",
    renderer="post_action_toggle_button.jinja2",
)
def put_topic_lock(request: Request) -> dict:
    """Lock a topic with Intercooler."""
    topic = request.context

    topic.is_locked = True
    request.db_session.add(LogTopic(LogEventType.TOPIC_LOCK, request, topic))

    return {"name": "lock", "subject": topic, "is_toggled": True}

@ic_view_config(
    route_name="topic_lock",
    request_method="DELETE",
    permission="lock",
    renderer="post_action_toggle_button.jinja2",
)
def delete_topic_lock(request: Request) -> dict:
    """Unlock a topic with Intercooler."""
    topic = request.context

    topic.is_locked = False
    request.db_session.add(LogTopic(LogEventType.TOPIC_UNLOCK, request, topic))

    return {"name": "lock", "subject": topic, "is_toggled": False}

@ic_view_config(
    route_name="topic_title",
    request_method="GET",
    renderer="topic_title_edit.jinja2",
    permission="edit_title",
)
def get_topic_title(request: Request) -> dict:
    """Get the form for editing a topic's title with Intercooler."""
    return {"topic": request.context}

@ic_view_config(
    route_name="topic",
    request_param="ic-trigger-name=topic-title-edit",
    request_method="PATCH",
    permission="edit_title",
)
@use_kwargs(TopicSchema(only=("title",)), location="form")
def patch_topic_title(request: Request, title: str) -> dict:
    """Edit a topic's title with Intercooler."""
    topic = request.context

    if title == topic.title:
        return IC_NOOP

    request.db_session.add(
        LogTopic(
            LogEventType.TOPIC_TITLE_EDIT,
            request,
            topic,
            info={"old": topic.title, "new": title},
        )
    )

    topic.title = title

    return Response(topic.title)

@ic_view_config(
    route_name="topic_link",
    request_method="GET",
    renderer="topic_link_edit.jinja2",
    permission="edit_link",
)
def get_topic_link(request: Request) -> dict:
    """Get the form for editing a topic's link with Intercooler."""
    return {"topic": request.context}

@ic_view_config(
    route_name="topic",
    request_param="ic-trigger-name=topic-link-edit",
    request_method="PATCH",
    permission="edit_link",
)
@use_kwargs(TopicSchema(only=("link",)), location="form")
def patch_topic_link(request: Request, link: str) -> dict:
    """Edit a topic's link with Intercooler."""
    topic = request.context

    if link == topic.link:
        return IC_NOOP

    request.db_session.add(
        LogTopic(
            LogEventType.TOPIC_LINK_EDIT,
            request,
            topic,
            info={"old": topic.link, "new": link},
        )
    )

    topic.link = link
    topic.content_metadata = None

    return Response(f'{topic.link}')

@ic_view_config(
    route_name="topic_bookmark",
    request_method="PUT",
    permission="bookmark",
    renderer="post_action_toggle_button.jinja2",
)
def put_topic_bookmark(request: Request) -> dict:
    """Bookmark a topic with Intercooler."""
    topic = request.context

    savepoint = request.tm.savepoint()

    bookmark = TopicBookmark(request.user, topic)
    request.db_session.add(bookmark)

    try:
        # manually flush before attempting to commit, to avoid having all
        # objects detached from the session in case of an error
        request.db_session.flush()
        request.tm.commit()
    except IntegrityError:
        # the user has already bookmarked this topic
        savepoint.rollback()

    return {"name": "bookmark", "subject": topic, "is_toggled": True}

@ic_view_config(
    route_name="topic_bookmark",
    request_method="DELETE",
    permission="bookmark",
    renderer="post_action_toggle_button.jinja2",
)
def delete_topic_bookmark(request: Request) -> dict:
    """Unbookmark a topic with Intercooler."""
    topic = request.context

    request.query(TopicBookmark).filter(
        TopicBookmark.user == request.user, TopicBookmark.topic == topic
    ).delete(synchronize_session=False)

    return {"name": "bookmark", "subject": topic, "is_toggled": False}

@ic_view_config(
    route_name="topic_ignore",
    request_method="PUT",
    permission="ignore",
    renderer="post_action_toggle_button.jinja2",
)
def put_topic_ignore(request: Request) -> dict:
    """Ignore a topic with Intercooler."""
    topic = request.context

    savepoint = request.tm.savepoint()

    ignore = TopicIgnore(request.user, topic)
    request.db_session.add(ignore)

    try:
        # manually flush before attempting to commit, to avoid having all
        # objects detached from the session in case of an error
        request.db_session.flush()
        request.tm.commit()
    except IntegrityError:
        # the user has already ignored this topic
        savepoint.rollback()

    return {"name": "ignore", "subject": topic, "is_toggled": True}

@ic_view_config(
    route_name="topic_ignore",
    request_method="DELETE",
    permission="ignore",
    renderer="post_action_toggle_button.jinja2",
)
def delete_topic_ignore(request: Request) -> dict:
    """Unignore a topic with Intercooler."""
    topic = request.context

    request.query(TopicIgnore).filter(
        TopicIgnore.user == request.user, TopicIgnore.topic == topic
    ).delete(synchronize_session=False)

    return {"name": "ignore", "subject": topic, "is_toggled": False}

@ic_view_config(
    route_name="topic",
    request_method="GET",
    request_param="ic-trigger-name=markdown-source",
    renderer="markdown_source.jinja2",
    permission="view_content",
)
def get_topic_markdown_source(request: Request) -> dict:
    """Get the Markdown source for a topic with Intercooler."""
    return {"post": request.context}


"""
制作目标数据集
"""
import os
import cv2
import random
import numpy as np
import shutil
import math

def gen_box(s, r):
    """
    在的图像上随机生成一个 大小为s, 纵横比为r的框
    :param s:
    :param r:
    :return:
    """
    # 随机获取一个中心坐标
    center_x = round(random.uniform(0.2, 0.8), 2)
    center_y = round(random.uniform(0.2, 0.8), 2)
    w = np.sqrt(s/r)
    h = np.sqrt(s*r)
    # 左上角和右下角的坐标分别是
    x1, y1 = max(0, center_x - w/2), max(0, center_y - h/2)
    x2, y2 = min(1, center_x + w/2), min(1, center_y + h/2)
    return x1, y1, x2, y2

def intersection(box1, box2):
    """
    计算box1, box2 的交集
    :param box1:
    :param box2:
    :return:
    """
    # 交集
    inter_x1 = max(box1[0], box2[0])
    inter_y1 = max(box1[1], box2[1])
    inter_x2 = min(box1[2], box2[2])
    inter_y2 = min(box1[3], box2[3])

    # 交集
    inter_area = max(inter_y2 - inter_y1, 0) * max(inter_x2 - inter_x1, 0)
    return inter_area

def iou(box1, box2):
    """
    计算box1 和 box2 的iou
    :param box1:
    :param box2:
    :return:
    """
    inter_area = intersection(box1, box2)
    box1_area = (box1[2] - box1[0]) * (box1[3] - box1[1])
    box2_area = (box2[2] - box2[0]) * (box2[3] - box2[1])
    # 并集
    union_area = box2_area + box1_area - inter_area

    return inter_area / union_area

def select_target_imgs(s_list, r_list, n, threshold=0.8):
    """
    从图像上随机选取指定数量的符合要求的目标框
    :param s_list:  可供选择的 s的列表
    :param r_list:  可供选择的r的列表
    :param n:       要选取的目标框数量
    :param threshold:生成的目标框和之前的目标框的阀值不能大于threshold
    :return: n 个目标框
    """
    box = {}
    while len(box) != n:
        s = random.uniform(s_list[0], s_list[1])
        r = random.uniform(r_list[0], r_list[1])
        gen_target = gen_box(s, r)
        # 对于太小的, 要重新生成
        if (gen_target[2] - gen_target[0]) < 0.05 or \
            (gen_target[3] - gen_target[1]) < 0.05:
            continue

        # 对于生成的框, 和已有的目标框太相似, 也要去除
        is_in = False
        for k, target in box.items():
            # 获取交并比
            iou_val = iou(gen_target, target)
            if iou_val > threshold:
                is_in = True
                break
        if is_in:
            continue
        # 存入box
        box[len(box)+1] = gen_target
    return box

def gen_anno(img_base_path, origin_num, anno_base_path='../annot', target_s=(0.1, 0.3), target_r=(0.5, 2), per_target_num=6, split_rate=(0.8, 0.8)):
    """
    生成标注文本, 并且分割成训练集,验证集, 测试集
    :param img_base_path:   图片文件夹
    :param origin_num:      获取原始图片数量
    :param target_s:        生成的目标框大小
    :param target_r:        生成的目标框纵横比
    :param per_target_num:  每张原始图片生成目标框数量
    :return:
    """
    # 选取指定数量的原始图片
    origin_path = os.path.join(img_base_path, 'origin')
    target_path = os.path.join(img_base_path, 'target')
    train_anno_name = os.path.join(anno_base_path, 'train.txt')
    val_anno_name = os.path.join(anno_base_path, 'val.txt')
    test_anno_name = os.path.join(anno_base_path, 'test.txt')
    # 删除目标图像
    if os.path.exists(target_path):
        shutil.rmtree(target_path)
    os.mkdir(target_path)
    # 删除标注文件夹
    if os.path.exists(anno_base_path):
        shutil.rmtree(anno_base_path)
    os.mkdir(anno_base_path)

    all_origins = os.listdir(origin_path)
    select_origins = all_origins[:origin_num]

    data = []
    for img_suffix in select_origins:
        img_name = img_suffix.split('.')[0].strip()
        img_path = os.path.join(origin_path, img_suffix)
        img = cv2.imread(img_path)
        h, w = img.shape[:2]
        # 随机选择指定个目标框
        target_points = select_target_imgs(target_s, target_r, per_target_num)

        for ind, point in target_points.items():
            anno = []
            x1, y1, x2, y2 = (point * np.array([w, h, w, h])).astype(int)
            target = img[y1: y2, x1: x2]
            # cv2.imshow('10', img)
            # cv2.waitKey(0)
            # cv2.imshow('11', target)
            # cv2.waitKey(0)
            # random_trans = random.uniform(0.7, 1.3)
            # print(random_trans)
            # target = cv2.resize(target, None, fx=random_trans, fy=random_trans)
            # cv2.imshow('12', target)
            # cv2.waitKey(0)
            # cv2.destroyAllWindows()
            target_name = os.path.join(target_path, '{}_{}.jpg'.format(img_name, ind))
            cv2.imwrite(target_name, target)
            anno.append(target_name)
            anno.append(img_path)
            anno.append(",".join(['{:.2f}'.format(item) for item in point]))
            # 保存一个样本
            data.append(','.join(anno))

    total_num = len(data)
    train_val_ind = math.floor(split_rate[0] * total_num)
    train_ind = math.floor(split_rate[1] * train_val_ind)
    train_data = data[:train_ind]
    val_data = data[train_ind: train_val_ind]
    test_data = data[train_val_ind:]

    # 将所有的样本保存到文件中
    with open(train_anno_name, 'w') as f:
        f.write('\n'.join(train_data))
    with open(val_anno_name, 'w') as f:
        f.write('\n'.join(val_data))
    with open(test_anno_name, 'w') as f:
        f.write('\n'.join(test_data))

if __name__ == '__main__':
    gen_anno('../imgs', 20)
    print('over')


from activity import Activity, StabMixIn
from time import sleep
from logging import debug as log_debug, info as log_info, warning as log_warn, error as log_err

class TakeoffActivity(Activity, StabMixIn):

   def __init__(self, fsm, autoap):
      Activity.__init__(self, autoap)
      self.canceled = False
      self.fsm = fsm

   def _cancel(self):
      self.canceled = True

   def run(self):
      ap = self.autopilot.api
      api = self.autopilot.api
      arg = self.autopilot.arg
      if arg:
         vp_max = 4.0
         vp_target = min(vp_max, arg)
      else:
         vp_target = 1.0

      # start motors and wait for
      api.mot_en(True)
      while ap.motors_state.recv() != 2:
         if self.canceled:
            api.mot_en(False)
            return

      # "point of no return":
      ap.home_pos = [ap.pse.data[4], ap.pse.data[6]]
      api.set_hp(ap.home_pos)
      api.set_ys(0.0)

      # increase altitude setpoint:
      vp = -1.0
      while vp < vp_target:
         api.set_vp(vp)
         vp += 0.1
         sleep(0.05)
      api.set_vp(vp_target)
      #self.stabilize()
      self.fsm.handle('done')