######
#
# This script plots Fig S6
# (distribution of appearance times of different variant types)
#
#####

import sys
import numpy
import parse_file
from scipy.special import gammaln as loggamma
from math import log, exp

import matplotlib as mpl
import matplotlib.colors as colors
import matplotlib.cm as cmx
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import matplotlib.patheffects as pe
from mpl_toolkits.axes_grid.inset_locator import inset_axes

from numpy.random import shuffle

import figure_utils
import timecourse_utils
import stats_utils

mpl.rcParams['font.size'] = 6
mpl.rcParams['lines.linewidth'] = 1.0
mpl.rcParams['legend.frameon']  = False
mpl.rcParams['legend.fontsize']  = 'small'

####
#
# Set up figures
#
####

fig = plt.figure(figsize=(6.2, 1.7))

grid = gridspec.GridSpec(1, 2, width_ratios=[1,1], wspace=0.1)

time_axis = plt.Subplot(fig, grid[0])
fig.add_subplot(time_axis)

time_axis.spines['top'].set_visible(False)
time_axis.spines['right'].set_visible(False)
time_axis.get_xaxis().tick_bottom()
time_axis.get_yaxis().tick_left()

time_axis.set_ylabel('Fraction mutations $\geq t$')
time_axis.set_xlabel('Appearance time, $t$')
time_axis.set_xticks(figure_utils.time_xticks)
time_axis.set_xticklabels(figure_utils.time_xticklabels)
time_axis.set_xlim([0,60000])

missense_time_axis = plt.Subplot(fig, grid[1])
fig.add_subplot(missense_time_axis)

missense_time_axis.spines['top'].set_visible(False)
missense_time_axis.spines['right'].set_visible(False)
missense_time_axis.get_xaxis().tick_bottom()
missense_time_axis.get_yaxis().tick_left()

missense_time_axis.set_xlabel('Appearance time, $t$')
missense_time_axis.set_xticks(figure_utils.time_xticks)
missense_time_axis.set_xticklabels(figure_utils.time_xticklabels)
missense_time_axis.set_xlim([0,60000])
missense_time_axis.set_yticklabels([])

####
#
# Do calculation
#
####

excluded_types = set(['sv'])

# map of variant types
appearance_times = {}

pooled_appearance_times = []
pooled_var_types = []
restricted_appearance_times = []
restricted_var_types = []

populations = parse_file.complete_nonmutator_lines

for population in populations:
    sys.stderr.write("Processing %s...\t" % parse_file.get_pretty_name(population))

    # calculate mutation trajectories
    # load mutations
    mutations, depth_tuple = parse_file.parse_annotated_timecourse(population)

    population_avg_depth_times, population_avg_depths, clone_avg_depth_times, clone_avg_depths = depth_tuple

    dummy_times,fmajors,fminors,haplotype_trajectories = parse_file.parse_haplotype_timecourse(population)
    state_times, state_trajectories = parse_file.parse_well_mixed_state_timecourse(population)

    num_processed_mutations = 0

    for mutation_idx in xrange(0,len(mutations)):

        num_processed_mutations+=1

        position, gene_name, allele, var_type, test_statistic, pvalue, cutoff_idx, depth_fold_change, depth_change_pvalue, times, alts, depths, clone_times, clone_alts, clone_depths = mutations[mutation_idx]
        Ls = haplotype_trajectories[mutation_idx]
        state_Ls = state_trajectories[mutation_idx]

        good_idxs, filtered_alts, filtered_depths = timecourse_utils.mask_timepoints(times, alts, depths, var_type, cutoff_idx, depth_fold_change, depth_change_pvalue)

        freqs = timecourse_utils.estimate_frequencies(filtered_alts, filtered_depths)

        masked_times = times[good_idxs]
        masked_freqs = freqs[good_idxs]
        masked_state_Ls = state_Ls[good_idxs]
        masked_Ls = Ls[good_idxs]

        t = timecourse_utils.calculate_appearance_time(masked_times, masked_freqs, masked_state_Ls, masked_Ls)

        pooled_appearance_times.append(t)
        pooled_var_types.append(var_type)

        if var_type not in excluded_types:
            restricted_appearance_times.append(t)
            restricted_var_types.append(var_type)

    sys.stderr.write("added %d mutations\n" % num_processed_mutations)

# sort the lists (but preserve association between time and variant type
pooled_appearance_times, pooled_var_types = (list(x) for x in zip(*sorted(zip(pooled_appearance_times, pooled_var_types), key=lambda pair: pair[0])))
restricted_appearance_times, restricted_var_types = (list(x) for x in zip(*sorted(zip(restricted_appearance_times, restricted_var_types), key=lambda pair: pair[0])))

pooled_appearance_times = numpy.array(pooled_appearance_times)
restricted_appearance_times = numpy.array(restricted_appearance_times)

# calculate appearance time distribution for each variant type
observed_appearance_times = {}
observed_restricted_appearance_times = {}

for t,var_type in zip(pooled_appearance_times, pooled_var_types):
    if var_type not in observed_appearance_times:
        observed_appearance_times[var_type] = []
    observed_appearance_times[var_type].append(t)

for var_type in observed_appearance_times.keys():
    observed_appearance_times[var_type] = numpy.array(observed_appearance_times[var_type])
    observed_appearance_times[var_type].sort()

for t,var_type in zip(restricted_appearance_times, restricted_var_types):
    if var_type not in observed_restricted_appearance_times:
        observed_restricted_appearance_times[var_type] = []
    observed_restricted_appearance_times[var_type].append(t)

for var_type in observed_restricted_appearance_times.keys():
    observed_restricted_appearance_times[var_type] = numpy.array(observed_restricted_appearance_times[var_type])
    observed_restricted_appearance_times[var_type].sort()

####
#
# Now do bootstrap resampling to gauge significance
#
####

num_bootstraps = 10000
bootstrapped_kss = {var_type:[] for var_type in observed_appearance_times.keys()}
bootstrapped_restricted_kss = {var_type:[] for var_type in observed_restricted_appearance_times.keys()}

sys.stderr.write('Resampling %d bootstraps...\n' % num_bootstraps)
for bootstrap_idx in xrange(0,num_bootstraps):

    # permute var type labels
    shuffle(pooled_var_types)
    shuffle(restricted_var_types)

    # recalculate distributions for each type
    bootstrapped_appearance_times = {}
    bootstrapped_restricted_appearance_times = {}

    for t,var_type in zip(pooled_appearance_times, pooled_var_types):
        if var_type not in bootstrapped_appearance_times:
            bootstrapped_appearance_times[var_type] = []
        bootstrapped_appearance_times[var_type].append(t)

    for var_type in bootstrapped_appearance_times.keys():
        bootstrapped_appearance_times[var_type].sort()

    for t,var_type in zip(restricted_appearance_times, restricted_var_types):
        if var_type not in bootstrapped_restricted_appearance_times:
            bootstrapped_restricted_appearance_times[var_type] = []
        bootstrapped_restricted_appearance_times[var_type].append(t)

    for var_type in bootstrapped_restricted_appearance_times.keys():
        bootstrapped_restricted_appearance_times[var_type].sort()

    # recalculate ks distances
    for var_type in bootstrapped_appearance_times.keys():
        D = stats_utils.calculate_ks_distance(bootstrapped_appearance_times[var_type], pooled_appearance_times)
        bootstrapped_kss[var_type].append(D)

    for var_type in bootstrapped_restricted_appearance_times.keys():
        D = stats_utils.calculate_ks_distance(bootstrapped_restricted_appearance_times[var_type], restricted_appearance_times)
        bootstrapped_restricted_kss[var_type].append(D)

# calculate pvalues
sys.stdout.write('Pvalues for temporal nonuniformity (n=%d bootstraps):\n' % num_bootstraps)
for var_type in observed_appearance_times.keys():

    bootstrapped_appearance_times[var_type] = numpy.array(bootstrapped_appearance_times[var_type])

    D = stats_utils.calculate_ks_distance(observed_appearance_times[var_type], pooled_appearance_times)

    pvalue = ((bootstrapped_kss[var_type]>=D).sum()+1.0)/(len(bootstrapped_kss[var_type])+1.0)

    sys.stdout.write('%s: %g\n' % (var_type, pvalue))

sys.stdout.write('Excluding svs:\n')
for var_type in observed_restricted_appearance_times.keys():

    bootstrapped_restricted_appearance_times[var_type] = numpy.array(bootstrapped_restricted_appearance_times[var_type])

    D = stats_utils.calculate_ks_distance(observed_restricted_appearance_times[var_type], restricted_appearance_times)

    pvalue = ((bootstrapped_restricted_kss[var_type]>=D).sum()+1.0)/(len(bootstrapped_restricted_kss[var_type])+1.0)

    sys.stdout.write('%s: %g\n' % (var_type, pvalue))

######
#
# Now do plotting
#
######

all_ts, all_survivals = stats_utils.calculate_unnormalized_survival_from_vector(pooled_appearance_times, min_x=-1000,max_x=100000)

time_axis.step(all_ts, all_survivals/all_survivals[0], color='k', label='All')
missense_time_axis.step(all_ts, all_survivals/all_survivals[0], color='k', label='All')

restricted_ts, restricted_survivals = stats_utils.calculate_unnormalized_survival_from_vector(restricted_appearance_times, min_x=-1000,max_x=100000)
missense_time_axis.step(all_ts, restricted_survivals/restricted_survivals[0], color='k', label='All (excluding sv)',alpha=0.5)

for var_type in parse_file.var_types:

    color = figure_utils.get_var_type_color(var_type)
    vartype_ts, vartype_survivals = stats_utils.calculate_unnormalized_survival_from_vector(observed_appearance_times[var_type], min_x=-1000, max_x=100000)
    time_axis.step(vartype_ts, vartype_survivals/vartype_survivals[0], color=color, alpha=0.7, label=var_type)

    if var_type == 'missense':
        missense_time_axis.step(vartype_ts, vartype_survivals/vartype_survivals[0], color=color, alpha=0.7, label=var_type)

time_axis.legend(loc='upper right', frameon=False)
missense_time_axis.legend(loc='upper right', frameon=False)

sys.stderr.write("Saving figure...\t")
fig.savefig(parse_file.figure_directory+'extended_data_fig2.pdf',bbox_inches='tight')
sys.stderr.write("Done!\n")


from Bio import SeqIO
import sys

def divide_fasta_into_ref_and_query(ref_query, ref):

    with    open(ref,'r')                as ihandle       :
        refseq_itr         = SeqIO.parse(ihandle, "fasta")
        refseq_name_set    = set()
        for record in refseq_itr:
            refseq_name_set.add(record.name)

    with    open(ref_query,'r')          as ihandle       ,\
            open(ref_query+".ref",'w')   as ohandle_ref   ,\
            open(ref_query+".query",'w') as ohandle_query :
        ref_query_itr      = SeqIO.parse(ihandle,"fasta")
        ref_query_name_set = {}
        for record in ref_query_itr:
            if(record.name in refseq_name_set):
                SeqIO.write(
                    record        ,
                    ohandle_ref   ,
                    "fasta"
                    )
            else:
                SeqIO.write(
                    record        ,
                    ohandle_query ,
                    "fasta"
                    )

if __name__ == "__main__":
    #main function
    argvs=sys.argv
    divide_fasta_into_ref_and_query(argvs[1],argvs[2])


# Joshua Burbidge
# a snake game made with Pygame

import pygame
import pygame.freetype
from collections import deque
from math import floor
from random import randrange

'''
TODO:
add margin to top and adjust
reset message
BUG: snake collides with previous location of tail tile
'''

TS = 20
MARGIN = 4
GRIDSIZE = TS + MARGIN
TOP_BANNER = 50
HEIGHT = 360 + TOP_BANNER
WIDTH = 360
GRIDHEIGHT = floor((HEIGHT - TOP_BANNER) / (TS + MARGIN))
GRIDWIDTH = floor(WIDTH / (TS + MARGIN))
INIT_LEN = 5
FPS = 3

WHITE = (255,255,255)
BLACK = (0, 0, 0)

class Tile():
    def __init__(self, xLoc, yLoc):
        self.x = xLoc
        self.y = yLoc

def initialize():
    global screen, blueTile, redTile, greenTile, font, goal, score, tileQ
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    pygame.display.set_caption("game")
    blueTile = pygame.transform.scale(pygame.image.load("images/blue-tile.png"), (20,20))
    redTile = pygame.transform.scale(pygame.image.load("images/red-tile.png"), (20,20))
    greenTile = pygame.transform.scale(pygame.image.load("images/green-tile.png"), (20,20))
    pygame.freetype.init()
    font = pygame.freetype.SysFont(pygame.freetype.get_default_font(), 30)
    score = 0
    tileQ = deque()
    goal = Tile(-1,-1)
    init_tiles()

# initialize tile queue
def init_tiles():
    for i in range(INIT_LEN):
        tileQ.append(Tile(INIT_LEN-i, 8))
    new_goal()

def reset_game():
    tileQ.clear()
    init_tiles()
    global score
    score = 0

# create new goal tile, can't be same location as the old goal tile
# or a location occupied by the snake
def new_goal():
    global goal, goal
    newX = randrange(GRIDWIDTH)
    newY = randrange(GRIDHEIGHT)
    while (newX == goal.x and newY == goal.y) or isInSnake(newX, newY):
        newX = randrange(GRIDWIDTH)
        newY = randrange(GRIDHEIGHT)
    goal = Tile(newX, newY)

def isInSnake(xLoc, yLoc):
    for t in tileQ:
        if xLoc == t.x and yLoc == t.y:
            return True
    return False

# check if a move is valid in a direction
def canMove(dx, dy):
    headX = tileQ[0].x
    headY = tileQ[0].y
    nextX = headX + dx
    nextY = headY + dy
    outOfBounds = nextX < 0 or nextX >= GRIDWIDTH or nextY < 0 or nextY >= GRIDHEIGHT
    selfCollide = isInSnake(nextX, nextY)
    return not outOfBounds and not selfCollide

# moves the snake by one position in a given direction
def move_snake(dx, dy):
    if dx != 0 or dy != 0:
        headX = tileQ[0].x # repeated code
        headY = tileQ[0].y
        nextX = headX + dx
        nextY = headY + dy
        tileQ.appendleft(Tile(nextX, nextY))
        if goal.x != nextX or goal.y != nextY:
            tileQ.pop()
        else:
            global score
            score += 1
            new_goal()

def draw_window():
    screen.fill(BLACK)
    # create the grid drawing by drawing white squares
    x, y = 0, TOP_BANNER
    while y < HEIGHT - TS:
        while x < WIDTH - TS:
            pygame.draw.rect(screen, WHITE, pygame.Rect(x,y,TS,TS))
            x += TS + MARGIN
        x = 0
        y += TS + MARGIN

    screen.blit(greenTile, (goal.x*GRIDSIZE, TOP_BANNER+goal.y*GRIDSIZE))

    for t in tileQ:
        screen.blit(blueTile, (t.x * GRIDSIZE, TOP_BANNER+ t.y*GRIDSIZE))
    screen.blit(redTile, (tileQ[0].x * GRIDSIZE, TOP_BANNER+ tileQ[0].y*GRIDSIZE))

    font.render_to(screen, (10, 10), f'score: {score}' , WHITE)

    pygame.display.update()

def main():
    initialize()
    clock = pygame.time.Clock()

    dx = 1
    dy = 0

    run = True
    while run:
        clock.tick(FPS)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            # set direction of snake (can't do 180 degree turn)
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    run = False
                elif event.key == pygame.K_LEFT and dx == 0:
                    dx = -1
                    dy = 0
                    #break # break prevents 2 direction changes in same frame
                elif event.key == pygame.K_RIGHT and dx == 0:
                    dx = 1
                    dy = 0
                    #break
                elif event.key == pygame.K_UP and dy == 0:
                    dy = -1
                    dx = 0
                    #break
                elif event.key == pygame.K_DOWN and dy == 0:
                    dy = 1
                    dx = 0
                    #break
        if canMove(dx, dy):
            move_snake(dx, dy)
        else: # give message
            #run = False # quit back to menu
            reset_game()
            dx = 1
            dy = 0 # change
        draw_window()

    pygame.quit()

if __name__ == "__main__":
    main()


class kelas:
    def __init__(self, x, y, z, pil):
        if(x == 1):
            print("-" * 40)
            print("Anda memilih jaket", y[pil-1], "dengan harga Rp.", z[pil-1])
            print("-" * 40)
        else:
            return 0

    def hasil(self, y, a, b, c, pil1, pil):
        if(y == 2):
            print("-" * 40)
            print("Anda memilih jaket", a[pil-1], ", ukuran", b[pil1-1], "dengan harga Rp.", c[pil-1])
            print("-" * 40)
        else:
            return 0


#!/usr/bin/python -u
import libxml2
import libxml2mod
import sys

def error(msg, data):
    pass

# Memory debug specific
libxml2.debugMemory(1)

dtd="""<!ELEMENT foo EMPTY>"""
instance="""<?xml version="1.0"?>
<foo></foo>"""

dtd = libxml2.parseDTD(None, 'test.dtd')
ctxt = libxml2.newValidCtxt()
libxml2mod.xmlSetValidErrors(ctxt._o, error, error)
doc = libxml2.parseDoc(instance)
ret = doc.validateDtd(ctxt, dtd)
if ret != 1:
    print("error doing DTD validation")
    sys.exit(1)

doc.freeDoc()
dtd.freeDtd()
del dtd
del ctxt

# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
    print("OK")
else:
    print("Memory leak %d bytes" % (libxml2.debugMemory(1)))
    libxml2.dumpMemory()


'''
请考虑一颗二叉树上所有的叶子，这些叶子的值按从左到右的顺序排列形成一个 叶值序列 。

举个例子，如上图所示，给定一颗叶值序列为 (6, 7, 4, 9, 8) 的树。

如果有两颗二叉树的叶值序列是相同，那么我们就认为它们是 叶相似 的。

如果给定的两个头结点分别为 root1 和 root2 的树是叶相似的，则返回 true；否则返回 false 。

提示：

给定的两颗树可能会有 1 到 100 个结点。

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/leaf-similar-trees
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
'''

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def leafSimilar(self, root1: TreeNode, root2: TreeNode) -> bool:
        def dfs(node):
            if node:
                if not node.left and not node.right:
                    yield node.val
                yield from dfs(node.left)
                yield from dfs(node.right)
        return list(dfs(root1))==list(dfs(root2))

class Solution:
    def leafSimilar(self, root1: TreeNode, root2: TreeNode) -> bool:
        nums1 = []
        nums2 = []
        def find_leaf(root, nums):
            if root and not root.left and not root.right:
                nums.append(root.val)
            if root.left:
                find_leaf(root.left, nums)
            if root.right:
                find_leaf(root.right, nums)
            return nums
        return find_leaf(root1, nums1) == find_leaf(root2, nums2)


import serial
import time
import csv
import os

string_conn = '/dev/ttyUSB0'
arrSize = 13
dataRecorder = [0]*arrSize
fields = ['Lat', 'Lon', 'Alt', 'Speed', 'Yaw', 'Pitch', 'Roll', 'ax', 'ay', 'az', 'gx', 'gy', 'gz']

try:
	arduino = serial.Serial(string_conn, 115200, timeout = 1)
except:
	print('Please check your port!')

time.sleep(2)

def settingUp(notif):
	msgs = notif.decode('utf-8')
	msgs.split()
	print(msgs)
	if "chars" in msgs:
		userInput = input("Press any key")
		arduino.write(userInput.encode())
		return settingUp(arduino.readline())
	if "interrupt" in msgs:
		return 0
	else:
		return settingUp(arduino.readline())

def getVal():
	data = arduino.readline().decode('utf-8')
	splitLine = data.split(' ')
	if "invalid!" in splitLine:
		return getVal()
	else:
		return splitLine

with open('dataSample_fullParam', 'w') as f:
	write = csv.writer(f)
	write.writerow(fields)

readyStatus = settingUp(arduino.readline())
time.sleep(5)

while 1:
	if readyStatus == 0:
		try:
			rawData = getVal()
			for i in range(0, arrSize):
				dataRecorder[i] = rawData[i]
				print(dataRecorder[i])
			print('\n')
			with open('dataSample_fullParam','a+', newline='') as f:
				write = csv.writer(f)
				write.writerow(dataRecorder)
		except:
			print("Keyboard interupt")
			break
	else:
		print("System not ready, terminating!")
		break


import pandas as pd
import datetime
import locale

# Função para criar colunas de datas
def create_date_columns(df):
    # Extrai as informações de ano, mês e dia
    df['Ano'] = df['Data'].dt.year
    df['Mês'] = df['Data'].dt.month
    df['Dia'] = df['Data'].dt.day

    # Adiciona outras colunas úteis para análises de tempo
    df['DiaSemana'] = df['Data'].dt.dayofweek
    df['DiaSemanaNome'] = df['Data'].dt.strftime('%A').str.capitalize()
    df['DiaSemanaAbrev'] = df['Data'].dt.strftime('%a').str.capitalize()
    df['MêsNome'] = df['Data'].dt.strftime('%B').str.capitalize()
    df['Trimestre'] = df['Data'].dt.quarter
    df['Semestre'] = (df['Trimestre'] + 1) // 2
    df['AnoMês'] = df['Data'].dt.strftime('%Y-%m')
    df['AnoSemana'] = df['Data'].dt.strftime('%Y-%U')
    df['TrimestreAno'] = df.apply(lambda row: f"Q{row['Trimestre']}-{row['Ano']}", axis=1)
    df['SemestreAno'] = df.apply(lambda row: f"S{row['Semestre']}-{row['Ano']}", axis=1)
    df['DiaMesAno'] = df['Data'].dt.strftime('%d-%m-%Y')
    df['TrimestreMesAno'] = df.apply(lambda row: f"Q{row['Trimestre']}-{row['Data'].strftime('%b-%Y')}", axis=1)
    df['SemestreMesAno'] = df.apply(lambda row: f"S{row['Semestre']}-{row['Data'].strftime('%b-%Y')}", axis=1)
    df['AnoMesDia'] = df['Data'].dt.strftime('%Y-%m-%d')
    df['TrimestreAnoMesDia'] = df.apply(lambda row: f"Q{row['Trimestre']}-{row['Data'].strftime('%Y-%m-%d')}", axis=1)
    df['SemestreAnoMesDia'] = df.apply(lambda row: f"S{row['Semestre']}-{row['Data'].strftime('%Y-%m-%d')}", axis=1)
    df['AnoMesDiaSemana'] = df.apply(lambda row: f"{row['Data'].strftime('%Y-%m-%d')}-{row['DiaSemanaAbrev']}", axis=1)
    df['TrimestreAnoMesDiaSemana'] = df.apply(lambda row: f"Q{row['Trimestre']}-{row['Data'].strftime('%Y-%m-%d')}-{row['DiaSemanaAbrev']}", axis=1)
    df['SemestreAnoMesDiaSemana'] = df.apply(lambda row: f"S{row['Semestre']}-{row['Data'].strftime('%Y-%m-%d')}-{row['DiaSemanaAbrev']}", axis=1)
    df['SemanaNome'] = df['Data'].dt.isocalendar().week.map(lambda x: f'{x}º Sem')
    df['TrimestreNome'] = df['Trimestre'].map(lambda x: f'{x}º Trim')

# Função principal
def main():
    # Define a localidade para o Brasil
    locale.setlocale(locale.LC_ALL, 'pt_BR.utf8')

    # Cria uma lista de datas começando a partir de 01/01/2000 até 31/12/2030
    data_inicio = datetime.date(2020, 3, 29)
    data_fim = datetime.date(2021, 11, 22)
    dias = pd.date_range(data_inicio, data_fim, freq='D')

    # Cria um dataframe vazio
    dCalendario = pd.DataFrame()

    # Adiciona as colunas de data ao dataframe
    dCalendario['Data'] = dias

    # Cria colunas de datas
    create_date_columns(dCalendario)

    # Exibe o dataframe
    print(dCalendario.head())

    path = r'C:\Users\elder\OneDrive\Documentos\Entrevista Builder\Banco\dados\modelo\d_Calendario.csv'
    dCalendario.to_csv(path, index=False)

# Execute a função principal
if __name__ == "__main__":
    main()


from sys import version_info

if version_info[0:2] < (2, 6):
    def bin(value):
        bitstring = []

        if value > 0:
            prefix = '0b'
        elif value < 0:
            prefix = '-0b'
            value = abs(value)
        else:
            prefix = '0b0'

        while value:
            if value & 1 == 1:
                bitstring.append('1')
            else:
                bitstring.append('0')

            value >>= 1

        bitstring.reverse()

        return prefix + ''.join(bitstring)
else:
    bin = bin


import pytest
import responses

from dhis2 import exceptions, Api
from .common import BASEURL, API_URL

@pytest.fixture  # BASE FIXTURE
def api():
    return Api(BASEURL, "admin", "district")

@pytest.mark.parametrize(
    "payload,threshold,expected",
    [
        (
            {"dataElements": [1, 2, 3, 4, 5, 6, 7, 8]},
            3,
            [
                {"dataElements": [1, 2, 3]},
                {"dataElements": [4, 5, 6]},
                {"dataElements": [7, 8]},
            ],
        ),
        (
            {"dataElements": [1, 2, 3, 4, 5, 6, 7, 8]},
            9,
            [{"dataElements": [1, 2, 3, 4, 5, 6, 7, 8]}],
        ),
    ],
)
@responses.activate
def test_post_partitioned(api, payload, threshold, expected):
    endpoint = "metadata"
    url = "{}/{}".format(API_URL, endpoint)
    for p in expected:
        responses.add(responses.POST, url, json=p, status=200)

    for index, p in enumerate(
        api.post_partitioned(endpoint=endpoint, json=payload, thresh=threshold)
    ):
        assert p.status_code == 200

    assert len(responses.calls) == len(expected)

@pytest.mark.parametrize(
    "payload_invalid",
    [
        {"dataElements": [1, 2, 3, 4, 5, 6, 7, 8], "organisationUnits": []},
        {"dataElements": []},
        ["dataElements", {}],
        None,
        3,
        dict(),  # stopIteration check, should raise because empty
    ],
)
def test_post_partitioned_invalid(api, payload_invalid):
    with pytest.raises(exceptions.ClientException):
        for _ in api.post_partitioned(endpoint="metadata", json=payload_invalid):
            continue

@pytest.mark.parametrize("threshold", [0, 1, 1.5, None, [], [3]])
def test_post_partitioned_threshold_invalid(api, threshold):
    payload = {"dataElements": [1, 2, 3]}
    with pytest.raises(exceptions.ClientException):
        for _ in api.post_partitioned(
            endpoint="metadata", json=payload, thresh=threshold
        ):
            continue


import uuid

from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from django.conf import settings
from django.utils.html import mark_safe

from cuser.middleware import CuserMiddleware

COLORS_CHOICES = (
    ('info', _('Light blue')),
    ('primary', _('Blue')),
    ('danger', _('Red')),
    ('warning', _('Yellow')),
    ('success', _('Green')),
    ('secondary', _('Gray')),
    ('dark', _('Black')),
    ('light', _('White')),
)

class TimeStampedModel(models.Model):
    """
    An abstract base class model that provides self-updating
    ``created`` and ``modified`` field.
    """
    created = models.DateTimeField(auto_now_add=True, verbose_name=_('created'))
    modified = models.DateTimeField(auto_now=True, verbose_name=_('modified'))

    class Meta:
        abstract = True

class PublishableModelQuerySet(models.QuerySet):

    # Get the list of published objects
    def published(self):
        """
        We show every objects to staff as a preview
        even if they are not published, yet.
        """
        user = CuserMiddleware.get_user()
        qs = self
        if user and not user.is_staff:
            qs = qs.filter(published=True)
        return qs

class PublishableModelManager(models.Manager):

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

    def published(self):
        return self.get_queryset().published()

class PublishableModel(models.Model):
    """
    A concrete base class model that updates the publication
    date as soon as it becomes published.
    """
    published = models.BooleanField(default=False, verbose_name=_('published'))
    publication_date = models.DateTimeField(blank=True, null=True, verbose_name=_('publication_date'))

    objects = PublishableModelManager()

    # Pubblication date is updated if published has been modified from False to True
    def __init__(self, *args, **kwargs):
        super(PublishableModel, self).__init__(*args, **kwargs)
        self.old_published = self.published

    def save(self, *args, **kwargs):
        if self.old_published != self.published and self.published:
            self.publication_date = timezone.now()
        super(PublishableModel, self).save(*args, **kwargs)

class PromotableModel(models.Model):
    """
    An abstract base class model that enables a promotion feature
    similar to a facebook like on any model.
    """
    promotions = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, verbose_name=_('promotions'))

    def user_has_promoted(self):
        # Fetch the logged user thanks to a dedicated middleware
        user = CuserMiddleware.get_user()
        if user in self.promotions.all():
            return True
        else:
            return False

    class Meta:
        abstract = True

class Element(models.Model):
    """
    An abstract base class model that represents a single piece of content.
    """
    title = models.CharField(
        max_length = 80,
        verbose_name = _('title'),
    )
    icon = models.CharField(
        blank = True,
        max_length = 30,
        verbose_name = _('icon'),
    )
    ICON_STYLE_CHOICES = (
        ('r', 'r - regular'),
        ('s', 's - solid'),
        ('l', 'l - light'),
        ('d', 'd - duotone'),
        ('b', 'b - brand'),

    )
    ICON_STYLE_DEFAULT = 'r'
    icon_style = models.CharField(
        blank = True,
        choices = ICON_STYLE_CHOICES,
        default = ICON_STYLE_DEFAULT,
        max_length = 1,
        verbose_name = _('icon style')
    )
    description = models.TextField(blank=True, verbose_name=_('description'))
    color = models.CharField(blank=True, choices=COLORS_CHOICES, max_length=30, default='default', verbose_name=_('color'))

    def __str__(self):
        return self.title

    def icon_tag(self):
        if self.icon:
            return mark_safe(''.format(self.icon))
        else:
            return _('No icon')
    icon_tag.short_description = _('Icon')

    def color_tag(self):
        if self.color:
            return mark_safe('{1}'.format(self.color, self.get_color_display()))
        else:
            return _('No color')
    color_tag.short_description = _('Color')

    class Meta:
        abstract = True

class Category(models.Model):
    """
    An abstract base class model that defines a specific type of object.
    """
    title = models.CharField(max_length=60, unique=True)
    default = models.BooleanField(default=False)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = _("categories")
        abstract = True

class DiventiImageModel(models.Model):
    """
    An abstract base class that manages models based on images uploaded on the internet.
    """
    image = models.URLField(blank=True, verbose_name=_('image'))
    label = models.CharField(max_length=50, blank=True, verbose_name=_('label'))

    def image_tag(self, image_url=0):
        if image_url:
            return mark_safe(''.format(image_url))
        elif self.image:
            return mark_safe(''.format(self.image))
        else:
            return _('No image')
    image_tag.short_description = _('Image')

    class Meta:
        abstract = True

    def __str__(self):
        return u'{0}'.format(self.label)

class DiventiCoverQuerySet(models.QuerySet):

    # Get the active cover or returns nothing
    def active(self):
        try:
            cover = self.model.objects.get(active=True)
        except self.model.DoesNotExist:
            cover = self.model.objects.none()
        except self.model.MultipleObjectsReturned:
            msg = _("There must be only one object at a time. Please fix!")
            raise self.model.MultipleObjectsReturned(msg)
        return cover

class DiventiCoverManager(models.Manager):

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

    def active(self):
        return self.get_queryset().active()

class DiventiCoverModel(DiventiImageModel):
    """
    An abstract base class that helps to implement an image that can be activated.
    """

    active = models.BooleanField(default=False, verbose_name=_('active'))

    objects = DiventiCoverManager()

    class Meta:
        abstract = True

class FeaturedModelQuerySet(PublishableModelQuerySet):

    # Get the featured object that can be selected to appear on the landing page
    # Even super users should not see featured objects if they are not strictly published
    def featured(self):
        try:
            featured_model = self.published().get(featured=True)
        except self.model.DoesNotExist:
            # Fail silently, return nothing
            featured_model = self.none()
        except self.model.MultipleObjectsReturned:
            msg = _('Multiple featured objects returned. Please fix!')
            raise self.model.MultipleObjectsReturned(msg)
        return featured_model

    # Get the not featured object that can be selected to appear on the landing page
    def not_featured(self):
        not_featured_models = self.published().filter(featured=False)
        return not_featured_models

    # Returns the first pinned objects
    # It assumes that the model has a "publication_date" field
    def pinned(self):
        featured_model = self.published().filter(pinned=True)
        try:
            featured_model = featured_model.get()
        except self.model.MultipleObjectsReturned:
            featured_model = featured_model.order_by('-publication_date').first()
        except self.model.DoesNotExist:
            featured_model = featured_model.first()
        return featured_model

    # Returns the list of pinned objects
    def pinned_list(self):
        featured_model = self.published().filter(pinned=True)
        return featured_model

class FeaturedModelManager(models.Manager):

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

    def published(self):
        return self.get_queryset().published()

    def featured(self):
        return self.get_queryset().featured()

    def not_featured(self):
        return self.get_queryset().not_featured()

    def pinned(self):
        return self.get_queryset().pinned()

    def pinned_list(self):
        return self.get_queryset().pinned_list()

class FeaturedModel(PublishableModel):
    """
    An abstract base class that includes a featured boolean field

    """
    pinned = models.BooleanField(
        default = False,
        verbose_name = _('pinned'),
        help_text = _('Pinned objects appear on the navbar and on the landing page')
    )
    featured = models.BooleanField(
        default=False,
        verbose_name=_('featured'),
        help_text = _('Featured objects are displayed on the top of their page. If pinned, they are also displayed on the top of the landing page')
    )

    objects = FeaturedModelManager()

    class Meta:
        abstract = True

class HighlightedModelQuerySet(models.QuerySet):

    # Get the highlighted object or the first item of the queryset
    def highlighted_or_first(self):
        try:
            highlighted_model = self.get(highlighted=True)
        except self.model.DoesNotExist:
            # Fail silently and return the first item
            highlighted_model = self.first()
        except self.model.MultipleObjectsReturned:
            msg = _('Multiple highlighted objects returned. Please fix!')
            raise self.model.MultipleObjectsReturned(msg)
        return highlighted_model

class HighlightedModelManager(models.Manager):

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

    def highlighted_or_first(self):
        return self.get_queryset().highlighted_or_first()

class HighlightedModel(models.Model):
    """
        An abstract bae class that includes a featured boolean field
        without the publishable functionality.
    """
    highlighted = models.BooleanField(default=False, verbose_name=_('highlighted'))

    objects = HighlightedModelManager()

    class Meta:
        abstract = True

class DiventiColModel(models.Model):
    COL_CHOICES = [
        (12, _('Full (12)')),
        (8, _('Two thirds (8)')),
        (6, _('Half (6)')),
        (4, _('One third (4)')),
        (3, _('One fourth (3)')),
    ]
    col_lg = models.PositiveIntegerField(default=12, choices=COL_CHOICES, verbose_name=_('lg column'))
    order_lg = models.PositiveIntegerField(default=1, verbose_name=_('lg order'))
    col_md = models.PositiveIntegerField(default=12, choices=COL_CHOICES, verbose_name=_('md column'))
    order_md = models.PositiveIntegerField(default=1, verbose_name=_('md order'))
    col_sm = models.PositiveIntegerField(default=12, choices=COL_CHOICES, verbose_name=_('sm column'))
    order_sm = models.PositiveIntegerField(default=1, verbose_name=_('sm order'))

    class Meta:
        abstract = True

class SectionModel(models.Model):
    """ Includes utility methods for content areas such as sections. """
    ALIGNMENT_CHOICES = (
        ('left', _('left')),
        ('centered', _('centered')),
        ('right', _('right')),
    )
    alignment = models.CharField(
        default='centered',
        choices=ALIGNMENT_CHOICES,
        max_length=50,
        verbose_name=_('alignment')
    )
    POSITION_CHOICES = (
        (1, _('text first')),
        (3, _('text second')),
    )
    position = models.PositiveIntegerField(
        default=1,
        choices=POSITION_CHOICES,
        verbose_name=_('text position')
    )

    class Meta:
        abstract = True


class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        for a in ransomNote:
            if a in magazine:
                i = magazine.find(a)
                magazine = magazine[:i] + magazine[i+1:]

            else: return False

        return True

def main():
    s = Solution()
    ran = "aa"
    mag = "ab"
    print(s.canConstruct(ran, mag))

if __name__ == "__main__":
    main()


# You are stuck in maze, size of (NxM) and try to escape avoiding monsters
# Your location is (1, 1) and the exit is on (N, M) and you can move one container by one container
# 0: the place where the monster exists, 1: the place that you can pass through
# Write a program that calculates the minimal movements (contains both the starting and end point)
# Constraints: 4<= N, M <= 200

# Input Example
# 5 6
# 101010
# 111111
# 000001
# 111111
# 111111

# Output Example
# 10

def escape(n, m):

    return False

input_indicator = input()
info = list(input_indicator.split(' '))
row = int(info[0])
col = int(info[1])
maze = [[0] * col] * row
print(maze)
for i in range(row-1):
    maze[i] = input()
print(maze)


import pandas as pd
import csv

def anonymiser(fichierIn, fichierOut, fichierConfig):
    fns = {
    'agregation_1': FonctionGenerique.agregation_1,
    'agregation_N': FonctionGenerique.agregation_N,
    'COPY': FonctionGenerique.copyChamps,
    'Transforme': FonctionGenerique.transformeCrypt,
    }

    df_config = pd.read_csv(fichierConfig, sep=';')
    col_fns = {r['COLUMN_NAME']: partial(fns[r['MASKING']], params=r['args'].split(', ')) for _, r in
    df_config.iterrows()}
    chunkSize = 10000
    df = pd.read_csv(
    fichierIn, sep=';', low_memory=True, chunksize=chunkSize, error_bad_lines=False, encoding='utf8')
    for i, chunk in enumerate(df):
        columbToUpdate = list(col_fns)
        chunk[columbToUpdate] = chunk[columbToUpdate].apply(col_fns) # appliquer les functions
        chunk.to_csv(
        fichierOut, index=False, header=(i == 0), encoding='utf8', sep=';', mode='w' if i == 0 else 'a')


from components import questions
from components import variables

quiz = False
choice = ["y", "n"]

print("\n\033[0;31;40m ---------------------------------------------------\n")
print("                    Marvel Quiz                      \n")
print("            Which Marvel character are you?          \n")
print("\n---------------------------------------------------\033[m\n")

while quiz is False:
    questions.result(variables.answer)
    choice = input("Do you want to play again? y/n: ")

    if choice == "n":
        print("====== see ya! =======")
        exit()
    elif choice == "y":
        variables.Hulk = 0
        variables.IronMan = 0
        variables.CaptainAmerica = 0
        variables.AntMan = 0
        variables.DocStrange = 0
    quiz = False


print("-----------------------------------------------------------")
print(".__________________.")
print("|Area :            |")
print("|__________________|\n")

while True:
    print("Triangle----- 1  | Circle------------ 4")
    print("Square------- 2  | Parallelogram----- 5")
    print("Rectangle---- 3  | Trapezoidal------- 6")
    print("Back--------- !")
    MODE = input("Choose a shape: ")

    if MODE == "1":
        import triangle
    elif MODE == "2":
        import square
    elif MODE == "3":
        import rectangle
    elif MODE == "4":
        import circle
    elif MODE == "5":
        import parallelogram
    elif MODE == "6":
        import trapezoidal
    elif MODE == "!":
        import menu
    else:
        print("\n!!ERROR RESPONSE!!\nPlease Try again\n")


from matplotlib import pyplot as plt
import serial
import sys
import time
import struct
import os
import math as m
import statistics as st
import numpy as np
import pickle as pkl
from copy import deepcopy
from multiprocessing import Process, Manager
import pyaudio
import random as r

import pyFuncs.AudioFuncs as af

plot_selection = 'peaks'
# plot_selection = 'heatmap'
# plot_selection = '3d'

readFilePath = 'MusicData/Instruments/Tenor/noteRec.pkl'
# readFilePath = 'MusicData/Instruments/Alto/noteRec.pkl'

# readFilePath = 'pickle/noteRec_'
# ii = 0
# while os.path.exists(readFilePath + str(ii) + '.pkl'): ii += 1 # Loop until filename ii is not taken
# readFilePath = readFilePath + str(ii-1) + '.pkl'

print(f'Opening {readFilePath}')

pklFile = open(readFilePath, 'rb')
pklDict = pkl.load(pklFile)
pklFile.close()

for foo in pklDict: print(foo)

Right = np.where(np.array(pklDict['solenoid_played']) == 'Right')[0]
Left = np.where(np.array(pklDict['solenoid_played']) == 'Left')[0]

calc_pitch = np.array( pklDict['calc_pitch'] )
calc_confidence = np.array( pklDict['calc_confidence'] )
stepper_position = np.array( pklDict['stepper_position'] )

RATE = pklDict['FS_RATE']

def loadPeaks(fooDict):
    outData = []
    ii = 0

    frqs = []
    pos = []
    signi = []
    while fooDict['stepper_position'][ii] <= fooDict['stepper_position'][ii+1]:
        # if ii > 100: break
        fooSig = fooDict['signal'][ii]
        fooPos = fooDict['stepper_position'][ii]

        print(f"{len(pos)}\033[1A")
        freqs, amps = af.getHarmonic(RATE, fooSig)
        foo_frqs, foo_amps = af.FFT_Peaks(freqs, amps)
        frqs += list(foo_frqs)
        signi += [foo/max(foo_amps) for foo in foo_amps]
        pos += [fooPos for foo in foo_frqs]
        ii += 1
    outData.append( [pos, frqs, signi] )
    print(f"frqs:{len(frqs)}")
    print(f"pos:{len(pos)}")
    print(f"signi:{len(signi)}")

    return(outData)

    frqs = []
    pos = []
    signi = []
    while ii < len(fooDict['stepper_position']):
        fooSig = fooDict['signal'][ii]
        fooPos = fooDict['stepper_position'][ii]

        print(f"{len(pos)}\033[1A")
        freqs, amps = af.getHarmonic(RATE, fooSig)
        foo_frqs, foo_amps = af.FFT_Peaks(freqs, amps)
        frqs += foo_frqs
        signi += [foo/max(foo_amps) for foo in foo_amps]
        pos += [fooPos for foo in foo_frqs]
        ii += 1
    outData.append( [pos, frqs, signi] )
    print(f"frqs:{len(frqs)}")
    print(f"pos:{len(pos)}")
    print(f"signi:{len(signi)}")

    return(outData)

if plot_selection == 'heatmap':
    FREQS_H = None
    AMPS_H = []
    for fooSig in pklDict['signal']:
        # freqs_h, amps_h = af.FFT_Both(RATE, fooSig)
        # freqs_h, amps_h = af.getHarmonic(RATE, fooSig, harmonicCount=2)
        freqs_h, amps_h = af.getHarmonic(RATE, fooSig)
        # freqs_h, amps_h = af.getHarmonic(RATE, fooSig, harmonicCount=4)
        FREQS_H = freqs_h
        AMPS_H.append(amps_h)

    fig, ax = plt.subplots()
    freqCutoff = 1000
    maxInd = np.where(FREQS_H < freqCutoff)[0][-1]
    ax.matshow([fooAmps[:maxInd]/sum(fooAmps[:maxInd]) for fooAmps in AMPS_H], aspect='auto')
    ax.set_xticks(FREQS_H[:maxInd][::m.floor(maxInd/15)][:-1])
    plt.show()

if plot_selection == 'peaks':
    peakData = loadPeaks(pklDict)
    for foo in peakData:
        plt.scatter(foo[0], foo[1], alpha=foo[2])

    outputPickle_fileName = "tmp/notePeaks.pkl"
    outPkl = open(outputPickle_fileName, 'wb')
    pkl.dump(peakData, outPkl)
    outPkl.close()

    plt.show()

if plot_selection == '3d':
    fig = plt.figure()
    ax = plt.axes(projection='3d')

    peakData = loadPeaks(pklDict)
    for ii in range(len(peakData)):
        netIndex = sum([len(peakData[jj]) for jj in range(ii)])
        foo = peakData[ii]
        print(f"foo[0]   len:{len(foo[0])}")
        print(f"foo[1]   len:{len(foo[1])}")
        print(f"pklDict['solenoid_time'][netIndex:netIndex+len(peakData)]   len:{len(pklDict['solenoid_time'][netIndex:netIndex+len(peakData)])}")
        ax.scatter(
            foo[0],
            foo[1],
            pklDict['solenoid_time'][netIndex:netIndex+len(foo[0])],
            alpha=np.array(foo[2])/5,
        )

    ax.set_xlabel("Stepper Position")
    ax.set_ylabel("Frequency (Hz)")
    ax.set_zlabel("Solenoid Strike Time")
    plt.show()

# plt.scatter(range(len(Right)), calc_pitch[Right], alpha = calc_confidence[Right] )
# plt.scatter(range(len(Left)), calc_pitch[Left], alpha = calc_confidence[Left] )

# plt.scatter(abs(stepper_position[Right]), calc_pitch[Right], alpha = calc_confidence[Right] )
# plt.scatter(abs(stepper_position[Left]), calc_pitch[Left], alpha = calc_confidence[Left] )

# plt.scatter(stepper_position[Right], calc_pitch[Right] )
# plt.scatter(stepper_position[Left], calc_pitch[Left] )

# plt.scatter(stepper_position[Right], calc_pitch[Right], alpha = calc_confidence[Right] )
# plt.scatter(stepper_position[Left], calc_pitch[Left], alpha = calc_confidence[Left] )

# plt.plot(range(len(Right)), calc_pitch[Right] )
# plt.plot(range(len(Left)), calc_pitch[Left] )

# plt.scatter(pklDict['calc_pitch'], pklDict['calc_confidence'])

plt.show()


import pytest
from unittest.mock import Mock
from GEMEditor.database.model import *
from GEMEditor.model.classes.cobra import Model, Metabolite, Reaction
from GEMEditor.model.classes.annotation import Annotation
from GEMEditor.database.test.fixtures import database
from PyQt5.QtWidgets import QApplication

# Make sure to only start an application
# if there is no active one. Opening multiple
# applications will lead to a crash.
app = QApplication.instance()
if app is None:
    app = QApplication([])

@pytest.fixture()
def progress():
    mock = Mock()
    mock.wasCanceled = Mock(return_value=False)
    return mock

#Todo: Reimplement test case to not edit settings
# class TestAnnotationSettingsDialog:
#
#     @pytest.mark.parametrize("check_state", (True, False))
#     def test_get_settings(self, check_state):
#         dialog = AnnotationSettingsDialog()
#
#         # Check states
#         dialog.checkBox_charge.setChecked(check_state)
#         dialog.checkBox_formula.setChecked(check_state)
#
#         # Check getting the settings
#         settings = dialog.get_settings()
#         assert settings["formula"] == dialog.checkBox_formula.isChecked()
#         assert settings["charge"] == dialog.checkBox_charge.isChecked()
#
#     @pytest.mark.parametrize("check_state", (True, False))
#     def test_get_settings_resources(self, check_state):
#         metabolite_resources = {"a": 1, "b": 2}
#         reaction_resources = {"c": 3, "d": 4}
#         dialog = AnnotationSettingsDialog(metabolite_resources, reaction_resources)
#
#         # Set state for metabolite checkboxes
#         for checkbox in dialog.metabolite_checkboxes:
#             checkbox.setChecked(check_state)
#
#         # Set state for reaction checkboxes
#         for checkbox in dialog.reaction_checkboxes:
#             checkbox.setChecked(check_state)
#
#         settings = dialog.get_settings()
#         if check_state:
#             assert set(settings["reaction_resources"]) == set(reaction_resources.values())
#             assert set(settings["metabolite_resources"]) == set(metabolite_resources.values())
#         else:
#             assert not settings["reaction_resources"]
#             assert not settings["metabolite_resources"]

class Test_get_reactions_with_same_signature:

    def test_get_entry_matching_signature(self, database):
        signature = set([1, 2, 3, 4])
        entries = set([1])
        result = get_reactions_with_same_signature(database, entries,
                                                   signature, set())
        assert result == set([1])

    def test_dont_get_reactions_matching_signature_not_in_entries(self, database):
        signature = set([1, 2, 3, 4])
        entries = set()
        result = get_reactions_with_same_signature(database, entries,
                                                   signature, set())
        assert result == set()

    def test_not_matching_when_one_metabolite_missing(self, database):
        signature = set([1, 2, 3])
        entries = set([1])
        result = get_reactions_with_same_signature(database, entries,
                                                   signature, set())
        assert result == set()

    def test_not_matching_if_additional_metabolite(self, database):
        signature = set([1, 2, 3, 4, 5])
        entries = set([1])
        result = get_reactions_with_same_signature(database, entries,
                                                   signature, set())
        assert result == set()

    def test_match_if_additional_metabolite_is_ignored(self, database):
        signature = set([1, 2, 3])
        entries = set([1])
        result = get_reactions_with_same_signature(database, entries,
                                                   signature, set([4]))
        assert result == set([1])

class Test_map_by_annotation:

    def test_map_metabolites(self, database):
        metabolite = Metabolite("m1")
        metabolite.annotation.add(Annotation(identifier="MNXM2", collection="metanetx.chemical"))
        metabolite.annotation.add(Annotation(identifier="MNXM215", collection="metanetx.chemical"))

        assert map_by_annotation(database, metabolite) == set([1, 2])

    def test_empty_result_if_not_in_db(self, database):
        metabolite = Metabolite("m1")
        metabolite.annotation.add(Annotation(identifier="MNXM2000", collection="metanetx.chemical"))

        assert map_by_annotation(database, metabolite) == set()

class Test_update_metabolite_database_mapping:

    def test_map_metabolite_by_annotation(self, database, progress):
        model = Model()
        met1 = Metabolite("m1")
        model.add_metabolites([met1])
        met1.annotation.add(Annotation(identifier="MNXM2", collection="metanetx.chemical"))

        update_metabolite_database_mapping(database, model, progress)
        assert model.database_mapping[met1] == 1

    def test_map_metabolite_by_name(self, database, progress):
        model = Model()
        met1 = Metabolite("m1", name="Water")
        model.add_metabolites([met1])

        update_metabolite_database_mapping(database, model, progress)
        assert model.database_mapping[met1] == 1

    def test_not_mapped_for_name_substring(self, database, progress):
        model = Model()
        met1 = Metabolite("m1", name="ater")
        model.add_metabolites([met1])

        update_metabolite_database_mapping(database, model, progress)
        assert model.database_mapping[met1] is None

    def test_map_metabolite_by_formula(self, database, progress):
        model = Model()
        met1 = Metabolite("m1", formula="H2O")
        model.add_metabolites([met1])

        update_metabolite_database_mapping(database, model, progress)
        assert model.database_mapping[met1] == 1

class Test_check_ambiguous_mappings:

    def test_do_nothing_if_no_ambiguous_maps(self):
        model = Model()
        metabolite = Metabolite()
        model.database_mapping[metabolite] = 1
        check_ambiguous_mappings(model, None)

        assert model.database_mapping[metabolite] == 1

    def test_ambiguous_maps_present(self):
        # Todo: Implement test
        assert True

class Test_update_reaction_database_mapping:

    def test_map_reaction_by_stoichiometry(self, database, progress):
        model = Model()
        met1 = Metabolite("m1")
        met2 = Metabolite("m2")
        met3 = Metabolite("m3")
        met4 = Metabolite("m4")
        model.add_metabolites((met1, met2,
                               met3, met4))
        model.database_mapping.update({met1: 1,
                                       met2: 2,
                                       met3: 3,
                                       met4: 4})
        reaction = Reaction("r1")
        reaction.add_metabolites({met1: -1, met2: -1,
                                  met3: 1, met4: 1})
        model.add_reactions([reaction])

        update_reaction_database_mapping(database, model, progress)

        assert model.database_mapping[reaction] == 1

    def test_map_reaction_by_annotation(self, database, progress):
        model = Model()
        met1 = Metabolite("m1")
        met2 = Metabolite("m2")
        model.add_metabolites([met1, met2])

        reaction = Reaction("r1")
        reaction.add_metabolites({met1: -1, met2: 1})
        reaction.annotation.add(Annotation(identifier="MNXR14892",
                                           collection="metanetx.reaction"))
        model.add_reactions([reaction])

        update_reaction_database_mapping(database, model, progress)

        assert model.database_mapping[reaction] == 1

    def test_no_map_by_stoichiometry_if_any_metabolite_not_mapped(self, database, progress):
        model = Model()
        met1 = Metabolite("m1")
        met2 = Metabolite("m2")
        model.add_metabolites((met1, met2))
        model.database_mapping.update({met1: 1})

        reaction = Reaction("r1")
        reaction.add_metabolites({met1: -1, met2: -1})
        model.add_reactions([reaction])

        update_reaction_database_mapping(database, model, progress)
        assert reaction not in model.database_mapping


import inflect

e = inflect.engine()

def main():
    names: list = []
    while True:
        try:
            n: str = input("Name: ")
            if len(n) > 0:
                n = n.title()
                names.append(n)
            else:
                exit(0)
        except EOFError:
            print(f"\nAdieu, adieu, to {e.join(names)}")
            break
        else:
            continue

if __name__ == "__main__":
    main()


import numpy as np
import cv2
import math
from random import random
import warnings
import time

# TODO: update from rjq's

warnings.simplefilter('ignore', np.RankWarning)

BANNED = ("'", '"', ',', '.')

def get_l2_dist(point1, point2):
    '''
    :param point1: tuple (x, y) int or float
    :param point2: tuple (x, y)
    :return: float
    '''
    return float(((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2)**0.5)

def get_l1_dist(point1, point2):
    '''
    :param point1: tuple (x, y) int or float
    :param point2: tuple (x, y)
    :return: float
    '''
    return float(abs(point1[0] - point2[0]) + abs(point1[1] - point2[1]))

def get_cos(point, point1, point2):
    '''
    :param point: tuple (x, y) int or float
    :param point1: tuple (x, y) int or float
    :param point2: tuple (x, y) int or float
    :return: float
    '''
    # point is pivot
    vec1 = (point[0] - point1[0], point[1] - point1[1])
    vec2 = (point[0] - point2[0], point[1] - point2[1])

    a_dot_b = vec1[0] * vec2[0] + vec1[1] * vec2[1]
    if a_dot_b > 0:
        sign = 1
    else:
        sign = -1
    a_dot_b = a_dot_b * sign
    a_mul_b = get_l2_dist(point, point1) * get_l2_dist(point, point2)
    try:
        cos = sign * math.exp(math.log(a_dot_b) - math.log(a_mul_b))
    except:
        #print('cos error')
        cos = 0.0
    # possible error: ValueError: math domain error
    return cos

def get_shortest_dist(point, point1, point2):
    '''
    :param point: tuple (x, y) int or float
    :param point1: tuple (x, y) int or float
    :param point2: tuple (x, y) int or float
    :return: float
    '''
    dist1 = get_l2_dist(point, point1)
    dist2 = get_l2_dist(point, point2)
    if get_cos(point1, point, point2) < 0 or get_cos(point2, point, point1) < 0:
        return min(dist1, dist2)
    else:
        return dist1 * math.sqrt(1 - get_cos(point1, point, point2)**2)

def get_theta(points_list):
    '''
    :param points_list: list(tuple), tuple (x, y) int or float
    :return: float
    '''
    if len(points_list) < 2:
        raise AttributeError('get_theta need at least 2 points')
    xs, ys = [], []
    for (x, y) in points_list:
        xs.append(x)
        ys.append(y)
    xs = np.array(xs)
    x_var = np.var(xs)
    y_var = np.var(ys)
    ys = np.array(ys)
    # convert back to the coordination of cnts
    if x_var < y_var:
        m, b = np.polyfit(ys, xs, 1)
    else:
        m, b = np.polyfit(xs, ys, 1)
        if abs(m) > 1e-10:
            m = 1 / m
        else:
            m = 1e10
    theta = np.arctan(m)
    return theta

def get_radius(point, cnt):
    '''
    :param point: (x, y), int or float, x needs to be row, y needs to be col
    :param cnt: cnt: numpy.ndarray, shape (n, 1, 2) or (n, 2), dtype float32 or int32, point order (col, row)
    :return:
    '''
    cnt = np.squeeze(cnt)
    # change the order of the cnt
    cnt_changed = [(point[1], point[0]) for point in cnt]
    cnt_changed = cnt_changed + [cnt_changed[0]]
    dist_list = []

    for i in range(len(cnt_changed) - 1):
        dist_list.append(get_shortest_dist(point, cnt_changed[i], cnt_changed[i + 1]))
    return max(dist_list)

def is_validate_cnts(im, cnts):
    '''
    :param im: numpy.ndarray, shape (row, col, 3), dtype uint 8
    :param cnts: list(numpy.ndarray), shape (n, 1, 2) or (n, 2), dtype float32 or int32, point order (col, row)
    :return: bool
    '''
    cols, rows = [], []
    for cnt in cnts:
        cnt = np.squeeze(cnt)
        for i in range(len(cnt)):
            cols.append(cnt[i][0])
            rows.append(cnt[i][1])
    col_max = max(cols)
    row_max = max(rows)
    col_min = min(cols)
    row_min = min(rows)
    im_row, im_col = im.shape[0] - 1, im.shape[1] - 1
    flag = True
    if im_row < row_max:
        flag = False
    if im_col < col_max:
        flag = False
    if col_min < 0:
        flag = False
    if row_min < 0:
        flag = False
    return flag

def is_validate_point(im, point):
    '''
    :param im: numpy.ndarray, shape (row, col, 3), dtype uint 8
    :param point: (x, y) int or float , x needs to be row, y needs to be col
    :return: bool
    '''
    row, col = im.shape[:2]
    return (point[0] < row) and (point[1] < col)

def is_inside_point_cnt(point, cnt):
    '''
    :param point: (x, y) int or float, where x is row, y is col
    :param cnt: numpy.ndarray, shape (n, 1, 2), dtype int32 or float32, point order (col, row)
    :return: bool
    '''
    cnt = np.array(cnt, np.float32)
    point = (point[1], point[0])
    return cv2.pointPolygonTest(cnt, point, False) >= 0

def validate(im, cnts, cnts1=None, chars=None):
    '''
    :param im: numpy.ndarray, shape (row, col, 3), dtype uint 8
    :param cnts: list(numpy.ndarray), shape (n, 1, 2) or (n,2), dtype int32 or float32, point order (col, row)
    :param cnts1: if is not None, cnts is char_cnts, cnts1 is text cnts
    :return:
        im: numpy.ndarray, shape (row, col, 3), dtype uint 8
        cnts: list(numpy.ndarray), shape (n, 1, 2), dtype float32, point order (col, row)
    '''
    row, col = im.shape[:2]
    # make sure the shape cnts

    temp = []
    for cnt in cnts:
        cnt = np.reshape(cnt, (-1, 1, 2))
        temp.append(cnt)
    cnts = temp

    for i in range(len(cnts)):
        num, one, two = cnts[i].shape[0], cnts[i].shape[1], cnts[i].shape[2]
        for j in range(num):
            for k in range(one):
                for l in range(two):
                    if cnts[i][j, k, l] < 0.0:
                        cnts[i][j, k, l] = 0.0

    # if cnt out side the img, drop it
    if chars is None:
        temp = []
        for cnt in cnts:
            num, one, two = cnt.shape[0], cnt.shape[1], cnt.shape[2]
            flag = True
            for i in range(num):
                if cnt[i, 0, 0] >= col or cnt[i, 0, 1] >= row:
                    flag = False
                    print('cnt is out of image')
            if flag:
                temp.append(cnt)
        cnts = [np.array(np.reshape(cnt, (-1, 1, 2)), np.float32) for cnt in cnts]
        return im, cnts
    else:
        temp = []
        for cnt in cnts1:
            cnt = np.reshape(cnt, (-1, 1, 2))
            temp.append(cnt)
        cnts1 = temp

        for i in range(len(cnts1)):
            num, one, two = cnts1[i].shape[0], cnts[i].shape[1], cnts[i].shape[2]
            for j in range(num):
                for k in range(one):
                    for l in range(two):
                        if cnts1[i][j, k, l] < 0.0:
                            cnts1[i][j, k, l] = 0.0

        # priori: the num of char box matches num of char
        # priori: the num of text box matches the len of chars
        # testing:
        chars_count = 0
        for text in chars:
            for char in text:
                chars_count += 1
        if chars_count != len(cnts):
            pass
            #print('our priori for synthtext is wrong, algo might goes wrong: chars_count != len(char_cnts) ')
            # print('chars_count', chars_count)
            # print('len_char_count', len(cnts))

        temp_char_cnts = []
        temp_text_cnts = []
        temp_chars = []
        flatten_index = 0
        for text_index in range(len(chars)):
            temp_chars_ = []
            text_flag = False
            for char_index in range(len(chars[text_index])):
                flag = True
                for i in range(len(cnts[flatten_index])):
                    if cnts[flatten_index][i, 0, 0] >= col or cnts[flatten_index][i, 0, 1] >= row:
                        flag = False
                        print('cnt is out of image')
                text_flag = flag or text_flag
                if flag:
                    temp_chars_.append(chars[text_index][char_index])
                    temp_char_cnts.append(cnts[flatten_index])
                flatten_index += 1
            if text_flag:
                temp_text_cnts.append(cnts1[text_index])
                temp_chars.append(temp_chars_)

        cnts = temp_char_cnts
        cnts1 = temp_text_cnts
        chars = temp_chars

        cnts = [np.array(np.reshape(cnt, (-1, 1, 2)), np.float32) for cnt in cnts]
        # cnts1 = [np.array(np.reshape(cnt, (-1,1,2)), np.float32) for cnt in cnts1]
        # print('cnts' , cnts)
        # print('cnts1' , cnts1)

        return im, cnts, cnts1, chars

def resize(im, cnts, row, col):
    '''
    :param im: numpy.ndarray, shape (row, col, 3), dtype uint 8
    :param cnts: list(numpy.ndarray), shape (n, 1, 2), dtype float32, point order (col, row)
    :param row: int
    :param col: int
    :return:
        im: numpy.ndarray, shape (row, col, 3), dtype uint 8
        cnts: list(numpy.ndarray), shape (n, 1, 2), dtype float32, point order (col, row)
    '''
    im_row, im_col = im.shape[0], im.shape[1]
    im_ = cv2.resize(im, (row, col), interpolation=cv2.INTER_CUBIC)
    cnts_ = []
    for cnt in cnts:
        cnt = np.reshape(cnt, (-1, 1, 2))
        temp = np.zeros_like(cnt, np.float32)
        for i in range(len(cnt)):
            temp[i][0][0] = cnt[i][0][0] * col / im_col
            temp[i][0][1] = cnt[i][0][1] * row / im_row
        cnts_.append(temp)
    cnts_ = [np.array(np.reshape(cnt, (-1, 1, 2)), np.float32) for cnt in cnts_]
    return im_, cnts_

def sampling(p1, p2, sampling_num):
    '''
    :param p1: point(x,y) int or float
    :param p2: point(x,y)
    :param sampling_num:
    :return: points_list, list(point), float
    '''
    x = np.linspace(p1[0], p2[0], sampling_num)
    y = np.linspace(p1[1], p2[1], sampling_num)
    return [(x[i], y[i]) for i in range(x.shape[0])]

def get_cos_with_4(p1, p2, p3, p4):
    '''
    :param p1: point(x,y) int or float
    :param p2: point(x,y) int or float
    :param p3: point(x,y) int or float
    :param p4: point(x,y) int or float
    :return: float
    '''
    vector_1 = (p2[0] - p1[0], p2[1] - p1[1])
    vector_2 = (p4[0] - p3[0], p4[1] - p3[1])
    if get_l2_dist(vector_2, (0, 0)) * get_l2_dist(vector_1, (0, 0)) == 0.0:
        return 0.0
    return (vector_1[1] * vector_2[1] + vector_1[0] * vector_2[0]) / (get_l2_dist(vector_2, (0, 0)) * get_l2_dist(vector_1, (0, 0)))

def find_mid_line_with_radius_theta(points_list, crop_skel, neighbor, sampling_num=500):
    '''
    :param points_list: list(tuple), tuple (x, y)
    :param sampling_num: int. the number to sample on one line for a cnt
    :return: center_line, radius_dict, theta_dict
        center_line: list(tuple), tuple (x, y), x y are int
        radius_dict: dict, key is tuple (x, y), value is float
        theta_dict: dict, key is tuple (x, y), value is float
    '''

    points_list = [tuple(point) for point in points_list]

    if len(points_list) > 4:
        circular_points_list = points_list + points_list[:3]
        cosine_list = [(circular_points_list[i + 1], circular_points_list[i + 2],
                        get_cos_with_4(circular_points_list[i + 0],
                                       circular_points_list[i + 1],
                                       circular_points_list[i + 2],
                                       circular_points_list[i + 3]), i)
                       for i in range(len(points_list))]
        best = None
        #(i,j),i<j
        for i in range(len(cosine_list)):
            for j in range(i + 1, len(cosine_list)):
                if cosine_list[i][0] != cosine_list[j][1] and cosine_list[j][0] != cosine_list[i][1]:
                    if best is None:
                        best = (i, j)
                    else:
                        if cosine_list[best[0]][2] + cosine_list[best[1]][2] > cosine_list[i][2] + cosine_list[j][2]:
                            best = (min(i, j), max(i, j))

        line_one = [cosine_list[p][1] for p in range(best[0], best[1])]
        line_two = ([cosine_list[p][1] for p in range(best[1], len(cosine_list))] + [cosine_list[p][1] for p in range(0, best[0])])[::-1]
    elif len(points_list) == 4:
        d1 = get_l2_dist(points_list[0], points_list[1])
        d2 = get_l2_dist(points_list[1], points_list[2])
        d3 = get_l2_dist(points_list[2], points_list[3])
        d4 = get_l2_dist(points_list[3], points_list[0])
        if d1 + d3 < d2 + d4:
            line_one = [points_list[1], points_list[2]]
            line_two = [points_list[0], points_list[3]]
        else:
            line_one = [points_list[0], points_list[1]]
            line_two = [points_list[3], points_list[2]]
    elif len(points_list) == 3:
        d1 = get_l2_dist(points_list[0], points_list[1])
        d2 = get_l2_dist(points_list[1], points_list[2])
        d3 = get_l2_dist(points_list[2], points_list[0])

        if d1 < min(d2, d3):
            line_one = [points_list[2], points_list[0]]
            line_two = [points_list[2], points_list[1]]
        if d2 < min(d3, d1):
            line_one = [points_list[0], points_list[1]]
            line_two = [points_list[0], points_list[2]]
        if d3 < min(d2, d1):
            line_one = [points_list[1], points_list[0]]
            line_two = [points_list[1], points_list[2]]
    else:
        raise AttributeError('points_list with less than 3 points')

    point_list_one = []
    point_list_two = []
    total_len_one = sum([get_l2_dist(line_one[i], line_one[i + 1]) for i in range(len(line_one) - 1)])
    total_len_two = sum([get_l2_dist(line_two[i], line_two[i + 1]) for i in range(len(line_two) - 1)])
    for p in range(len(line_one) - 1):
        point_list_one += sampling(line_one[p + 0], line_one[p + 1], math.floor(get_l2_dist(line_one[p + 0], line_one[p + 1]) * sampling_num / total_len_one))

    for p in range(len(line_two) - 1):
        point_list_two += sampling(line_two[p + 0], line_two[p + 1], math.floor(get_l2_dist(line_two[p + 0], line_two[p + 1]) * sampling_num / total_len_two))

    if len(point_list_one) != len(point_list_two):
        if len(point_list_one) < len(point_list_two):
            point_list_one, point_list_two = point_list_two, point_list_one  # by default, one > two
        while len(point_list_one) != len(point_list_two):
            p = int(random() * len(point_list_one))
            point_list_one.pop(p)

    center_line_set = set()
    center_line = []
    radius_dict = {}
    theta_dict = {}

    for i in range(len(point_list_one)):
        x1, y1 = point_list_one[i][0], point_list_one[i][1]
        x2, y2 = point_list_two[i][0], point_list_two[i][1]
        x, y = int(round((x1 + x2) / 2)), int(round((y1 + y2) / 2))
        if not((x, y) in center_line_set):
            center_line.append((x, y))
        center_line_set.add((x, y))
        radius_dict[(x, y)] = get_l2_dist((x1, y1), (x2, y2)) / 2

    if len(points_list) == 4:
        theta = get_theta([center_line[0]] + center_line[::30] + [center_line[-1]])
        for point in center_line:
            theta_dict[point] = theta
    else:
        for p, point in enumerate(center_line):
            neighbor = int(round(neighbor))
            theta = get_theta(list(set(center_line[max(p - neighbor, 0):p + neighbor])))
            theta_dict[point] = theta

    temp = []
    temp_radius_dict = {}
    temp_theta_dict = {}
    crop_length1 = radius_dict[center_line[0]]
    crop_length2 = radius_dict[center_line[-1]]
    decrease = 0.0
    while len(temp) <= 1:
        for point in center_line:
            crop_length1 = crop_length1 * (1 - decrease)
            crop_length2 = crop_length2 * (1 - decrease)
            if get_l2_dist(point, center_line[0]) >= crop_length1 * crop_skel and \
               get_l2_dist(point, center_line[-1]) >= crop_length2 * crop_skel:
                temp.append(point)
                temp_radius_dict[point] = radius_dict[point]
                temp_theta_dict[point] = theta_dict[point]
        decrease += 0.01
    center_line = temp
    radius_dict = temp_radius_dict
    theta_dict = temp_theta_dict
    return center_line, radius_dict, theta_dict

def get_maps_textbox(im, cnts, thickness, crop_skel, neighbor):
    '''
    :param im: numpy.ndarray, shape (row, col, 3), dtype uint 8
    :param cnts: list(numpy.ndarray), shape (n, 1, 2), dtype int32 or float32, point order (col, row)
    :return: skels_points, radius_dict, cos_theta_dict, sin_theta_dict, theta_dict, mask_fills
        skels_points: list(tuple), tuple (x, y), x y are int
        radius_dict: dict, key is tuple (x, y), value is float
        score_dict: dict, key is tuple (x, y), value is bool
        cos_theta_dict: dict, key is tuple (x, y), value is float
        sin_theta_dict: dict, key is tuple (x, y), value is float
        mask_fills: list(numpy.ndarray), numpy.ndarray shape (row, col, 1), dtype bool
    '''

    skels_points = []
    radius_dict = {}
    weight_dict = {}
    score_dict = {}
    theta_dict = {}
    cos_theta_dict = {}
    sin_theta_dict = {}
    mask_fills = []
    for cnt in cnts:
        #t = time.time()
        cnt = np.squeeze(cnt)
        # change cordinate from cnt to point_list
        point_list = [(point[1], point[0]) for point in cnt]
        skel_points, radius_dict_cnt, theta_dict_cnt = \
            find_mid_line_with_radius_theta(point_list, crop_skel, neighbor, sampling_num=500)

        for point, radius in radius_dict_cnt.items():
            radius_dict[point] = radius
        for point, theta in theta_dict_cnt.items():
            theta_dict[point] = theta
        for point in skel_points:
            skels_points.append(point)

        #print('part1 takes:', time.time() - t)
        #t = time.time()

        mask_fill = np.zeros(im.shape[:2], dtype=np.uint8)
        cnt_ = np.array(cnt, np.int32)
        mask_fill = cv2.fillPoly(mask_fill, pts=[cnt_], color=(255))
        mask_fills.append(mask_fill.copy().astype(np.bool))

        #print('part2 takes:', time.time() - t)
        #t = time.time()

        # get belt
        belt = set()
        connect_dict = {}
        for point in skel_points:
            r = int(thickness * radius_dict[point])
            for i in range(-r, r + 1):
                for j in range(-r, r + 1):
                    candidate = (point[0] + i, point[1] + j)
                    if is_validate_point(im, candidate):
                        belt.add(candidate)
                        if candidate not in connect_dict:
                            connect_dict[candidate] = []
                        connect_dict[candidate].append(point)

        #print('part3 takes:', time.time() - t)
        #t = time.time()

        # score map
        for point in belt:
            score_dict[point] = True

        # theta, raidus map
        for point in belt:
            min_dist = 1e8
            min_dist_point = None
            for skel_point in connect_dict[point]:
                dist = get_l2_dist(point, skel_point)
                if dist < min_dist:
                    min_dist_point = skel_point
                    min_dist = dist
            cos_theta_dict[point] = math.cos(theta_dict[min_dist_point[0], min_dist_point[1]])
            sin_theta_dict[point] = math.sin(theta_dict[min_dist_point[0], min_dist_point[1]])
            radius_dict[point] = radius_dict[min_dist_point[0], min_dist_point[1]] - min_dist
            weight_dict[point] = 1 / len(set(belt))

        #print('part4 takes:', time.time() - t)
        #t = time.time()

    return skels_points, radius_dict, score_dict, cos_theta_dict, sin_theta_dict, mask_fills, weight_dict

def find_mid_line_with_radius_theta_char(char_cnt_per_text, sampling_num=500):
    '''
    :param char_cnt_per_text: list(tuple(point, char_cnt));
                            point: (x, y) int;
                            char_cnt: np.ndarray(4,2) or (4,1,2);
    :param crop_skel:
    :param neighbor:
    :param sampling_num:
    :return:
        center_line: list(tuple), tuple (x, y), x y are int
        radius_dict: dict, key is tuple (x, y), value is float
        theta_dict: dict, key is tuple (x, y), value is float

    '''
    radius_dict = {}
    theta_dict = {}

    skel_points = set()
    len_ = len(char_cnt_per_text)

    for point, char_cnt in char_cnt_per_text:
        radius_dict[point] = get_radius(point, char_cnt)

    for i in range(len_):
        skel_points.add(char_cnt_per_text[i][0])
    for i in range(len_ - 1):
        point1, point2 = char_cnt_per_text[i][0], char_cnt_per_text[i + 1][0]
        sample_points = sampling(point1, point2, sampling_num // (len_ - 1))
        sample_radius = np.linspace(radius_dict[point1], radius_dict[point2], len(sample_points))
        if i == 0:
            theta = get_theta([point1, point2])
        else:
            # theta = 0.5*(get_theta([point1, point2])+get_theta([point1, char_cnt_per_text[i-1][0]]))
            theta = get_theta([char_cnt_per_text[i - 1][0], point1, point2])
        for point, radius in zip(sample_points, sample_radius):
            sample = (int(round(point[0])), int(round(point[1])))
            skel_points.add(sample)
            radius_dict[sample] = radius
            theta_dict[sample] = theta
    if len_ == 1:
        theta_dict[char_cnt_per_text[0][0]] = math.pi / 2
    for i in range(len_):
        assert char_cnt_per_text[i][0] in radius_dict
        assert char_cnt_per_text[i][0] in theta_dict
    return skel_points, radius_dict, theta_dict

def get_center_point(cnt):
    '''
    :param cnt: list(tuple(col,row))
    :return: tuple(x, y) x, y are int, x is row, y is col
    '''
    cnt = np.squeeze(cnt)
    xs, ys = [], []
    for point in cnt:
        xs.append(point[1])
        ys.append(point[0])
    return int(round(sum(xs) / len(xs))), int(round(sum(ys) / len(ys)))

def char_filter(char_cnt_per_text_with_char):
    '''
    :param char_cnt_per_text_with_char: list(tuple(point, char_cnt, char));
            point: (x, y) int;
            char_cnt: np.ndarray(4,2) or (4,1,2);
            char: str
    :return: char_cnt_per_text: list(tuple(point, char_cnt, char));
            point: (x, y) int;
            char_cnt: np.ndarray(4,2) or (4,1,2);
    '''
    char_cnt_per_text = []
    for point, char_cnt, char in char_cnt_per_text_with_char:
        if char not in BANNED:
            char_cnt_per_text.append((point, char_cnt))

    return char_cnt_per_text

def reconstruct(skel_points, radius_dict_cnt, row, col):
    '''
    :param skel_points: list(tuple(x,y))
    :param radius_dict_cnt:
    :return:
        mask_fill numpy.ndarray shape (row, col, 1), dtype bool
    '''
    # denote that: when changing from point_list to hull or cnt
    # we need to change the coordination
    zeros = np.zeros((row, col), np.uint8)
    for point in skel_points:
        radius = radius_dict_cnt[point]
        radius = int(round((radius)))
        zeros = cv2.circle(zeros, (point[1], point[0]), radius, (255), -1)
    _, cnts, _ = cv2.findContours(zeros, 1, 2)
    mask_fill = np.zeros((row, col), np.uint8)
    cnts = [np.array(cnt, np.int32) for cnt in cnts]
    mask_fill = cv2.fillPoly(mask_fill, cnts, (255)).astype(np.bool)
    return mask_fill

def get_maps_charbox(im, cnts, thickness, crop_skel, neighbor, chars):
    '''
    :param im: numpy.ndarray, shape (row, col, 3), dtype uint 8
    :param cnts: list(list(numpy.ndarray)), shape (n, 1, 2), dtype int32, point order (col, row)
                [text_cnts, char_cnts]
    :param thickness: float
    :param neighbor: float
    :param crop_skel: float
    :param chars: a nested list storing the chars info for synthtext
    :return:
        skels_points: list(tuple), tuple (x, y), x y are int
        radius_dict: dict, key is tuple (x, y), value is float
        score_dict: dict, key is tuple (x, y), value is bool
        cos_theta_dict: dict, key is tuple (x, y), value is float
        sin_theta_dict: dict, key is tuple (x, y), value is float
        mask_fills: list(numpy.ndarray), numpy.ndarray shape (row, col, 1), dtype bool

    '''
    skels_points = []
    radius_dict = {}
    weight_dict = {}
    score_dict = {}
    theta_dict = {}
    cos_theta_dict = {}
    sin_theta_dict = {}
    mask_fills = []

    char_cnts, text_cnts = cnts
    flatten_chars = []
    for temp in chars:
        for char in temp:
            flatten_chars.append(char)

    flatten_index = 0
    for text_index in range(len(chars)):
        temp = flatten_index
    # for text_index in (14,):
    #     flatten_index = 66
        char_cnt_per_text_with_char = []
        for char_index in range(len(chars[text_index])):
            char_cnt = char_cnts[flatten_index]
            char = flatten_chars[flatten_index]
            flatten_index += 1
            center_point = get_center_point(char_cnt)
            char_cnt_per_text_with_char.append((center_point, char_cnt, char))
        char_cnt_per_text = char_filter(char_cnt_per_text_with_char)

        if len(char_cnt_per_text) == 1:
            point_list = [(point[0][1], point[0][0]) for point in char_cnt_per_text[0][1]]
            skel_points, radius_dict_cnt, theta_dict_cnt = \
                find_mid_line_with_radius_theta(point_list, crop_skel, neighbor)
        else:
            skel_points, radius_dict_cnt, theta_dict_cnt = \
                find_mid_line_with_radius_theta_char(char_cnt_per_text, sampling_num=500)
        for point, radius in radius_dict_cnt.items():
            radius_dict[point] = radius
        for point, theta in theta_dict_cnt.items():
            theta_dict[point] = theta
        [skels_points.append(point) for point in skel_points]

        mask_fill = reconstruct(skel_points, radius_dict_cnt, im.shape[0], im.shape[1])
        mask_fills.append(mask_fill.astype(np.bool))

        # get belt
        belt = set()
        connect_dict = {}

        for point in skel_points:
            r = int(thickness * radius_dict[point])
            for i in range(-r, r + 1):
                for j in range(-r, r + 1):
                    candidate = (point[0] + i, point[1] + j)
                    if is_validate_point(im, candidate):
                        belt.add(candidate)
                        if candidate not in connect_dict:
                            connect_dict[candidate] = []
                        connect_dict[candidate].append(point)

        # score map
        for point in belt:
            score_dict[point] = True

        # theta, raidus map
        for point in belt:
            min_dist = 1e8
            min_dist_point = None
            for skel_point in connect_dict[point]:
                dist = get_l2_dist(point, skel_point)
                if dist < min_dist:
                    min_dist_point = skel_point
                    min_dist = dist
            cos_theta_dict[point] = math.cos(theta_dict[min_dist_point[0], min_dist_point[1]])
            sin_theta_dict[point] = math.sin(theta_dict[min_dist_point[0], min_dist_point[1]])
            radius_dict[point] = radius_dict[min_dist_point[0], min_dist_point[1]] - min_dist
            weight_dict[point] = 1 / len(set(belt))

    return skels_points, radius_dict, score_dict, cos_theta_dict, sin_theta_dict, mask_fills, weight_dict

def get_maps(im, cnts, is_textbox, thickness, crop_skel, neighbor, chars=None):
    '''
    :param im: numpy.ndarray, shape (row, col, 3), dtype uint 8
    :param cnts:
           if is_textbox is True:
            cnts: list(numpy.ndarray), shape (n, 1, 2), dtype int32 or float32, point order (col, row) for textbox
           if is_textbox is False:
            cnts: [char_cnts, text_cnts], both char_cnts and text_cnts are the same as the text_cnts above
    :param is_textbox: bool
    :param thickness: float, used to span a belt from center(skeleton) line, used both for (text_cnts) and (char&text cnts)
    :param crop_skel: float, used to crop the head and end of center(skeleton) line, used for (text_cnts)
    :param neighbor: float, used to determine the range for fitting aline to get theta, used both for (text_cnts) and (char&text cnts)
    :return: skels_points: list(tuple) center(skeleton) line, (x, y) int, x is row, y is col
             radius_dict, score_dict, cos_theta_dict, sin_theta_dict: key is tuple(x,y), value is float
             mask_fills: list(np.ndarray) shape(row,col,1), dtype bool
    '''

    if is_textbox:
        # check the shape first
        temp = []
        for cnt in cnts:
            cnt = np.reshape(cnt, (-1, 1, 2))
            temp.append(cnt)
        cnts = temp

        # validate the cnts
        if not is_validate_cnts(im, cnts):
            im, cnts = validate(im, cnts)
        cnts = [np.array(cnt, np.float32) for cnt in cnts]
        skels_points, radius_dict, score_dict, cos_theta_dict, sin_theta_dict, mask_fills, weight_dict = \
            get_maps_textbox(im, cnts, thickness, crop_skel, neighbor)

    else:
        if chars is None:
            raise AttributeError('chars need to be passed in')
        char_cnts, text_cnts = cnts

        # check the shape first
        temp = []
        for cnt in char_cnts:
            cnt = np.reshape(cnt, (-1, 1, 2))
            temp.append(cnt)
        char_cnts = temp

        for cnt in text_cnts:
            cnt = np.reshape(cnt, (-1, 1, 2))
            temp.append(cnt)
        text_cnts = temp

        # validate the cnts
        if (not is_validate_cnts(im, char_cnts)) or\
                (not is_validate_cnts(im, text_cnts)):
            im, char_cnts, text_cnts, chars = validate(im, char_cnts, text_cnts, chars)

        char_cnts = [np.array(cnt, np.float32) for cnt in char_cnts]
        text_cnts = [np.array(cnt, np.float32) for cnt in text_cnts]
        cnts = [char_cnts, text_cnts]
        skels_points, radius_dict, score_dict, cos_theta_dict, sin_theta_dict, mask_fills, weight_dict = \
            get_maps_charbox(im, cnts, thickness, crop_skel, neighbor, chars)
    return skels_points, radius_dict, score_dict, cos_theta_dict, sin_theta_dict, mask_fills, weight_dict

if __name__ == '__main__':
    ########### test text_cnts ############

    # PKL_DIR = '/home/rjq/data_cleaned/pkl/'
    # import pickle
    #
    # for i in range(1000):
    #     res = pickle.load(open(PKL_DIR+'totaltext_train/'+str(i)+'.bin', 'rb'))
    #     print('processing '+str(i))
    #     print('img_name', res['img_name'])
    #     img_name = res['img_name']
    #     img = res['img']
    #     cnts = res['contour']
    #     is_text_cnts = res['is_text_cnts']
    #
    #     skels_points, radius_dict, score_dict, cos_theta_dict, sin_theta_dict, mask_fills = \
    #         get_maps(img, cnts, is_text_cnts, thickness=0.15, crop_skel=1.0, neighbor=5)
    #     TR = mask_fills[0]
    #     for i in range(1, len(mask_fills)):
    #         TR = np.bitwise_or(TR, mask_fills[i])
    #     TCL = np.zeros(img.shape[:2], np.bool)
    #     for point, _ in score_dict.items():
    #         TCL[point[0], point[1]] = True
    #     radius = np.zeros(img.shape[:2], np.float32)
    #     for point, r in radius_dict.items():
    #         radius[point[0], point[1]] = r
    #     cos_theta = np.zeros(img.shape[:2], np.float32)
    #     for point, c_t in cos_theta_dict.items():
    #         cos_theta[point[0], point[1]] = c_t
    #     sin_theta = np.zeros(img.shape[:2], np.float32)
    #     for point, s_t in sin_theta_dict.items():
    #         sin_theta[point[0], point[1]] = s_t
    #
    #
    #     def save_heatmap(save_name, map):
    #         map = np.array(map, np.float32)
    #         if np.max(map) != 0.0 or np.max(map) != 0:
    #             cv2.imwrite(save_name, (map * 255 / np.max(map)).astype(np.uint8))
    #         else:
    #             cv2.imwrite(save_name, map.astype(np.uint8))
    #     # cv2.imwrite(img_name+'.jpg', img)
    #     # zeros = np.zeros_like(img)
    #     # cnts = [np.array(cnt, np.int32) for cnt in cnts]
    #     # zeros = cv2.drawContours(zeros, cnts, -1, (255,255,255), 1)
    #     # cv2.imwrite(img_name+'_box.jpg', zeros)
    #     # save_heatmap(img_name+'_TR.jpg', TR)
    #     # save_heatmap(img_name+'_TCL.jpg', TCL)
    #     # save_heatmap(img_name+'_radius.jpg', radius)
    #     # save_heatmap(img_name+'_cos_theta.jpg', cos_theta)
    #     # save_heatmap(img_name+'_sin_theta.jpg', sin_theta)

    ######## test char_cnts and text_cnts ############
    PKL_DIR = '/home/rjq/data_cleaned/pkl/'
    import pickle

    for index in range(8000, 800000):
        # for index in (1741,):
        res = pickle.load(open(PKL_DIR + 'synthtext_chars/' + str(index) + '.bin', 'rb'))
        print('processing' + str(index))
        print('imname ', res['img_name'])
        img_name = res['img_name']
        img_name = img_name.replace('/', '_')
        img = res['img']
        cnts = res['contour']
        is_text_cnts = res['is_text_cnts']
        chars = res['chars']

        cv2.imwrite(img_name + '.jpg', img)
        char_cnts, text_cnts = cnts
        zeros = np.zeros_like(img)
        char_cnts = [np.array(cnt, np.int32) for cnt in char_cnts]
        text_cnts = [np.array(cnt, np.int32) for cnt in text_cnts]
        zeros = cv2.drawContours(zeros, char_cnts, -1, (0, 0, 255), 1)
        zeros = cv2.drawContours(zeros, text_cnts, -1, (255, 255, 255), 1)
        cv2.imwrite(img_name + '_box.jpg', zeros)

        skels_points, radius_dict, score_dict, cos_theta_dict, sin_theta_dict, mask_fills = \
            get_maps(img, cnts, is_text_cnts, thickness=0.15, neighbor=5, crop_skel=1.0,
                     chars=chars)

        TR = mask_fills[0]
        for i in range(1, len(mask_fills)):
            TR = np.bitwise_or(TR, mask_fills[i])
        TCL = np.zeros(img.shape[:2], np.bool)
        for point, _ in score_dict.items():
            TCL[point[0], point[1]] = True
        radius = np.zeros(img.shape[:2], np.float32)
        for point, r in radius_dict.items():
            radius[point[0], point[1]] = r
        cos_theta = np.zeros(img.shape[:2], np.float32)
        for point, c_t in cos_theta_dict.items():
            cos_theta[point[0], point[1]] = c_t
        sin_theta = np.zeros(img.shape[:2], np.float32)
        for point, s_t in sin_theta_dict.items():
            sin_theta[point[0], point[1]] = s_t

        def save_heatmap(save_name, map):
            map = np.array(map, np.float32)
            if np.max(map) != 0.0 or np.max(map) != 0:
                cv2.imwrite(save_name, (map * 255 / np.max(map)).astype(np.uint8))
            else:
                cv2.imwrite(save_name, map.astype(np.uint8))

        save_heatmap(img_name + '_TR.jpg', TR)
        save_heatmap(img_name + '_TCL.jpg', TCL)
        save_heatmap(img_name + '_radius.jpg', radius)
        save_heatmap(img_name + '_cos_theta.jpg', cos_theta)
        save_heatmap(img_name + '_sin_theta.jpg', sin_theta)


print("""
**************************************
**    Welcome to the Snakes Cafe!   **
**    Please see our menu below.    **
**
** To quit at any time, type "quit" **
**************************************

Appetizers
----------
Wings
Cookies
Spring Rolls

Entrees
-------
Salmon
Steak
Meat Tornado
A Literal Garden

Desserts
--------
Ice Cream
Cake
Pie

Drinks
------
Coffee
Tea
Unicorn Tears

***********************************
** What would you like to order? **
***********************************
""")

# EMPTY MEAL DICTIONARY
menu_items = {
    "Wings": 0, "Cookies": 0, "Spring Rolls": 0,
    "Salmon": 0, "Steak": 0, "Meat Tornado": 0, "A Literal Garden": 0,
    "Ice Cream": 0, "Cake": 0, "Pie": 0,
    "Coffee": 0, "Tea": 0, "Unicorn Tears": 0
}

# VARIABLES
# sing_response = f"** {num_items} order of {order} has been added to your meal **"
# plur_response = f"** {num_items} orders of {order} have been added to your meal **"
customer_ticket = {}

# start loop and repeat until user enters 'quit'

while True:
    order = input('> ').capitalize()
    if order == "Quit":
        break
    elif order not in menu_items:
        print('**Sorry! We don\'t seem to carry that. Would you like to order anything else?**')
        continue
    elif order not in customer_ticket:
        customer_ticket.update({order: 0})
    customer_ticket[order] += 1
    print(f'** {customer_ticket[order]} order of {order} have been added to your meal.**')
    # else:
    # print(f'** {customer_ticket[order]} orders of {order} have been added to your meal.**')

# end/break loop when user quits


'''
Get all file names within a file folder
'''

#mypath ='C:\\Users\\codye\\Documents\\Schoolwork\\Modernization Class'
def pathtolist(pathname):
    '''Function takes a copied path file directory and converts it so
    python can read and pull file names'''
    new_path = pathname.split('\\')
    com_path = ''
    for string in new_path:
        com_path += (string + '\\')

    from os import walk
    files = []
    for (dirpath, dirnames, filenames) in walk(com_path):
        files.extend(filenames)
        break
    return files


#coding: UTF-8
from selenium import webdriver
from time import sleep
# 下载地址
# http://chromedriver.storage.googleapis.com/index.html
driver=webdriver.Chrome()
driver.maximize_window()
driver.get('http://www.baidu.com')
driver.find_element_by_id("kw").send_keys("刘德华")
driver.find_element_by_id("su").click()

sleep(5)
driver.quit()


import torch
from torch import nn
import numpy as np
import matplotlib
import matplotlib.pyplot as plt

import sklearn
from sklearn.datasets import make_blobs
from sklearn.model_selection import train_test_split
from helper_functions import accuracy_fn, plot_predictions, plot_decision_boundary

X_blob, y_blob = make_blobs(n_samples=1000,
                            n_features=2,
                            centers=4,
                            cluster_std=1.5,
                            random_state=42)

X_blob = torch.from_numpy(X_blob).type(torch.float32)
y_blob = torch.from_numpy(y_blob).type(torch.LongTensor)

X_blob_train, X_blob_test, y_blob_train, y_blob_test = train_test_split(X_blob,
                                                                        y_blob,
                                                                        test_size=0.2,
                                                                        random_state=42)

print(X_blob_train.shape, y_blob_train.shape)
plt.figure(figsize=(10, 7))
plt.scatter(X_blob[:, 0], X_blob[:, 1], c=y_blob, cmap=plt.cm.RdYlBu)
plt.show()

class BlobModel(nn.Module):
    def __init__(self, input_features, output_features, hidden_units=8):
        super().__init__()
        self.linear_layer_stack = nn.Sequential(
            nn.Linear(in_features=input_features, out_features=hidden_units),
            nn.ReLU(),
            nn.Linear(in_features=hidden_units, out_features=hidden_units),
            nn.ReLU(),
            nn.Linear(in_features=hidden_units, out_features=output_features)
        )

    def forward(self, x) -> torch.tensor:
        return self.linear_layer_stack(x)

torch.manual_seed(42)
model = BlobModel()


# Open and read file, getting polymer template and insertion rules
input = open('14_input.txt', 'r')
polymer_template = input.readline().strip()
insertion_rules = {}
for line in input:
    if '->' in line:
        pair, insertion = line.strip().split('->')
        insertion_rules[pair.strip()] = insertion.strip()
input.close()

# Initialize dict counting all polymer pairs
pair_count = {}
for i in range(len(polymer_template) - 1):
    pair = polymer_template[i] + polymer_template[i+1]
    if pair in pair_count.keys():
        pair_count[pair] += 1
    else:
        pair_count[pair] = 1

# Calculate number of each pair for a certain number of steps
steps = 40
for i in range(steps):

    # Create a dict for new pairs based on old pairs
    pair_count_new = {}

    # Figure out new pairs based on those we already have
    for pair in pair_count.keys():
        # Get insertion from insertion rules and generate new pairs
        insertion = insertion_rules[pair[0] + pair[1]]
        newpairs = (pair[0] + insertion, insertion + pair[1])
        for newpair in newpairs:
            if newpair in pair_count_new.keys():
                pair_count_new[newpair] += pair_count[pair]
            else:
                pair_count_new[newpair] = pair_count[pair]

    # Need to update the pairs to use as old pairs for next step
    pair_count = {}
    for pair in pair_count_new.keys():
        if pair in pair_count.keys():
            pair_count[pair] += pair_count_new[pair]
        else:
            pair_count[pair] = pair_count_new[pair]

# Sum up letters based on the pairs
letter_count = {}
for pair in pair_count:
    if pair[0] == pair[1]:
        # Equal letters in pair, add to sum
        if pair[0] in letter_count.keys():
            letter_count[pair[0]] += pair_count[pair]
        else:
            letter_count[pair[0]] = pair_count[pair]

    else:
        # Else, add half of it to avoid counting twice
        for letter in pair:
            if letter in letter_count.keys():
                letter_count[letter] += pair_count[pair] / 2
            else:
                letter_count[letter] = pair_count[pair] / 2

# Round numbers
for letter in letter_count.keys():
    letter_count[letter] = int(letter_count[letter] + 0.5)

print(f'Most common minus least common after {steps} steps: {max(letter_count.values()) - min(letter_count.values())}')


# from Strusion import IO
import IO
from math import floor
from tqdm import tqdm
#  Default values
x_axis = 192 			# x axis for second sub
y_axis = 48				# y axis for second sub
y_axis_bottom = 268		# y axis for second sub

default_sub_color = "ffffff"

def merge_two_subtitles(path_sub_1, path_sub_2, color=None,
                        x_axis=None, y_axis=None):
    sub1 = IO.load(path_sub_1)  # loading file
    sub2 = IO.load(path_sub_2)  # ''

    sub_position_str = set_position(
        axis_x=x_axis, axis_y=y_axis, one_subtitle=False)
    color_str = set_color(color)
    control = False  # control var to indicates that is a new sub block
    sub1.append('')

    for i in tqdm(range(len(sub2))):
        if 'ï»¿' in sub2[i]:
            sub2[i] = sub2[i][len(sub2[i]) - 1]

        if control:  # goes into because is the firstline without '-->'
            # add the first line
            sub1.append(sub_position_str + color_str + sub2[i])
            control = False

        elif sub2[i] != '':
            sub1.append(sub2[i])  # add the subsequent lines

        else:
            sub1.append("")  # add the last line
            sub1.append("")

        if '-->' in sub2[i]:  # from here, the code goes to a new sub block
            control = True
    return sub1

def change_one_subtitle(path_sub, color=None, x_axis=None, y_axis=None):
    sub1 = IO.load(path_sub)
    sub_out = list()

    sub_position_str = set_position(
        axis_x=x_axis,
        axis_y=y_axis,
        one_subtitle=True)
    color_str = set_color(color)
    control = False
    sub1.append('')
    for i in tqdm(range(len(sub1))):
        if 'ï»¿' in sub1[i]:
            sub1[i] = sub1[i][len(sub1[i]) - 1]

        if control:
            sub_out.append(sub_position_str + color_str + sub1[i])
            control = False

        elif sub1[i] != '':

            sub_out.append(sub1[i])  # add the subsequent lines

        else:
            sub_out.append("")  # add the last line
            sub_out.append("")

        if '-->' in sub1[i]:  # from here, the code goes to a new sub block
            control = True
    return sub_out

def change_subtitle_delay(millis, path_sub):
    millisecs = int(millis)
    sub = IO.load(path_sub)
    for i in tqdm(range(len(sub))):
        if '-->' in sub[i]:
            slices = sub[i].split(" --> ")
            ini = format_string_to_millisecs(slices[0])
            end = format_string_to_millisecs(slices[1])
            modification = "{} --> {}".format(
                format_millisecs_to_string(ini + millisecs),
                format_millisecs_to_string(end + millisecs))
            sub[i] = modification
    return sub

def set_position(one_subtitle, axis_x=None, axis_y=None):  # axis
    """
    Define the subtitle position on top
    :param axis_x, axis_y:
    :return:
    """

    # two different position exists for the y axis,
    # that's why the extra 'if' in y,
    x = axis_x if axis_x else x_axis  # se false usa o default
    y = axis_y if axis_y else (y_axis_bottom if one_subtitle else y_axis)
    return "{\\pos(" + str(x) + "," + str(y) + ")}"

def set_color(color):
    return ""

def format_millisecs_to_string(millis):
    millis = str(millis)
    millisecs = int(millis[-3:])
    millis = int(millis)
    seconds = (millis / 1000) % 60
    seconds = int(seconds)
    minutes = (millis / (1000 * 60)) % 60
    minutes = int(minutes)
    hours = (millis / (1000 * 60 * 60)) % 24
    string_formated = "{:02d}:{:02d}:{:02d},{:03d}"\
        .format(floor(hours), minutes, seconds, millisecs)
    return string_formated

def format_string_to_millisecs(string):
    # all the vars are in millisecs
    slices = string.split(':')
    hour = int(slices[0]) * (1000 * 60 * 60)
    minutes = int(slices[1]) * (1000 * 60)
    slices2 = slices[2].split(',')
    seconds = int(slices2[0]) * 1000
    millisecs = int(slices2[1])
    total = hour + minutes + seconds + millisecs
    return total