#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pygame
from dashLine import *
from random import randint
from pygame.locals import *

# Definindo as cores que serão utilizadas em nosso jogo
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

# Criamos uma classe para tratar das funções da bola do
# jogo pong.
class Pong():
	def __init__(self, screensize):
		# OBS: Não podemos guardar a tela como parâmetro pois isso
		# geraria conflito com os outros objetos e a referência
		# para esta janela não seria guardada.

		# Armazenamos o tamanho da janela dentro do proprio objeto
		# para que não seja preciso passá-la como parâmetro de uma
		# função depois.
		self.screensize = screensize

		# Gerando as posições centrais do pong.
		self.centerx = int(screensize[0]*0.5)
		self.centery = int(screensize[1]*0.5)

		# Tamanho do raio.
		self.radius = 5

		# Gerando um retângulo externo e invisivel.
		self.rect = pygame.Rect(self.centerx - self.radius,
								self.centery - self.radius,
								self.radius*2, self.radius*2)

		# Definindo a cor.
		self.color = WHITE

		# Lista com direção x e y.
		self.direction = [0,0]

		# Velocidade com qual o pong se move em cada eixo.
		self.speed = [4,0]

		# Guardamos uma contagem para aumentar a Velocidade
		self.counter = 0

		# Verifica se o pong batou na esquerda.
		self.hitEdgeLeft = False
		# Verifica se o pong batou na direita.
		self.hitEdgeRight = False

	def render(self, screen):
		# Esta função receberá a tela criada no código principal,
		# a cor definida na criação do objeto, e o retângulo que
		# criamos anteriormente, o zero no final indica que não
		# haverá uma borda nesse objeto.
		pygame.draw.rect(screen, self.color, self.rect, 0)

	def update(self, jogador, computador):
		# Atualiza a posição X e Y andando na direção escolhida
		# com a velocidade atual.
		self.centerx += self.direction[0] * self.speed[0]
		self.centery += self.direction[1] * self.speed[1]

		# Atualiza o novo centro do retângulo de acordo com o
		# calculo feito anteriormente.

		self.rect.center = (self.centerx, self.centery)

		if self.rect.top <= 0:
			self.rect.top = 0
			self.direction[1] *= -1
		if self.rect.bottom >= self.screensize[1] - 1:
			self.rect.bottom = self.screensize[1] - 1
			self.direction[1] *= -1
		if self.rect.left <= 0:
			self.direction[0] *= - 1
			self.hitEdgeLeft = True
		if self.rect.right >= self.screensize[0] - 1:
			self.direction[0] *= - 1
			self.hitEdgeRight = True

		if self.rect.colliderect(jogador.rect):
			self.direction[0] = -1
			self.speed[1] = 3
			self.counter = int((self.counter + 1) / 10)
			self.speed[0] = randint(2 + self.counter, 8 + self.counter)
		if self.rect.colliderect(computador.rect):
			self.direction[0] = 1
			self.speed[1] = 3
			self.counter = int((self.counter + 1) / 10)
			self.speed[0] = randint(2 + self.counter, 8 + self.counter)

class Paddle():
	def __init__(self, screensize):
		self.screensize = screensize
		self.centerx = screensize[0] - 16
		self.centery = int(screensize[1]*0.5)

		self.color = WHITE
		self.radiusxy = [5, 30]

		self.direction = 0
		self.speed = 4

		self.rect = pygame.Rect(self.centerx - self.radiusxy[0],
								self.centery - self.radiusxy[1],
								self.radiusxy[0]*2, self.radiusxy[1]*2)

	def render(self, screen):
		pygame.draw.rect(screen, self.color, self.rect, 0)

	def update(self):
		self.centery += self.direction * self.speed
		if self.centery - self.radiusxy[1] <= 0:
			self.centery = self.radiusxy[1]
		elif self.centery + self.radiusxy[1] >= self.screensize[1] - 1:
			self.centery = self.screensize[1] - 1 - self.radiusxy[1]
		self.rect.center = (self.centerx, self.centery)

		if self.rect.top <= 0:
			self.rect.top = 0
		if self.rect.bottom >= self.screensize[1] - 1:
			self.rect.bottom = self.screensize[1] - 1

class AIPaddle():
	def __init__(self, screensize):
		self.screensize = screensize
		self.centerx = 16
		self.centery = int(screensize[1]*0.5)

		self.color = WHITE
		self.radiusxy = [5, 30]
		self.speed = 4

		self.rect = pygame.Rect(self.centerx - self.radiusxy[0],
								self.centery - self.radiusxy[1],
								self.radiusxy[0]*2, self.radiusxy[1]*2)

	def render(self, screen):
		pygame.draw.rect(screen, self.color, self.rect, 0)

	def update(self, pong):
		self.speed = randint(3,4)
		if pong.direction[0] == -1:
			if self.rect.top > pong.rect.top:
				self.centery -= self.speed
			elif self.rect.bottom < pong.rect.bottom:
				self.centery += self.speed

		self.rect.center = (self.centerx, self.centery)

# Definimos uma função principal que será responsável pela
# execução do jogo
def main():
	# Iniciamos uma instancia do pygame utilizando o método
	# init() dentro do pacote pygame.
	pygame.init()

	# Definimos o título da janela
	pygame.display.set_caption("Pong")

	# Indicamos o tamanho da janela utilizando uma tupla
	# com os tamanhos (largura, altura)
	screensize = (640,480)

	# Iniciamos uma nova janela utilizando o tamanho
	# definido anteriormente
	screen = pygame.display.set_mode(screensize)

	# Para que o jogo rode é necessário ter controle sobre
	# o tempo que se passa no processador, chamados de tick,
	# e para isso utilizamos um objeto próprio do pygame
	# chamado de Clock()
	clock = pygame.time.Clock()

	# Define uma fonte de systema.
	# myfont = pygame.font.Font("/font/8-BIT WONDER.ttf", 50)
	myfont = pygame.font.SysFont("monospace", 50)
	# Define um texto com a fonte escolhida e uma cor.
	myText = myfont.render("Game Over", 0, WHITE)
	# Pega o retângulo externo do texto criado e muda o
	# centro dele em uma nova instância.
	rect = myText.get_rect(center=(int(screensize[0]*0.5), int(screensize[1]*0.5)))

	# Ver instruções acima.
	myText2 = myfont.render("You Win", 0, WHITE)
	rect2 = myText2.get_rect(center=(int(screensize[0]*0.5), int(screensize[1]*0.5)))
	#go = pygame.image.load("images/gameOver.png")

	# Aqui criamos uma instancia de cada objeto necessário
	# para o jogo

	# Barra do jogador
	jogador = Paddle(screensize)

	# Barra do computador
	computador = AIPaddle(screensize)

	# Bola do pong
	pong = Pong(screensize)
	# Definimos uma direção inicial
	# Depois podemos definir para o jogador apertar para o lado que ele
	# deseja que a bola possa ir.
	pong.direction = [-1,-1]

	# Esta variável serve para que possamos tratar mais
	# facilmente como o jogo é executado
	running = True
	fim = False

	scoreJogador = 0
	scoreComputador = 0

	while running:
		# Temos que dizer ao jogo quantos Frames Por Segundo desejamos.
		# Para isso utilizamos a função tick do objeto Clock() que foi
		# instanciado anteriormente.
		clock.tick(60)

		# Precisamos também tratar todos os eventos que ocorrem em nosso
		# jogo, como: fechamento da janelaf, botão apertado, etc.
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				running = False
			if event.type == KEYDOWN:
				if event.key == K_UP:
					jogador.direction = -1
				elif event.key == K_DOWN:
					jogador.direction = 1
				elif event.key == K_SPACE and fim == True:
					pong = Pong(screensize)
					jogador = Paddle(screensize)
					computador = AIPaddle(screensize)
					pong.direction = [-1,-1]
					scoreJogador = 0
					scoreComputador = 0
					fim = False
			if event.type == KEYUP:
				if event.key == K_UP and jogador.direction == -1:
					jogador.direction = 0
				elif event.key == K_DOWN and jogador.direction == 1:
					jogador.direction = 0

		# Após cada iteração do jogo, devemos limpar a tela anterior,
		# se não, o jogo ficaria sendo desenhado por cima do anterior,
		# e não queremos isso.f
		screen.fill(BLACK)

		if pong.hitEdgeRight:
			screen.blit(myText, rect)
			fim = True
		elif pong.hitEdgeLeft:
			screen.blit(myText2, rect2)
			fim = True
		else:
			pong.update(jogador, computador)
			jogador.update()
			computador.update(pong)

		# Função fora do escopo da criação do jogo, ela serve
		# para gerar uma linha "cortada". Usada como:
		# draw_dashed_line(surf, color, start_pos, end_pos, width, dash_length)
		draw_dashed_line(screen, WHITE, (int(screensize[0]*0.5), 10), (int(screensize[0]*0.5), screensize[1]-1), 5, screensize[1]/20)
                #		pygame.draw.line(screen, WHITE, (int(screensize[0]*0.5), 10), (int(screensize[0]*0.5), screensize[1]-1))

		# Mandamos um sinal para cada objeto do nosso jogo que possui a
		# função render() que servirá para que eles sejam desenhados na
		# tela e passamos a nossa tela como um parâmetro.
		pong.render(screen)
		jogador.render(screen)
		computador.render(screen)

		# Mandamos o Pygame mostrar tudo o que foi desenhado nesta iteração
		# do jogo.
		pygame.display.flip()

	# Quando o jogo para de ser executado, ou seja, a variável
	# running passar a ter o valor falso, o loop principal do
	# jogo será terminado e assim chamamos o método de fechamento
	# do pygame.
	pygame.quit()

# No início do programa chamamos a função main() para
# que o jogo seja executado.
main()


import cv2
import mss
import pytesseract
import pyautogui
import re
import numpy as np
import time

from PIL import Image
from BoundBox import GUI

class FastWords:
    def __init__(self, no_dims=False):
        pytesseract.pytesseract.tesseract_cmd = r'C:\Users\Ali\AppData\Local\Tesseract-OCR\tesseract'

        self.SCT = mss.mss()
        if no_dims:
            gui = GUI()
            gui.mainloop()
            self.dimensions = {
                'left':     gui.bbox_r[0].get(),
                'top':      gui.bbox_r[1].get(),
                'width':    gui.bbox_r[2].get() - gui.bbox_r[0].get(),
                'height':   gui.bbox_r[3].get() - gui.bbox_r[1].get()
            }

            gui = GUI()
            gui.mainloop()
            self.dimensions_large = {
                'left':     gui.bbox_r[0].get(),
                'top':      gui.bbox_r[1].get(),
                'width':    gui.bbox_r[2].get() - gui.bbox_r[0].get(),
                'height':   gui.bbox_r[3].get() - gui.bbox_r[1].get()
            }

        else:
            self.dimensions = {
                    'left': 787,
                    'top': 117,
                    'width': 1110,
                    'height': 195
                }

            self.dimensions_large = {
                    'left': 787,
                    'top': 117,
                    'width': 1110,
                    'height': 195
            }

        self.init_text_box(self.dimensions)

    def init_text_box(self, dims):
        img = np.array(self.SCT.grab(dims))
        while True:
            cv2.imshow('', img)
            if cv2.waitKey(25) & 0xFF == ord("q"):
                cv2.destroyAllWindows()
                break

    def clean_text(self, tes_out:str) -> str:
        try:
            res = re.search('[A-Z]+', tes_out).group()
        except AttributeError as e:
            res = ""
        print(tes_out)
        print(res)
        return res

    def convert_to_text(self, img):
        txt = pytesseract.image_to_string(img)
        return self.clean_text(txt)

    def read_screen(self) -> str:
        img = np.array(self.SCT.grab(self.dimensions))
        color = cv2.cvtColor(img, cv2.IMREAD_COLOR)
        return self.convert_to_text(color)

    def find_letter(self, letter, SwitchBool):
        '''Looks for letter

        Args:
            letter: letter to be looked for

        '''

        while SwitchBool.switch.bool:
            print('looking for letter')
            time.sleep(1)

if __name__ == '__main__':
    FW = FastWords(no_dims=True)
    print(FW.dimensions)


import numpy as np
import matplotlib.pyplot as plt

# Eğitim seti
X = np.array([1, 2, 3])
D = np.array([3, 5, 7])
def Hesapla():
# Ağırlık katsayıları başlangıç değeri
    w1 = 1
    b = 1

# Öğrenme katsayısı
    eta = 0.005

# Epoch sayısı
    num_epochs = 20

# Hata dizisi
    E = np.zeros(num_epochs)

# Epoch döngüsü
    for epoch in range(num_epochs):

    # Her bir veri için ağırlık güncellemesi
        for j in range(len(X)):
        # Ağırlık güncellemesi
            w1 = w1 - eta * (-34 + 14 * w1 + 6 * b)
            b = b - eta * (-15 + 6 * w1 + 3 * b)

        # Mevcut ağırlıklar için yapay sinir ağının çıkışı hesaplanır
            v = w1 * X[j] + b
            y = v

        # X(j) girişi için yapay sinir ağı hatası
            e = D[j] - y

            print('w1 = {}; b = {}'.format(w1, b))

    # Epoch için karesel hata
        KareselHata = (1 / 2) * np.sum(e ** 2)
        print('*** Epoch = {}'.format(epoch + 1))
        print('E = {}'.format(KareselHata))

    # Hata dizisi güncellemesi
        E[epoch] = KareselHata

    # Ağırlık ve bias değerleri
        print('Optimizasyon sonucunda Ağırlık, Bias ve Karesel Hata Değerleri')
        print('w1 = {}; b = {}'.format(w1, b))
        print('E = {}'.format(KareselHata))

    # Hata grafiği
        plt.plot(np.arange(num_epochs) + 1, E)
        plt.xlabel('Epoch')
        plt.ylabel('E')
        plt.grid()
        plt.show()


#!/usr/bin/python3

import json
import os
import shlex
import sys
import random

CONFIGFILENAME = 'config.json'
CONFIGFILEPATH = "/".join(os.path.realpath(__file__).split('/')[:-1]) + '/'
OUTPUTTOFILE = False
OUTPUTFILENAME = ''

PREFIX = ''
POSTFIX = ''
ALWAYSCHANGE = dict()
SOMETIMESCHANGE = dict()
CHANGECASE = False
SETCASE = 'lower'

HelloMessage = '''
#################################
#                               #
#     @@@@    @@@@@    @@@@     #
#    @          @      @        #
#    @          @      @@@      #
#    @          @      @        #
#     @@@@      @      @        #
#                               #
#  F L A G   G E N E R A T O R  #
#################################
                   brought to you
                        by LeKSuS
'''
HelpMessage = '''
ctfgen - tool for generating CTF flags.
Usage: ctfgen [options] [flags]
    * You can provide multiple flags;
    * Everything from the first parameter that cannot be interpreted as option will be interpreted as flags.

Options:
    -c, --count         <integer>   Amount of variations generated for each flag. Set to 1 by default;
    -f, --file          <file>      Read flags from file. Each line will be interpreted as separate flag;
    -h, --help                      Display this help message;
    -i, --interactive               Run in interactive mode;
    -o, --output        <file>      Redirect output into file instead of console;
    -s, --settings      <file>      Provide custom configuration file (you can modify standart instead).

Examples:
    ctfgen this is flag         | Generates three flags, from "this", "is" and "flag"
    ctfgen "this is flag"       | Generates flag from string "this is flag"
    ctfgen -c 15 yoooooooo      | Generates 15 random flags from "yoooooooo"
    ctfgen -c 4 -f input.txt -o flags.txt   | Generates 4 random flags from each line from input.txt file
                                            | and outputs them into flags.txt
    ctfgen -s ~/custom.json "Hello, world!" | Generates flag from "Hello, world!" using rules from ~/custom.json

Configuration file:
    The configuration file must be named "config.json" and placed in the same directory as the script; Otherwise, you have to specify path to configuration file using --settings option.

    Configuration file is a JSON file with following structure:
    {
        "FlagPrefix" : "flag{",         | Prefix used to each flag;
        "FlagPostfix" : "}",            | Postfix used to each flag;
                                        | Prefix and postfix are not affected by following settings;
                                        |
                                        |
        "AlwaysChange" : [              | Dictionary of phrases that will always be changed ;
            {                           |
                "'" : [""],             | "'" symbol will be removed;
                " " : ["_", "-"],       | " " symbol will be changed randomly to "_" or "-".;
                "lol" : ["lul"]         | "lol" will be changed to "lul";
            }                           |
        ],                              | All rules in this section must be written in lower case;
                                        |
                                        |
        "SometimesChange" : [           | Dictionary of phrases that will sometimes be changed;
            {                           |
                "a" : ["4"],            | "a" symbol has a chance to be changed to "4";
                "b" : ["6"],            | "b" symbol has a chance to be changed to "6";
                "e" : ["3"],            | "e" symbol has a chance to be changed to "3";
                "g" : ["6", "9"],       | "g" symbol has a chance to be changed to "6" or "9";
                "i" : ["1"],            | "i" symbol has a chance to be changed to "1";
                "j" : ["1"],            | "j" symbol has a chance to be changed to "1";
                "l" : ["1"],            | "l" symbol has a chance to be changed to "1";
                "o" : ["0"],            | "o" symbol has a chance to be changed to "0";
                "q" : ["9"],            | "q" symbol has a chance to be changed to "9";
                "s" : ["5"],            | "s" symbol has a chance to be changed to "5";
                "t" : ["7"],            | "t" symbol has a chance to be changed to "7";
                                        |
                "for" : ["4"],          | "for" has a chance to be changed to "4";
                "to" : ["2"],           | "to" has a chance to be changed to "2";
                "ate" : ["8"]           | "ate" has a chance to be changed to "8";
            }                           |
        ],                              | All rules in this section must be written in lower case;
                                        |
                                        |
        "CaseSettings" : [              | Settings defining case of flag;
            {                           |
                "ChangeCase" : true,    | Determines whether to change the case of given flag (true/false);
                "SetCase" : "random"    | If "ChangeCase" is set to true, this determines case
                                        | of genereated flag. Could be set to:
            }                           |       * lower     - only lowercase
        ]                               |       * upper     - only uppercase
    }                                   |       * random    - mix of both cases
'''
InteractiveHelpMessage = '''
ctfgen - tool for generating CTF flags.
You're in interactive mode. To transform anything to flag, just type it in

Command list:
    options                                 List all settings variables;
    set <variable name|id> <value>          Assign new value to variable;

    write <file>                            Redirect output to file instead of console;
    console                                 Redirect output back to console;
    clearoutput                             Clear output file;
    read <file>                             Read flags from file. Each line will be
                                            interpreted as separate flag;

    help                                    Display this help message;
    exit                                    Exit interactive mode;
'''

def read_config(file = CONFIGFILEPATH + CONFIGFILENAME):
    global PREFIX, POSTFIX, ALWAYSCHANGE, SOMETIMESCHANGE, CHANGECASE, SETCASE
    with open(file, 'r') as f:
        try:
            conf = json.loads(f.read())
        except:
            print('Error while reading configuration file')

        try:
            PREFIX = conf['Prefix']
            POSTFIX = conf['Postfix']
            ALWAYSCHANGE = conf['AlwaysChange'][0]

            SOMETIMESCHANGE = conf['SometimesChange'][0]

            CaseSettings = conf['CaseSettings'][0]
            CHANGECASE = CaseSettings['ChangeCase']
            SETCASE = CaseSettings['SetCase'].lower()
        except KeyError as e:
            raise ValueError("Wrong configuration file format:", e)

def write_config():
    save = {
        "Prefix" : PREFIX,
        "Postfix" : POSTFIX,
        "AlwaysChange" : [ALWAYSCHANGE],
        "SometimesChange" : [SOMETIMESCHANGE],
        "CaseSettings" : [{
            "ChangeCase" : CHANGECASE,
            "SetCase" : SETCASE
        }]
    }
    with open(CONFIGFILENAME, 'w') as f:
        f.write(json.dumps(save, indent=4, sort_keys=True))

def modify(string):
    letters = list(string.lower())

    i = 0
    while i < len(letters):
        if letters[i] in ALWAYSCHANGE:
            if len(ALWAYSCHANGE[letters[i]]) < 1:
                raise ValueError(f'No matches for letter {letters[i]} in AlwaysChange section of configuration file')
            else:
                variants = ALWAYSCHANGE[letters[i]].copy()
                new_letters = random.choice(variants)
                del letters[i]

                for c in new_letters[::-1]:
                    letters.insert(i, c)

        if letters[i] in SOMETIMESCHANGE:
            if len(SOMETIMESCHANGE[letters[i]]) < 1:
                raise ValueError(f'No matches for letter {letters[i]} in SometimesChange section of configuration file')
            else:
                variants = SOMETIMESCHANGE[letters[i]].copy()
                variants.append(letters[i])
                letters[i] = random.choice(variants)

        if CHANGECASE and letters[i].isalpha():
            if SETCASE == "lower":
                letters[i] = letters[i].lower()
            elif SETCASE == "upper":
                letters[i] = letters[i].upper()
            elif SETCASE == "random":
                letters[i] = random.choice([letters[i].upper(), letters[i].lower()])
            else:
                raise ValueError(f'SetCase value from configuration file doesn\'t match any of given options.\n' +
                                 f'Possible options: upper, lower, random;\n' +
                                 f'Given option: {SETCASE}')

        i += 1

    return PREFIX + "".join(letters) + POSTFIX

def output(flag):
    if OUTPUTTOFILE:
        with open(OUTPUTFILENAME, 'a') as f:
            f.write(modify(flag) + '\n')
    else:
        print(modify(flag))

def interactive():
    global OUTPUTTOFILE, OUTPUTFILENAME, PREFIX, POSTFIX, ALWAYSCHANGE, SOMETIMESCHANGE, CHANGECASE, SETCASE

    print(HelloMessage)
    print(InteractiveHelpMessage)

    msg = ''
    while msg not in ['quit', 'exit']:
        msg = input(' > ').strip().lower()

        if msg == 'options':
            print(f" ID |     Name        |              Value                        \n" +
                  f"====|=================|===========================================\n" +
                  f"  0 | Prefix          | {PREFIX}" +(42-len(PREFIX))*" "+         "\n" +
                  f"  1 | Postfix         | {POSTFIX}" +(42-len(POSTFIX))*" "+       "\n" +
                  f"  2 | ChangeCase      | {CHANGECASE}" +(42-len(str(CHANGECASE)))*" "+ "\n" +
                  f"  3 | SetCase         | {SETCASE}" +(42-len(SETCASE))*" "+       "\n" +
                  f"    |                 |                                           \n" +
                  f"  - | AlwaysChange    | This options can be viewed and            \n" +
                  f"  - | SometimesChange | edited only in configuration file         ")
        elif msg.startswith('set'):
            args = shlex.split(msg)

            if args[1] in ['0', 'prefix']:
                PREFIX = args[2]
            elif args[1] in ['1', 'postfix']:
                POSTFIX = args[2]
            elif args[1] in ['2', 'changecase']:
                if args[2] in ['0', 'false']:
                    CHANGECASE = False
                else:
                    CHANGECASE = True
            elif args[1] in ['3', 'setcase']:
                if args[2] in ['lower', 'upper', 'random']:
                    SETCASE = args[2]
                else:
                    print(f'SetCase can be only set to "upper", "lower" or "random"; given option: "{args[2]}"')
            write_config()
        elif msg.startswith('write'):
            args = shlex.split(msg)

            OUTPUTTOFILE = True
            OUTPUTFILENAME = args[1]
        elif msg == 'console':
            OUTPUTTOFILE = False
        elif msg == 'clearoutput':
            if os.path.isfile(OUTPUTFILENAME):
                open(OUTPUTFILENAME, 'w').close()
            else:
                print('Sorry, I can\'t clear something non-existing!')

        elif msg == "help":
            print(InteractiveHelpMessage)

        elif msg in ["exit", "quit"]:
            ... ### Do nothing

        elif msg.startswith("read"):
            args = shlex.split(msg)

            if os.path.isfile(args[1]):
                with open(args[1], 'r') as f:
                    flag = f.readline().replace('\n', '')
                    while flag:
                        output(flag)
                        flag = f.readline().replace('\n', '')
            else:
                print("Given path doesn't exist or isn't a file")
        else:
            output(msg)

if __name__ == '__main__':
    read_config()

    if len(sys.argv) == 1 or (len(sys.argv) == 2  and sys.argv[1].lower in ['-i', '--interactive']):
        interactive()
    elif len(sys.argv) == 2  and sys.argv[1].lower in ['-h', '--help']:
        print(HelpMessage)
    else:
        flags_from = 1
        repeat = 1

        read_from_file = False
        input_file_name = ''

        flags = ['-c', '--count', '-f', '--file', '-o', '--output', '-s', '--settings']

        while flags_from < len(sys.argv):
            if sys.argv[flags_from] in flags:
                if sys.argv[flags_from] in ['-c', '--count']:
                    count = sys.argv[flags_from + 1]

                    try:
                        repeat = int(count)
                    except:
                        raise ValueError(f'Error: exspected integer after -c flag; got {count}')

                elif sys.argv[flags_from] in ['-f', '--file']:
                    file = sys.argv[flags_from + 1]

                    if os.path.isfile(file):
                        read_from_file = True
                        input_file_name = file
                    else:
                        raise ValueError("Error: Path to input file doesn't exist or isn't a file")

                elif sys.argv[flags_from] in ['-o', '--output']:
                    OUTPUTTOFILE = True
                    OUTPUTFILENAME = sys.argv[flags_from + 1]
                    open(OUTPUTFILENAME, 'w').close()

                elif sys.argv[flags_from] in ['-s', '--settings']:
                    read_config(sys.argv[flags_from + 1])

                flags_from += 2
            else:
                break

        if read_from_file:
            with open(input_file_name, 'r') as f:
                flag = f.readline().replace('\n', '')
                while flag:
                    for i in range(repeat):
                        output(flag)

                    flag = f.readline().replace('\n', '')
        else:
            while flags_from < len(sys.argv):
                flag = sys.argv[flags_from]
                flags_from += 1

                for i in range(repeat):
                    output(flag)


import os
import sys

from flask import Flask, jsonify, request, abort, send_file, send_from_directory
from dotenv import load_dotenv
from linebot import LineBotApi, WebhookParser, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, ImageMessage, TextSendMessage, ImageSendMessage

from fsm import TocMachine
from utils import send_text_message

load_dotenv()

machine = TocMachine(
    states=["conscription", "soldier", "freedom", "exemption"],
    transitions=[
        {"trigger": "advance", "source": "conscription", "dest": "soldier", "conditions": "fulfill_obligations"},
        {"trigger": "advance", "source": "conscription", "dest": "freedom", "conditions": "not_passing_checkup"},
        {"trigger": "advance", "source": "soldier", "dest": "freedom", "conditions": "honorary_discharged"},
        {"trigger": "advance", "source": "soldier", "dest": "exemption", "conditions": "with_a_separation"},
        {"trigger": "advance", "source": "soldier", "dest": "=", "conditions": "some_basic_things",},
        {"trigger": "advance", "source": "exemption", "dest": "soldier", "conditions": "go_checkup_again",},
        {"trigger": "advance", "source": "exemption", "dest": "freedom", "conditions": "exempt_from_duty",},
        {"trigger": "advance", "source": "freedom", "dest": "conscription"}
                ],

    initial="conscription",
    auto_transitions=False,
    show_conditions=True,
    # show_auto_transitions=True
)

app = Flask(__name__, static_url_path="")

# get channel_secret and channel_access_token from your environment variable
channel_secret = os.getenv("LINE_CHANNEL_SECRET", None)
channel_access_token = os.getenv("LINE_CHANNEL_ACCESS_TOKEN", None)
if channel_secret is None:
    print("Specify LINE_CHANNEL_SECRET as environment variable.")
    sys.exit(1)
if channel_access_token is None:
    print("Specify LINE_CHANNEL_ACCESS_TOKEN as environment variable.")
    sys.exit(1)

line_bot_api = LineBotApi(channel_access_token)
parser = WebhookParser(channel_secret)
# handler = WebhookHandler(channel_secret)

@app.route("/callback", methods=["POST"])
def callback():
    signature = request.headers["X-Line-Signature"]
    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # parse webhook body
    try:
        events = parser.parse(body, signature)
    except InvalidSignatureError:
        abort(400)

    # if event is MessageEvent and message is TextMessage, then echo text
    for event in events:
        if not isinstance(event, MessageEvent):
            continue
        if not isinstance(event.message, TextMessage):
            continue
        response = machine.advance(event)
        if response == False:
            send_text_message(event.reply_token, "你在工蝦餃")
        # line_bot_api.reply_message( event.reply_token, TextSendMessage(text=event.message.text) )

    return "OK"

@app.route("/webhook", methods=["POST"])
def webhook_handler():
    signature = request.headers["X-Line-Signature"]
    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info(f"Request body: {body}")

    # parse webhook body
    try:
        events = parser.parse(body, signature)
    except InvalidSignatureError:
        abort(400)

    for event in events:
        if not isinstance(event, MessageEvent):
            continue
        if not isinstance(event.message, TextMessage):
            continue
        if not isinstance(event.message.text, str):
            continue
        print(f"\nFSM STATE: {machine.state}")
        print(f"REQUEST BODY: \n{body}")
        response = machine.advance(event)
        if response == False:
            send_text_message(event.reply_token, "Not Entering any State")

    return "OK"

# show fsm graph
@app.route("/show-fsm", methods=["GET"])
def show_fsm():
    machine.get_graph().draw("fsm.png", prog="dot", format="png")
    return send_file("fsm.png", mimetype="image/png")#, as_attachment=True)
    # return send_from_directory(".","fsm.png")

@app.route("/show-fsm", methods=['POST'])
def handle_image_message():
    signature = request.headers["X-Line-Signature"]
    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info(f"Request body: {body}")

    # parse webhook body
    try:
        events = parser.parse(body, signature)
    except InvalidSignatureError:
        abort(400)

    # for event in events:
    #     url = "https://i.imgur.com/rhIgq1g.png"
    #     line_bot_api.reply_message(event.reply_token, ImageSendMessage(url, url))
    #     return "OK"

if __name__ == "__main__":
    port = os.environ.get("PORT", 8000)
    app.run(host="0.0.0.0", port=port, debug=True)


from django.test import TestCase

from portal.forms import SignUpForm, PreferenceForm, PartnerForm
from portal.models import Hobby
from portal.tests.test_views import create_student_and_return

class SignUpFormTests(TestCase):
    @staticmethod
    def create_form(username=''):
        form_data = {'name': 'Name', 'username': username, 'gender': 'M', 'course': 'C', 'social_link': 'NA'}
        return SignUpForm(data=form_data)

    def test_empty_form_is_invalid(self):
        form = self.create_form()
        self.assertFalse(form.is_valid())

    def test_maximum_username_length(self):
        form = self.create_form('ab123415')
        self.assertFalse(form.is_valid())

        form = self.create_form('ab12315')
        self.assertTrue(form.is_valid())

class PreferenceFormTests(TestCase):
    @staticmethod
    def create_form(does_party=False, hobbies=None):
        form_data = {'party': does_party, 'hobbies': hobbies}
        return PreferenceForm(data=form_data)

    def test_empty_is_valid(self):
        form = self.create_form()
        self.assertTrue(form.is_valid())

    def test_maximum_5_hobbies(self):
        Hobby(description='A').save()
        Hobby(description='B').save()
        Hobby(description='C').save()
        Hobby(description='D').save()
        Hobby(description='E').save()

        form = self.create_form(False, Hobby.objects.all())
        self.assertTrue(form.is_valid())

        Hobby(description='F').save()

        form = self.create_form(False, Hobby.objects.all())
        self.assertFalse(form.is_valid())

class PartnerFormTests(TestCase):
    @staticmethod
    def create_form(instance=None, partner=None):
        if not partner:
            form_data = {}
        else:
            form_data = {'partner': partner.id}
        return PartnerForm(instance=instance, data=form_data)

    def setUp(self):
        self.student = create_student_and_return('A', child=False)

    def test_empty_form_is_valid(self):
        form = self.create_form(self.student)
        self.assertTrue(form.is_valid())

    def test_propose_to_someone_else_is_valid(self):
        new = create_student_and_return('B', child=False)
        form = self.create_form(self.student, new)
        self.assertTrue(form.is_valid())

    def test_student_cant_propose_to_self(self):
        form = self.create_form(self.student, self.student)
        self.assertFalse(form.is_valid())

    def test_cannot_propose_to_child(self):
        new = create_student_and_return('B', child=True)
        form = self.create_form(self.student, new)
        self.assertFalse(form.is_valid())

    def test_cannnot_propose_to_someone_married(self):
        new = create_student_and_return('B', child=False)
        new.confirmed = True
        new.save()
        form = self.create_form(self.student, new)
        self.assertFalse(form.is_valid())


import requests
import os

URL_BASE = "http://146.19.247.196"
token = str

def get_token_from_file() -> token:
    with open("TOKEN.txt", encoding="utf-8") as file:
        return file.read()

def get_or_create_token() -> token:
    if os.path.exists("TOKEN.txt"):
        return get_token_from_file()
    else:
        token = input("Введите ваш токен телеграм бота.\n")
        with open("TOKEN.txt", "w", encoding="utf-8") as file:
            file.write(token)
        return token

def check_access() -> bool:
    token = get_or_create_token()
    proj = "proj1"
    port = ":8000/"

    data = {'token_bot': token, 'project_name': proj}

    full_url = URL_BASE + port + "ask_access/"
    resp = requests.post(full_url, json=data)
    if resp.json()['status'] == "ok":
        return True
    else:
        return False

if __name__ == '__main__':
    has_access = check_access()


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

import os
import os.path
import shutil

from .defines import PAGE_ATTACH_DIR
from .exceptions import ReadonlyException
from .events import AttachListChangedParams

class Attachment(object):
    """
    Класс для работы с прикрепленными файлами
    """
    def __init__(self, page):
        """
        page - страница, для которой интересуют прикрепленные файлы
        """
        self.page = page

    def getAttachPath(self, create=False):
        """
        Возвращает путь до папки с прикрепленными файлами
        create - создать папку для прикрепленных файлов,
        если она еще не создана?
        """
        path = os.path.join(self.page.path, PAGE_ATTACH_DIR)

        if create and not os.path.exists(path):
            os.mkdir(path)

        return path

    @property
    def attachmentFull(self):
        """
        Возвращает список прикрепленных файлов.
        Пути до файлов полные
        """
        path = self.getAttachPath()
        return [os.path.join(path, fname)
                for fname in self.getAttachRelative()]

    def getAttachRelative(self, dirname="."):
        """
        Возвращает список прикрепленных файлов
        (только имена файлов без путей относительно директории dirname).
        dirname - поддиректория в PAGE_ATTACH_DIR,
        где хотим получить список файлов
        """
        path = self.getAttachPath()

        if not os.path.exists(path):
            return []

        fullpath = os.path.join(path, dirname)

        return os.listdir(fullpath)

    def attach(self, files):
        """
        Прикрепить файлы к странице
        files -- список файлов (или папок), которые надо прикрепить
        """
        if self.page.readonly:
            raise ReadonlyException

        attachPath = self.getAttachPath(True)

        for name in files:
            if os.path.isdir(name):
                basename = os.path.basename(name)
                shutil.copytree(name, os.path.join(attachPath, basename))
            else:
                shutil.copy(name, attachPath)

        self.page.updateDateTime()
        self.page.root.onAttachListChanged(self.page,
                                           AttachListChangedParams())

    def removeAttach(self, files):
        """
        Удалить прикрепленные файлы
        files - список имен файлов (путей относительно папки PAGE_ATTACH_DIR)
        """
        if self.page.readonly:
            raise ReadonlyException

        attachPath = self.getAttachPath(True)

        for fname in files:
            path = os.path.join(attachPath, fname)
            try:
                if os.path.isdir(path):
                    shutil.rmtree(path)
                else:
                    os.remove(path)
            except OSError:
                self.page.root.onAttachListChanged(self.page,
                                                   AttachListChangedParams())
                raise IOError(u"Can't remove %s" % fname)

        self.page.updateDateTime()
        self.page.root.onAttachListChanged(self.page,
                                           AttachListChangedParams())

    @staticmethod
    def sortByName(fname):
        """
        Deprecated. Please use kye=str.lower instead.

        Метод для сортировки файлов по имени
        Key stile method to sort files by name.

        Args:
            fname: path to the file.
        Returns:
            fname.lower()
        """
        return fname.lower()

    @staticmethod
    def sortByType(fname):
        NOT_EXISTS = 0
        IS_FILE = 1
        IS_DIR = 2

        if not os.path.exists(fname):
            return NOT_EXISTS
        if os.path.isdir(fname):
            return IS_DIR

        return IS_FILE

    @staticmethod
    def sortByExt(fname):
        """
        Метод для сортировки файлов по расширению
        Key stile method to sort files by extension.
        If the extension is equivalent for 2 files they will be sorted by name.

        Args:
            fname: path to the file.
        Returns:
            (file_ext, file_name)
        """
        name, ext = os.path.splitext(os.path.basename(fname).lower())

        return ext, name

    @staticmethod
    def sortByDate(full_file_path):
        """
        Метод для сортировки файлов по дате последней модификации.
        Key stile method to sort files by last modified date.
        If the date is equivalent for 2 files they will be sorted by name.

        Args:
            full_file_path: full path to the existing file.
        Returns:
            (os.stat().st_mtimem, full_file_path.lower())
        """
        stat = os.stat(full_file_path)

        return stat.st_mtime, full_file_path.lower()

    @staticmethod
    def sortBySize(full_file_path):
        """
        Метод для сортировки файлов по размеру файла.
        Key stile method to sort files by file size.
        If the size is equivalent for 2 files they will be sorted by name.

        Args:
            full_file_path: full path to the existing file.
        Returns:
            (os.stat().st_mtimem, full_file_path.lower())
        """
        stat = os.stat(full_file_path)

        return stat.st_size, full_file_path.lower()

    def sortBySizeRelative(self, relative_file_path):
        """
        Метод для сортировки файлов по размеру файла.
        Key stile method to sort files by file size.
        If the size is equivalent for 2 files they will be sorted by name.

        Args:
            relative_file_path: relative path to the file.
        Returns:
            (os.stat().st_mtimem, relative_file_path.lower())
        """
        stat = os.stat(self.getFullPath(relative_file_path))

        return stat.st_size, relative_file_path.lower()

    def sortByDateRelative(self, relative_file_path):
        """
        Метод для сортировки файлов по дате.
        Key stile method to sort files by last modified date.
        If the date is equivalent for 2 files they will be sorted by name.

        Args:
            relative_file_path: relative path to the file.
        Returns:
            (os.stat().st_mtimem, relative_file_path.lower())
        """
        stat = os.stat(self.getFullPath(relative_file_path))

        return stat.st_mtime, relative_file_path.lower()

    def getFullPath(self, fname, create=False):
        """
        Возвращает полный путь до прикрепленного файла с именем fname.
        Файл fname не обязательно должен существовать.
        create - нужно ли создавать папку PAGE_ATTACH_DIR,
        если ее еще не существует?
        """
        return os.path.join(self.getAttachPath(create), fname)


import zlib
import logging

logger = logging.getLogger('dev')

class CorruptedMessage(ValueError):
    pass

class UdpcpMessageHeader(object):
    """
    """
    checksum = 0x02aa0055   # 4B       - it will be updated in init so no worry
    messageType = 0b01      # 2b # 5B  - 01 for data, 10 for ack
    version = 0b010         # 3b
    noAck = False           # 1b       - no ack on any message
    useChecksum = True      # 1b       - if 0 'checksum' must be 0
    singleAck = True        # 1b       - ack only on last part
    duplicate = False       # 1b # 6B  - 0
    reserved = 0b0000000    # 7b       - must be 0..
    fragmentAmount = 0x01   # 1B # 7B  - 0 or 1 for not fragmented messages
    fragmentNumber = 0x00   # 1B # 8B  - 0 for first element
    messageId = 0x0000      # 2B # 10B - unique, used to complete fragmented messages,
    #                                    start with 0 for sync message
    dataLength = 0x0000     # 2B # 12B - length of data in octets

    def __init__(self, raw_data=None):
        """
        Creation of header from either binary data (raw_data) or with default
        values.
        """
        if raw_data is None:
            return
        data = [int(x.encode('hex'), 16) for x in raw_data[:12]]
        self.checksum = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]
        self.messageType = data[4] >> 6
        self.version = (data[4] >> 3) % 0b1000
        self.noAck = bool((data[4] >> 2) % 2)
        self.useChecksum = bool((data[4] >> 1) % 2)
        self.singleAck = bool(data[4] % 2)
        self.duplicate = bool((data[5] >> 7) % 2)
        self.fragmentAmount = data[6]
        self.fragmentNumber = data[7]
        self.messageId = (data[8] << 8) + data[9]
        self.dataLength = (data[10] << 8) + data[11]

    def calculate_checksum_for_data(self, data):
        """
        Calculate checksum for data.
        """
        cs = zlib.adler32(buffer(data))
        if cs % 0xffffffff != cs:
            cs = (cs % 0xffffffff) + 1
        return cs

    def to_bytes(self):
        """
        Create byte array from header.
        """
        tmp = []
        tmp += [self.checksum >> 24, (self.checksum >> 16) & 0xff, (self.checksum >> 8) & 0xff, self.checksum & 0xff]
        tmp.append((self.messageType << 6) + (self.version << 3) +
                   (int(self.noAck) << 2) + (int(self.useChecksum) << 1) +
                   int(self.singleAck))
        tmp.append((int(self.duplicate) << 7) + self.reserved)
        tmp.append(self.fragmentAmount)
        tmp.append(self.fragmentNumber)
        tmp += [self.messageId >> 8, self.messageId & 0xff]
        tmp += [self.dataLength >> 8, self.dataLength & 0xff]

        return bytearray(tmp)

    def __repr__(self):
        """
        __repr__ for message header
        """
        return ("UDPCP message header:\n"
                "\tchecksum: {m.checksum:#x}\n"
                "\tmessageType: {m.messageType:#b}\n"
                "\tversion: {m.version:#b}\n"
                "\tnoAck: {m.noAck}\n"
                "\tuseChecksum: {m.useChecksum}\n"
                "\tsingleAck: {m.singleAck}\n"
                "\tduplicate: {m.duplicate}\n"
                "\tfragmentAmount: {m.fragmentAmount:#x}\n"
                "\tfragmentNumber: {m.fragmentNumber:#x}\n"
                "\tmessageId: {m.messageId:#x}\n"
                "\tdataLength: {m.dataLength:#x}").format(m=self)

class UdpcpMessage(object):
    payload = None

    def __init__(self, data=None, payload=None, validate=True):
        """
        To create message from data received from socket -- use 'data'.
        To create new message with specified payload -- use 'payload'.
        If 'validate' is False checksum will not be checked when creating message
        from socket data.
        """
        if payload is not None and data is not None:
            raise Exception("UDPCP message should not be created with both "
                            "binnary data and payload.")
        self.header = UdpcpMessageHeader(data)
        if data is not None:
            self.init_from_data(data, validate)

        if payload is not None:
            self.payload = payload
            self.header.dataLength = len(payload)
            self.update_checksum()

    def init_from_data(self, data, validate):
        """
        Initialize payload from binary data. Check if message is not corrupted.
        """
        if len(data) > 12:
            self.payload = str(data[12:])

        cs = self.header.checksum
        self.update_checksum()
        if validate and self.header.useChecksum and abs(cs - self.header.checksum) > 1:
            logger.error('Corrupted UDPCP message received')
            raise CorruptedMessage("Checksum error.")

    @classmethod
    def calculate_checksum_for_data(cls, data):
        """
        Calculate checksum for provided data.
        """
        cs = zlib.adler32(buffer(data))
        if cs % 0xffffffff != cs:
            cs = (cs % 0xffffffff) + 1
        return cs

    def to_bytes(self):
        """
        Create byte representation of the message.
        """
        if self.payload:
            return self.header.to_bytes() + bytearray(self.payload)
        return self.header.to_bytes()

    def set_checksum(self, value):
        """
        Set checksum to defined value.
        """
        self.header.checksum = value

    def update_checksum(self):
        """
        Recalculate checksum for message.
        """
        self.header.checksum = 0
        if not self.header.useChecksum:
            return
        self.header.checksum = self.calculate_checksum_for_data(self.to_bytes())

    def create_ack(self, duplicate):
        """
        Create new UDPCP ack-message (response to this message).
        """
        m = UdpcpMessage()
        m.header.messageType = 0b10
        m.header.noAck = True
        m.header.singleAck = True
        m.header.messageId = self.header.messageId
        m.header.duplicate = duplicate
        m.header.fragmentNumber = self.header.fragmentNumber
        m.header.fragmentAmount = self.header.fragmentAmount
        m.update_checksum()
        return m

    def __repr__(self):
        """Print for UDPCP Message"""
        return '\nPayload:\n\t'.join([self.header.__repr__(), self.payload.__repr__()])


import pickle
from utils import yaml_load

def get_numpy_word_embed():
    row = 0

    config = yaml_load("config.yaml")
    model_cfg = config.get("model", {})
    data_cfg = config.get("data", {})
    glove_path = model_cfg["glove_path"]
    glove_length = model_cfg["glove_length"]
    vocab_file = data_cfg["vocab_file"]

    words_embed = {}
    with open(glove_path, mode='r')as f:
        lines = f.readlines()
        for line in lines:
            line_list = line.split()
            word = line_list[0]
            embed = line_list[1:]
            embed = [float(num) for num in embed]
            words_embed[word] = embed
            if row > 20000:
                break
            row += 1

    word2idx = {}
    with open(vocab_file, 'rb') as handle:
        word2idx = pickle.load(handle)
    idx2word = {idx: w for w, idx in word2idx.items()}
    id2emb = {}
    id2emb[0] = [0.0] * glove_length
    for (_, idx) in word2idx.items():
        if idx2word[idx] in words_embed:
            id2emb[idx] = words_embed[idx2word[idx]]
        else:
            id2emb[idx] = [0.0] * glove_length
    data = [id2emb[idx] for idx in range(len(word2idx) + 1)]

    return data


from fastapi import FastAPI
from pydantic import BaseModel
# input으로 List를 받기 위한 import.
from typing import List
from app.load_distance_matrix import load_distance_matrix
from app.floyd_warshall import floyd_warshall_initialize
from app.held_karp import held_karp
from app.two_opt import local_search_2_opt
from app.util import distance_calc
from app.make_distance_matrix import make_distance_matrix

from copy import deepcopy

import numpy as np

class Locations(BaseModel):
    locations: List[int]

# INF 상수는 연결되어있지 않음을 의미.
INF = 10**5

# distance matrix 초기화.
DISTANCE_MATRIX = make_distance_matrix(INF)

# 총 vertex 개수.
V = len(DISTANCE_MATRIX)

# DISTANCE_MATRIX 확인.
# print("DISTANCE_MATRIX")
# print(DISTANCE_MATRIX)

# distance matrix와 floyd-warshall을 이용하여,
# a -> b로의 최단 거리와, 이동 경로 저장.
# 모든 점으로부터 모든 점으로까지 최단거리
SHORTEST_DISTANCES, SHORTEST_PATHS = floyd_warshall_initialize(DISTANCE_MATRIX,INF)

# SHORTEST_DISTANCES, SHORTEST_PATHS 확인.
# print("SHORTEST_DISTANCES")
# print(SHORTEST_DISTANCES)
# print("SHORTEST_PATHS")
# print(SHORTEST_PATHS)

app = FastAPI()

@app.post("/shortest-path")
def find_shortest_path(locations: Locations):
    # 방문할 위치들 입력 확인.
    print("locations")
    print(locations.locations)

    # 시작점과 끝점을 추가해서 TSP를 적용할 list 만들기.
    visit_list = deepcopy(locations.locations)
    # 원래는 0번 카운터에서 시작했지만, 중간에서도 시작하기 위해 입력 리스트의 첫번째 원소를 시작위치로.
    start_location = locations.locations[0]
    # visit_list.insert(0,0)
    visit_list.append(V-1)

    # TSP 알고리즘을 적용하기 위해, 방문하는 위치들만으로 완전그래프(complete graph) 만들기.
    # complete matrix 만들기.
    l = len(visit_list)
    complete_graph = [[-1 for i in range(l)] for i in range(l)]
    for r in range(l):
        for c in range(l):
            complete_graph[r][c]=SHORTEST_DISTANCES[visit_list[r]][visit_list[c]]

    # 방문해야할 장소 개수가 15이하일 때는 exact algorithm인 held-karp algorithm 적용.
    #           "          15이상일 때는 heuristic algorithm인 2-opt algorithm 적용.
    # 최단거리, 최단경로 초기화.
    shortest_distance = -1
    temp_path = []
    if l <= 14:
        shortest_distance, temp_path = held_karp(complete_graph,INF)
    else:
        # 입력 형태를 맞추기 위해, distance matrix인 complete_graph를 numpy array로 변환해줌.
        complete_graph_np_array = np.array(complete_graph)

        # seed 초기화. seed[0]는 경로를, seed[1]은 거리를 의미.
        seed=[[],[]]

        # path 초기화는 숫자가 낮은 순서로 방문.
        seed[0]=[ i for i in range(len(complete_graph_np_array))]
        seed[1] = distance_calc(complete_graph_np_array,seed)

        temp_path,shortest_distance = local_search_2_opt(complete_graph_np_array,seed,-1,True)

    # 실제 경로로 변환해주기.
    # paths를 보고, 경로 알려주기.
    real_path = [start_location]
    path_len = len(temp_path)
    for i in range(path_len-1):
        real_path.extend(SHORTEST_PATHS[visit_list[temp_path[i]]][visit_list[temp_path[i+1]]][1:])

    # 디버깅.
    # 최단 경로
    print("real_path")
    print(real_path)

    # 최단 거리 출력해보기.
    print("shortest_distance")
    print(shortest_distance)

    return {"path":real_path}


'''Plot schematic illustrating forward pass.

Author: guangzhi XU (xugzhi1987@gmail.com)
Update time: 2021-05-17 14:00:46.
'''

from __future__ import print_function
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

#-------------Main---------------------------------
if __name__=='__main__':

    g = nx.DiGraph()

    # nodes: (l, i), use l as x-coor, i as y-coor
    x0 = 0
    xl = 2
    xl1 = 5
    layer0 = [(x0, 0), (x0, 2), (x0, 7), (x0, 9)]
    layeri = [(xl, 0), (xl, 5), (xl, 9)]
    layeri1 = [(xl1, 0), (xl1, 5), (xl1, 9)]

    layers = [layer0, layeri, layeri1]
    pos = {}

    # add nodes
    for lii in layers:
        g.add_nodes_from(lii)
        pos.update(dict(zip(lii, lii)))

    # add bias
    bias = (3.5, 11)
    g.add_node(bias)
    pos[bias] = bias

    # add links
    g.add_edge(layeri[1], layeri1[1])
    g.add_edge(bias, layeri1[1])

    # plot nodes
    fig = plt.figure(figsize=(12,12))
    ax = fig.add_subplot(111)
    nx.draw(g, pos=pos, ax=ax, node_size=2800, with_labels=False,
            node_color='c', alpha=0.7)

    import matplotlib.patches as patches
    rect = patches.Rectangle((x0-0.5, -0.9), 1.0, 10.9, facecolor='y', alpha=0.2)
    ax.add_patch(rect)
    rect = patches.Rectangle((xl-0.5, -0.9), 1.0, 10.9, facecolor='y', alpha=0.2)
    ax.add_patch(rect)
    rect = patches.Rectangle((xl1-0.5, -0.9), 1.0, 10.9, facecolor='y', alpha=0.2)
    ax.add_patch(rect)

    # add activation
    ax.arrow(xl1+0.2, 5, 1, 0, head_width=0.05, head_length=0.1)

    # add ellipses
    fontsize=28
    ax.text(x0, 4.5, r'$\vdots$', fontsize=fontsize, va='center', ha='center')
    ax.text(xl, 2.5, r'$\vdots$', fontsize=fontsize, va='center', ha='center')
    ax.text(xl, 7, r'$\vdots$', fontsize=fontsize, va='center', ha='center')
    ax.text(xl1, 2.5, r'$\vdots$', fontsize=fontsize, va='center', ha='center')
    ax.text(xl1, 7, r'$\vdots$', fontsize=fontsize, va='center', ha='center')

    # label layers
    fontsize=14
    ax.text(x0, -1.2, 'l = 0', fontsize=fontsize, va='center', ha='center', fontname='serif')
    ax.text(xl, -1.2, 'l = l', fontsize=fontsize, va='center', ha='center', fontname='serif')
    ax.text(xl1, -1.2, 'l = l+1', fontsize=fontsize, va='center', ha='center', fontname='serif')

    # label neurons
    fontsize=16
    ax.text(xl, 5, 'i', fontsize=fontsize, va='center', ha='center')
    ax.text(xl1, 5, 'j', fontsize=fontsize, va='center', ha='center')
    ax.text(bias[0], bias[1], 'bias', fontsize=fontsize, va='center', ha='center')
    ax.text(xl, 9, r'$0$', fontsize=fontsize, va='center', ha='center')
    ax.text(xl1, 9, r'$0$', fontsize=fontsize, va='center', ha='center')
    ax.text(xl, 0, r'$s_{l}-1$', fontsize=fontsize-3, va='center', ha='center')
    ax.text(xl1, 0, r'$s_{l+1}-1$', fontsize=fontsize-3, va='center', ha='center')

    # equation
    fontsize=16
    ax.text(0.5*(xl + xl1), 5.3, r'$ a_{i}^{(l)} \cdot \theta_{j,i}^{(l+1)}$',
            fontsize=fontsize, va='bottom', ha='center', bbox=dict(facecolor='g', alpha=0.3))
    ax.text(0.5*(bias[0] + xl1)-0.6, 0.5*(bias[1] + 5),
            r'$b_{j}^{(l+1)}$',
            fontsize=fontsize, va='bottom', ha='center', bbox=dict(facecolor='g', alpha=0.3))
    ax.text(xl1+1.4, 5.3, r'$a_{j}^{(l+1)} = g(z_{j}^{(l+1)})$',
            fontsize=fontsize, va='bottom', ha='center', bbox=dict(facecolor='g', alpha=0.3))

    ax.set_xlim(-2, 7)
    ax.set_ylim(-3, 12)

    plot_save_name='schematic_nn_forward.png'
    print('\n# <plot_schematic>: Save figure to', plot_save_name)
    fig.savefig(plot_save_name,dpi=100,bbox_inches='tight')

    fig.show()


from random import shuffle

# Import from itools
from itools.core import merge_dicts
from itools.gettext import MSG
from itools.log import log_warning
from itools.xapian import OrQuery, AndQuery, PhraseQuery, NotQuery

# Import from ikaaro
from ikaaro.folder_views import GoToSpecificDocument
from ikaaro.future.order import ResourcesOrderedTable
from ikaaro.future.order import ResourcesOrderedTableFile
from ikaaro.registry import register_resource_class

# Import from shop
from cross_selling_views import AddProduct_View
from cross_selling_views import CrossSelling_Configure, CrossSelling_TableView
from cross_selling_views import CrossSelling_Edit, cross_selling_schema
from utils import get_group_name, get_shop
from forms import ProductSelectorWidget
from products import Product

class CrossSellingTable(ResourcesOrderedTable):

    class_id = 'CrossSellingTable'
    class_title = MSG(u'Cross-Selling Table')
    class_description = MSG(u'This box allow to configure cross selling')
    class_handler = ResourcesOrderedTableFile
    class_version = '20100928'
    class_views = ['configure', 'back']

    form = [ProductSelectorWidget('name', title=MSG(u'Product'))]

    orderable_classes = Product

    # Views
    configure = CrossSelling_Configure()
    edit = CrossSelling_Edit()
    view_table = CrossSelling_TableView()
    add_product = AddProduct_View() # (XXX used by product selector widget)
    back = GoToSpecificDocument(specific_document='..',
                                title=MSG(u'See product'))

    @classmethod
    def get_metadata_schema(cls):
        return merge_dicts(ResourcesOrderedTable.get_metadata_schema(),
                           cross_selling_schema)

    def get_order_root(self):
        return self

    def get_products(self, context, product_format,
                     categories=[], excluded_products=[]):
        shop = get_shop(self)
        table = self
        if self.get_property('use_shop_configuration'):
            table = shop.get_resource('cross-selling')
        if table.get_property('enabled') is False:
            return

        root = context.root
        products_quantity = table.get_property('products_quantity')

        # Base query
        query = [PhraseQuery('format', product_format),
                 PhraseQuery('workflow_state', 'public')]
        # Do not show now buyable products
        group_name = get_group_name(shop, context)
        q = PhraseQuery('not_buyable_by_groups', group_name)
        query.append(NotQuery(q))
        # Excluded products query
        if excluded_products:
            exclude_query = [ PhraseQuery('abspath', str(abspath))
                              for abspath in excluded_products ]
            if len(exclude_query) > 1:
                exclude_query = OrQuery(*exclude_query)
            else:
                exclude_query = exclude_query[0]
            query.append(NotQuery(exclude_query))
        # Filter on product title
        filter_text = table.get_property('filter_text')
        if filter_text:
            query.append(PhraseQuery('title', filter_text))
        # Categories query
        mode_categories = table.get_property('categories')
        if mode_categories == 'current_category':
            query_categorie = [ PhraseQuery('parent_paths', str(x.get_abspath()))
                                for x in categories ]
            if len(query_categorie) > 1:
                query.append(OrQuery(*query_categorie))
            elif len(query_categorie) == 1:
                query.append(query_categorie[0])
        elif mode_categories == 'one_category':
            query.append(PhraseQuery('parent_paths',
                                     table.get_property('specific_category')))
        # Show reductions ?
        promotion = table.get_property('show_product_with_promotion')
        if promotion in ('0', '1'):
            query.append(PhraseQuery('has_reduction', bool(promotion)))

        # Product model
        product_model = table.get_property('product_model')
        if product_model:
            query.append(PhraseQuery('product_model', product_model))
        # Tags
        if table.get_property('tags'):
            query.append(
                OrQuery(*[PhraseQuery('tags', x)
                        for x in table.get_property('tags')]))

        # Selection in cross selling table
        handler = table.handler
        get_value = handler.get_record_value
        ids = list(handler.get_record_ids_in_order())
        names = []
        for id in ids[:products_quantity]:
            record = handler.get_record(id)
            path = get_value(record, 'name')
            names.append(path)
            products_quantity -= 1
            resource = self.get_resource(path, soft=True)
            if resource is None:
                log_warning('Error cross selling, %s' % path)
            elif resource.get_property('state') == 'public':
                yield resource

        if products_quantity <= 0:
            return

        if names:
            names_query = [ PhraseQuery('name', name) for name in names ]
            if len(names_query) > 1:
                names_query = OrQuery(*names_query)
            else:
                names_query = names_query[0]
            query.append(NotQuery(names_query))

        # Complete results
        sort = table.get_property('sort')
        if sort == 'random':
            # Random selection
            results = root.search(AndQuery(*query))
            # XXX It's not relevant to make a random cross selling
            # with more than 1000 products
            brains = list(results.get_documents(size=1000))
            shuffle(brains)
            for brain in brains[:products_quantity]:
                yield root.get_resource(brain.abspath)
        elif sort == 'last':
            results = root.search(AndQuery(*query))
            brains = list(results.get_documents(sort_by='ctime',
                            reverse=True, size=products_quantity))
            for brain in brains:
                yield root.get_resource(brain.abspath)

register_resource_class(CrossSellingTable)


# import globals
from threading import Lock
from flask import Flask, render_template, session, request, copy_current_request_context
from flask_socketio import SocketIO, emit

# import our own code
from app_config import *
from networks import *
from models import *
from db import *
from freqs import *

# set up app
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)
thread = None
thread_lock = Lock()

# logger
def log(x):
		print(x)
		emit('status','(server) '+x)

id2M={}

@app.route('/')
def analyze_word():
		return render_template('word.html',DEFAULT_WORD_STR=DEFAULT_WORD_STR,W2V_MODELS=W2V_MODELS)

@app.route('/about')
def index():
	return render_template('about.html')

@app.route('/corpus_coha')
def corpus_coha():
	return render_template('corpus_coha.html')

@app.route('/manifestos')
def manifestos():
		return render_template('manifestos.html')

@app.route('/manifestos_feb22')
def manifestos_feb22():
		return render_template('manifestos_feb22.html')

def get_model(opts):
	global id2M

	Mid=opts['model_id']
	if Mid in id2M:
		model = id2M[Mid]
	else:
		model = id2M[Mid] = Embedding(id=Mid,fn=opts['model_fn'],periods=opts['model_periods'])
	return model

@socketio.on('mostsimnet')
def mostsimnet(opts):
	msg='mostsimnet'
	log('starting '+msg+'()')
	print('mostsimnet_opts: ',opts)

	log('getting model')
	model=get_model(opts)

	log('getting sim data')
	try:
		n_top = int(opts['n_top'])
	except ValueError:
		n_top = DEFAULT_N_TOP

	most_similar_data = model.get_most_similar(words=opts['words'],n_top=n_top,periods=opts['periods'],combine_periods=opts['combine_periods'])

	log('making network')
	networks_data = sims2net(most_similar_data,combine_periods=opts['combine_periods'])

	emit(msg+'_resp', {'data':networks_data})

@socketio.on('get_freqs')
def get_freqs(opts):
	msg='get_freqs'
	log('starting '+msg+'()')
	print(msg+'_opts: ',opts)

	words=deperiodize_l(opts['words'])
	log('getting freqs for %s' % ', '.join(words))

	#hdf_fn = W2V_MODELS[opts['model_id']]['fn_freqs']
	#log('using hdf data stored in: '+hdf_fn)
	model_opts = W2V_MODELS[opts['model_id']]

	DATA=[]
	for word in words:
		df_freqs = get_df_freqs(word, model_opts)
		print('get_freqs received:', df_freqs)
		if df_freqs is None: continue
		data_ld = df_freqs.to_dict('records')
		DATA+=[(word,data_ld)]

	emit(msg+'_resp', DATA)

if __name__ == '__main__':
	# app.run(debug=True)
	import sys
	print(sys.argv)
	port=1799
	if len(sys.argv)>1:
		port=int(sys.argv[-1])
	print(' * Starting server on port',port)
	socketio.run(app, debug=True, port=port,host='0.0.0.0')


from google.net.proto import ProtocolBuffer
import abc
import array
import base64
try:
  from thread import allocate_lock as _Lock
except ImportError:
  from threading import Lock as _Lock
try:
  from google3.net.proto import _net_proto___parse__python
except ImportError:
  _net_proto___parse__python = None
import sys
try:
  __import__('google.net.rpc.python.proto_python_api_1_stub')
  __import__('google.net.rpc.python.pywraprpc')
  proto_python_api_1_stub = sys.modules.get('google.net.rpc.python.proto_python_api_1_stub')
  pywraprpc = sys.modules.get('google.net.rpc.python.pywraprpc')
  _client_stub_base_class = proto_python_api_1_stub.Stub
except ImportError:
  _client_stub_base_class = object
try:
  __import__('google.net.rpc.python.rpcserver')
  rpcserver = sys.modules.get('google.net.rpc.python.rpcserver')
  _server_stub_base_class = rpcserver.BaseRpcServer
except ImportError:
  _server_stub_base_class = object

if hasattr(__builtins__, 'xrange'): range = xrange

if hasattr(ProtocolBuffer, 'ExtendableProtocolMessage'):
  _extension_runtime = True
  _ExtendableProtocolMessage = ProtocolBuffer.ExtendableProtocolMessage
else:
  _extension_runtime = False
  _ExtendableProtocolMessage = ProtocolBuffer.ProtocolMessage

from google.appengine.api.api_base_pb import *
import google.appengine.api.api_base_pb
google_dot_apphosting_dot_api_dot_api__base__pb = __import__('google.appengine.api.api_base_pb', {}, {}, [''])
class StoreBlobRequest(ProtocolBuffer.ProtocolMessage):
  has_blob_key_ = 0
  blob_key_ = ""
  has_content_ = 0
  content_ = ""

  def __init__(self, contents=None):
    if contents is not None: self.MergeFromString(contents)

  def blob_key(self): return self.blob_key_

  def set_blob_key(self, x):
    self.has_blob_key_ = 1
    self.blob_key_ = x

  def clear_blob_key(self):
    if self.has_blob_key_:
      self.has_blob_key_ = 0
      self.blob_key_ = ""

  def has_blob_key(self): return self.has_blob_key_

  def content(self): return self.content_

  def set_content(self, x):
    self.has_content_ = 1
    self.content_ = x

  def clear_content(self):
    if self.has_content_:
      self.has_content_ = 0
      self.content_ = ""

  def has_content(self): return self.has_content_

  def MergeFrom(self, x):
    assert x is not self
    if (x.has_blob_key()): self.set_blob_key(x.blob_key())
    if (x.has_content()): self.set_content(x.content())

  if _net_proto___parse__python is not None:
    def _CMergeFromString(self, s):
      _net_proto___parse__python.MergeFromString(self, 'apphosting.StoreBlobRequest', s)

  if _net_proto___parse__python is not None:
    def _CEncode(self):
      return _net_proto___parse__python.Encode(self, 'apphosting.StoreBlobRequest')

  if _net_proto___parse__python is not None:
    def _CEncodePartial(self):
      return _net_proto___parse__python.EncodePartial(self, 'apphosting.StoreBlobRequest')

  if _net_proto___parse__python is not None:
    def _CToASCII(self, output_format):
      return _net_proto___parse__python.ToASCII(self, 'apphosting.StoreBlobRequest', output_format)

  if _net_proto___parse__python is not None:
    def ParseASCII(self, s):
      _net_proto___parse__python.ParseASCII(self, 'apphosting.StoreBlobRequest', s)

  if _net_proto___parse__python is not None:
    def ParseASCIIIgnoreUnknown(self, s):
      _net_proto___parse__python.ParseASCIIIgnoreUnknown(self, 'apphosting.StoreBlobRequest', s)

  def Equals(self, x):
    if x is self: return 1
    if self.has_blob_key_ != x.has_blob_key_: return 0
    if self.has_blob_key_ and self.blob_key_ != x.blob_key_: return 0
    if self.has_content_ != x.has_content_: return 0
    if self.has_content_ and self.content_ != x.content_: return 0
    return 1

  def IsInitialized(self, debug_strs=None):
    initialized = 1
    if (not self.has_blob_key_):
      initialized = 0
      if debug_strs is not None:
        debug_strs.append('Required field: blob_key not set.')
    return initialized

  def ByteSize(self):
    n = 0
    n += self.lengthString(len(self.blob_key_))
    if (self.has_content_): n += 1 + self.lengthString(len(self.content_))
    return n + 1

  def ByteSizePartial(self):
    n = 0
    if (self.has_blob_key_):
      n += 1
      n += self.lengthString(len(self.blob_key_))
    if (self.has_content_): n += 1 + self.lengthString(len(self.content_))
    return n

  def Clear(self):
    self.clear_blob_key()
    self.clear_content()

  def OutputUnchecked(self, out):
    out.putVarInt32(10)
    out.putPrefixedString(self.blob_key_)
    if (self.has_content_):
      out.putVarInt32(18)
      out.putPrefixedString(self.content_)

  def OutputPartial(self, out):
    if (self.has_blob_key_):
      out.putVarInt32(10)
      out.putPrefixedString(self.blob_key_)
    if (self.has_content_):
      out.putVarInt32(18)
      out.putPrefixedString(self.content_)

  def TryMerge(self, d):
    while d.avail() > 0:
      tt = d.getVarInt32()
      if tt == 10:
        self.set_blob_key(d.getPrefixedString())
        continue
      if tt == 18:
        self.set_content(d.getPrefixedString())
        continue

      if (tt == 0): raise ProtocolBuffer.ProtocolBufferDecodeError()
      d.skipData(tt)

  def __str__(self, prefix="", printElemNumber=0):
    res=""
    if self.has_blob_key_: res+=prefix+("blob_key: %s\n" % self.DebugFormatString(self.blob_key_))
    if self.has_content_: res+=prefix+("content: %s\n" % self.DebugFormatString(self.content_))
    return res

  def _BuildTagLookupTable(sparse, maxtag, default=None):
    return tuple([sparse.get(i, default) for i in range(0, 1+maxtag)])

  kblob_key = 1
  kcontent = 2

  _TEXT = _BuildTagLookupTable({
    0: "ErrorCode",
    1: "blob_key",
    2: "content",
  }, 2)

  _TYPES = _BuildTagLookupTable({
    0: ProtocolBuffer.Encoder.NUMERIC,
    1: ProtocolBuffer.Encoder.STRING,
    2: ProtocolBuffer.Encoder.STRING,
  }, 2, ProtocolBuffer.Encoder.MAX_TYPE)

  _STYLE = """"""
  _STYLE_CONTENT_TYPE = """"""
  _PROTO_DESCRIPTOR_NAME = 'apphosting.StoreBlobRequest'
  _SERIALIZED_DESCRIPTOR = array.array('B')
  _SERIALIZED_DESCRIPTOR.fromstring(base64.decodestring("WjVhcHBob3N0aW5nL2FwaS9ibG9ic3RvcmUvYmxvYnN0b3JlX3N0dWJfc2VydmljZS5wcm90bwobYXBwaG9zdGluZy5TdG9yZUJsb2JSZXF1ZXN0ExoIYmxvYl9rZXkgASgCMAk4AhQTGgdjb250ZW50IAIoAjAJOAEUugGgBAo1YXBwaG9zdGluZy9hcGkvYmxvYnN0b3JlL2Jsb2JzdG9yZV9zdHViX3NlcnZpY2UucHJvdG8SCmFwcGhvc3RpbmcaHWFwcGhvc3RpbmcvYXBpL2FwaV9iYXNlLnByb3RvIjUKEFN0b3JlQmxvYlJlcXVlc3QSEAoIYmxvYl9rZXkYASACKAkSDwoHY29udGVudBgCIAEoDCKJAQoZU2V0QmxvYlN0b3JhZ2VUeXBlUmVxdWVzdBJHCgxzdG9yYWdlX3R5cGUYASACKA4yMS5hcHBob3N0aW5nLlNldEJsb2JTdG9yYWdlVHlwZVJlcXVlc3QuU3RvcmFnZVR5cGUiIwoLU3RvcmFnZVR5cGUSCgoGTUVNT1JZEAASCAoERklMRRABMroBChRCbG9ic3RvcmVTdHViU2VydmljZRJHCglTdG9yZUJsb2ISHC5hcHBob3N0aW5nLlN0b3JlQmxvYlJlcXVlc3QaGi5hcHBob3N0aW5nLmJhc2UuVm9pZFByb3RvIgASWQoSU2V0QmxvYlN0b3JhZ2VUeXBlEiUuYXBwaG9zdGluZy5TZXRCbG9iU3RvcmFnZVR5cGVSZXF1ZXN0GhouYXBwaG9zdGluZy5iYXNlLlZvaWRQcm90byIAQjwKImNvbS5nb29nbGUuYXBwZW5naW5lLmFwaS5ibG9ic3RvcmVCFkJsb2JzdG9yZVN0dWJTZXJ2aWNlUGI="))
  if _net_proto___parse__python is not None:
    _net_proto___parse__python.RegisterType(
        _SERIALIZED_DESCRIPTOR.tostring())

class SetBlobStorageTypeRequest(ProtocolBuffer.ProtocolMessage):

  MEMORY       =    0
  FILE         =    1

  _StorageType_NAMES = {
    0: "MEMORY",
    1: "FILE",
  }

  def StorageType_Name(cls, x): return cls._StorageType_NAMES.get(x, "")
  StorageType_Name = classmethod(StorageType_Name)

  has_storage_type_ = 0
  storage_type_ = 0

  def __init__(self, contents=None):
    if contents is not None: self.MergeFromString(contents)

  def storage_type(self): return self.storage_type_

  def set_storage_type(self, x):
    self.has_storage_type_ = 1
    self.storage_type_ = x

  def clear_storage_type(self):
    if self.has_storage_type_:
      self.has_storage_type_ = 0
      self.storage_type_ = 0

  def has_storage_type(self): return self.has_storage_type_

  def MergeFrom(self, x):
    assert x is not self
    if (x.has_storage_type()): self.set_storage_type(x.storage_type())

  if _net_proto___parse__python is not None:
    def _CMergeFromString(self, s):
      _net_proto___parse__python.MergeFromString(self, 'apphosting.SetBlobStorageTypeRequest', s)

  if _net_proto___parse__python is not None:
    def _CEncode(self):
      return _net_proto___parse__python.Encode(self, 'apphosting.SetBlobStorageTypeRequest')

  if _net_proto___parse__python is not None:
    def _CEncodePartial(self):
      return _net_proto___parse__python.EncodePartial(self, 'apphosting.SetBlobStorageTypeRequest')

  if _net_proto___parse__python is not None:
    def _CToASCII(self, output_format):
      return _net_proto___parse__python.ToASCII(self, 'apphosting.SetBlobStorageTypeRequest', output_format)

  if _net_proto___parse__python is not None:
    def ParseASCII(self, s):
      _net_proto___parse__python.ParseASCII(self, 'apphosting.SetBlobStorageTypeRequest', s)

  if _net_proto___parse__python is not None:
    def ParseASCIIIgnoreUnknown(self, s):
      _net_proto___parse__python.ParseASCIIIgnoreUnknown(self, 'apphosting.SetBlobStorageTypeRequest', s)

  def Equals(self, x):
    if x is self: return 1
    if self.has_storage_type_ != x.has_storage_type_: return 0
    if self.has_storage_type_ and self.storage_type_ != x.storage_type_: return 0
    return 1

  def IsInitialized(self, debug_strs=None):
    initialized = 1
    if (not self.has_storage_type_):
      initialized = 0
      if debug_strs is not None:
        debug_strs.append('Required field: storage_type not set.')
    return initialized

  def ByteSize(self):
    n = 0
    n += self.lengthVarInt64(self.storage_type_)
    return n + 1

  def ByteSizePartial(self):
    n = 0
    if (self.has_storage_type_):
      n += 1
      n += self.lengthVarInt64(self.storage_type_)
    return n

  def Clear(self):
    self.clear_storage_type()

  def OutputUnchecked(self, out):
    out.putVarInt32(8)
    out.putVarInt32(self.storage_type_)

  def OutputPartial(self, out):
    if (self.has_storage_type_):
      out.putVarInt32(8)
      out.putVarInt32(self.storage_type_)

  def TryMerge(self, d):
    while d.avail() > 0:
      tt = d.getVarInt32()
      if tt == 8:
        self.set_storage_type(d.getVarInt32())
        continue

      if (tt == 0): raise ProtocolBuffer.ProtocolBufferDecodeError()
      d.skipData(tt)

  def __str__(self, prefix="", printElemNumber=0):
    res=""
    if self.has_storage_type_: res+=prefix+("storage_type: %s\n" % self.DebugFormatInt32(self.storage_type_))
    return res

  def _BuildTagLookupTable(sparse, maxtag, default=None):
    return tuple([sparse.get(i, default) for i in range(0, 1+maxtag)])

  kstorage_type = 1

  _TEXT = _BuildTagLookupTable({
    0: "ErrorCode",
    1: "storage_type",
  }, 1)

  _TYPES = _BuildTagLookupTable({
    0: ProtocolBuffer.Encoder.NUMERIC,
    1: ProtocolBuffer.Encoder.NUMERIC,
  }, 1, ProtocolBuffer.Encoder.MAX_TYPE)

  _STYLE = """"""
  _STYLE_CONTENT_TYPE = """"""
  _PROTO_DESCRIPTOR_NAME = 'apphosting.SetBlobStorageTypeRequest'
  _SERIALIZED_DESCRIPTOR = array.array('B')
  _SERIALIZED_DESCRIPTOR.fromstring(base64.decodestring("WjVhcHBob3N0aW5nL2FwaS9ibG9ic3RvcmUvYmxvYnN0b3JlX3N0dWJfc2VydmljZS5wcm90bwokYXBwaG9zdGluZy5TZXRCbG9iU3RvcmFnZVR5cGVSZXF1ZXN0ExoMc3RvcmFnZV90eXBlIAEoADAFOAJoABRzegtTdG9yYWdlVHlwZYsBkgEGTUVNT1JZmAEAjAGLAZIBBEZJTEWYAQGMAXTCARthcHBob3N0aW5nLlN0b3JlQmxvYlJlcXVlc3Q="))
  if _net_proto___parse__python is not None:
    _net_proto___parse__python.RegisterType(
        _SERIALIZED_DESCRIPTOR.tostring())

class BlobstoreStubServiceStub(object):
  """Makes Stubby RPC calls to a BlobstoreStubService server."""

  __metaclass__ = abc.ABCMeta

  __slots__ = ()

  @abc.abstractmethod
  def StoreBlob(self, request, rpc=None, callback=None, response=None):
    """Make a StoreBlob RPC call.

    Args:
      request: a StoreBlobRequest instance.
      rpc: Optional RPC instance to use for the call.
      callback: Optional final callback. Will be called as
          callback(rpc, result) when the rpc completes. If None, the
          call is synchronous.
      response: Optional ProtocolMessage to be filled in with response.

    Returns:
      The google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto if callback is None. Otherwise, returns None.
    """
    raise NotImplementedError()

  @abc.abstractmethod
  def SetBlobStorageType(self, request, rpc=None, callback=None, response=None):
    """Make a SetBlobStorageType RPC call.

    Args:
      request: a SetBlobStorageTypeRequest instance.
      rpc: Optional RPC instance to use for the call.
      callback: Optional final callback. Will be called as
          callback(rpc, result) when the rpc completes. If None, the
          call is synchronous.
      response: Optional ProtocolMessage to be filled in with response.

    Returns:
      The google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto if callback is None. Otherwise, returns None.
    """
    raise NotImplementedError()

class _BlobstoreStubService_ClientBaseStub(
    BlobstoreStubServiceStub, _client_stub_base_class):
  """Makes Stubby RPC calls to a BlobstoreStubService server."""

  __slots__ = (
      '_protorpc_StoreBlob', '_full_name_StoreBlob',
      '_protorpc_SetBlobStorageType', '_full_name_SetBlobStorageType',
  )

  def __init__(self, rpc_stub, rpc_factory=None):
    super(_BlobstoreStubService_ClientBaseStub, self).__init__(
        None, inject_stub=rpc_stub, rpc_factory=rpc_factory)

    self._protorpc_StoreBlob = pywraprpc.RPC()
    self._full_name_StoreBlob = self._stub.GetFullMethodName(
        'StoreBlob')

    self._protorpc_SetBlobStorageType = pywraprpc.RPC()
    self._full_name_SetBlobStorageType = self._stub.GetFullMethodName(
        'SetBlobStorageType')

  def StoreBlob(self, request, rpc=None, callback=None, response=None):
    """Make a StoreBlob RPC call.

    Args:
      request: a StoreBlobRequest instance.
      rpc: Optional RPC instance to use for the call.
      callback: Optional final callback. Will be called as
          callback(rpc, result) when the rpc completes. If None, the
          call is synchronous.
      response: Optional ProtocolMessage to be filled in with response.

    Returns:
      The google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto if callback is None. Otherwise, returns None.
    """

    if response is None:
      response = google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto
    return self._MakeCall(rpc,
                          self._full_name_StoreBlob,
                          'StoreBlob',
                          request,
                          response,
                          callback,
                          self._protorpc_StoreBlob,
                          package_name='apphosting')

  def SetBlobStorageType(self, request, rpc=None, callback=None, response=None):
    """Make a SetBlobStorageType RPC call.

    Args:
      request: a SetBlobStorageTypeRequest instance.
      rpc: Optional RPC instance to use for the call.
      callback: Optional final callback. Will be called as
          callback(rpc, result) when the rpc completes. If None, the
          call is synchronous.
      response: Optional ProtocolMessage to be filled in with response.

    Returns:
      The google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto if callback is None. Otherwise, returns None.
    """

    if response is None:
      response = google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto
    return self._MakeCall(rpc,
                          self._full_name_SetBlobStorageType,
                          'SetBlobStorageType',
                          request,
                          response,
                          callback,
                          self._protorpc_SetBlobStorageType,
                          package_name='apphosting')

class _BlobstoreStubService_ClientStub(_BlobstoreStubService_ClientBaseStub):
  __slots__ = ('_params',)
  def __init__(self, rpc_stub_parameters, service_name, rpc_factory=None):
    if service_name is None:
      service_name = 'BlobstoreStubService'
    stub = pywraprpc.RPC_GenericStub(service_name, rpc_stub_parameters)
    super(_BlobstoreStubService_ClientStub, self).__init__(stub, rpc_factory=rpc_factory)
    self._params = rpc_stub_parameters

class _BlobstoreStubService_RPC2ClientStub(_BlobstoreStubService_ClientBaseStub):
  __slots__ = ()
  def __init__(self, server, channel, service_name, rpc_factory=None):
    if service_name is None:
      service_name = 'BlobstoreStubService'
    if channel is None:
      if server is None:
        raise RuntimeError('Invalid argument combination to create a stub')
      channel = pywraprpc.NewClientChannel(server)
    elif channel.version() == 1:
      raise RuntimeError('Expecting an RPC2 channel to create the stub')
    stub = pywraprpc.RPC_GenericStub(service_name, channel)
    super(_BlobstoreStubService_RPC2ClientStub, self).__init__(stub, rpc_factory=rpc_factory)

class BlobstoreStubService(_server_stub_base_class):
  """Base class for BlobstoreStubService Stubby servers."""

  @classmethod
  def _MethodSignatures(cls):
    """Returns a dict of {<method-name>: (<request-type>, <response-type>)}."""
    return {
      'StoreBlob': (StoreBlobRequest, google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto),
      'SetBlobStorageType': (SetBlobStorageTypeRequest, google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto),
      }

  @classmethod
  def _StreamMethodSignatures(cls):
    """Returns a dict of {<method-name>: (<request-type>, <stream-type>, <response-type>)}."""
    return {
      }

  def __init__(self, *args, **kwargs):
    """Creates a Stubby RPC server.

    The arguments to this constructor are the same as the arguments to
    BaseRpcServer.__init__ in rpcserver.py *MINUS* export_name. This
    constructor passes its own value for export_name to
    BaseRpcServer.__init__, so callers of this constructor should only
    pass to this constructor values corresponding to
    BaseRpcServer.__init__'s remaining arguments.
    """
    if _server_stub_base_class is object:
      raise NotImplementedError('Add //net/rpc/python:rpcserver as a '
                                'dependency for Stubby server support.')
    _server_stub_base_class.__init__(self, 'apphosting.BlobstoreStubService', *args, **kwargs)

  @staticmethod
  def NewStub(rpc_stub_parameters, service_name=None, rpc_factory=None):
    """USE NewRPC2Stub INSTEAD."""
    if _client_stub_base_class is object:
      raise RuntimeError('Add //net/rpc/python as a dependency to use Stubby')
    return _BlobstoreStubService_ClientStub(
        rpc_stub_parameters, service_name, rpc_factory=rpc_factory)

  @staticmethod
  def NewRPC2Stub(
      server=None, channel=None, service_name=None, rpc_factory=None):
    """Creates a new BlobstoreStubService Stubby2 client stub.

    Args:
      server: host:port or bns address (favor passing a channel instead).
      channel: directly use a channel to create a stub. Will ignore server
          argument if this is specified.
      service_name: the service name used by the Stubby server.
      rpc_factory: the rpc factory to use if no rpc argument is specified.

    Returns:
     A BlobstoreStubServiceStub to be used to invoke RPCs.
    """

    if _client_stub_base_class is object:
      raise RuntimeError('Add //net/rpc/python:proto_python_api_2_stub (or maybe //net/rpc/python:proto_python_api_1_stub, but eww and b/67959631) as a dependency to create Stubby stubs')
    return _BlobstoreStubService_RPC2ClientStub(
        server, channel, service_name, rpc_factory=rpc_factory)

  def StoreBlob(self, rpc, request, response):
    """Handles a StoreBlob RPC call. You should override this.

    Args:
      rpc: a Stubby RPC object
      request: a StoreBlobRequest that contains the client request
      response: a google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto that should be modified to send the response
    """
    raise NotImplementedError()

  def SetBlobStorageType(self, rpc, request, response):
    """Handles a SetBlobStorageType RPC call. You should override this.

    Args:
      rpc: a Stubby RPC object
      request: a SetBlobStorageTypeRequest that contains the client request
      response: a google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto that should be modified to send the response
    """
    raise NotImplementedError()

  def _AddMethodAttributes(self):
    """Sets attributes on Python RPC handlers.

    See BaseRpcServer in rpcserver.py for details.
    """
    rpcserver._GetHandlerDecorator(
        getattr(self.StoreBlob, '__func__'),
        StoreBlobRequest,
        google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto,
        None,
        'INTEGRITY')
    rpcserver._GetHandlerDecorator(
        getattr(self.SetBlobStorageType, '__func__'),
        SetBlobStorageTypeRequest,
        google_dot_apphosting_dot_api_dot_api__base__pb.VoidProto,
        None,
        'INTEGRITY')

if _extension_runtime:
  pass

__all__ = ['StoreBlobRequest','SetBlobStorageTypeRequest','BlobstoreStubService']


import pandas as pd
import os
import re
from datetime import datetime

EV_PATTERN = re.compile('^ev_dump_.*\.csv$', re.IGNORECASE)
DEVICE_SCHEMA = {
    'timestamp': 'str',
    'device_id': 'str',
    'event_type': 'str',
    'event_payload': 'str'
}

def __clean_timestamp(rawValue:str) -> datetime:
    try:
        if rawValue is not None:
            actualVal = float(rawValue)
            return datetime.fromtimestamp(actualVal)
    except Exception:
        pass

    return None

def __clean_device_id(rawValue:str) -> str:
    try:
        if rawValue is not None and len(rawValue) == 8:
            # parse as hex into decimal to confirm its a valid value
            _ = int(rawValue, 16)
            return rawValue.lower()
    except Exception:
        pass

    return None

def __clean_event_type(rawValue:str) -> str:
    if rawValue is None or len(rawValue) >= 256:
        # unexpected value, lets skip it
        return None

    return rawValue.lower()

def get_ev_data(rootDir:str) -> pd.DataFrame:
    """Retrieves all EV data from the given folder and returns as a DataFrame."""

    combinedDf = None

    for fileName in os.listdir(rootDir):
        absFilePath = os.path.join(rootDir, fileName)
        if not os.path.isfile(absFilePath):
            continue # assuming all files are within the given directory and not subdirectories.

        if not re.match(EV_PATTERN, fileName):
            # not an ev file - skip for now
            continue

        df = pd.read_csv(absFilePath, sep=',', skiprows=1, skip_blank_lines=True, header=None, names=DEVICE_SCHEMA.keys(), dtype=DEVICE_SCHEMA, on_bad_lines='warn')
        df['timestamp'] = df['timestamp'].apply(__clean_timestamp)
        df['device_id'] = df['device_id'].apply(__clean_device_id)
        df['event_type'] = df['event_type'].apply(__clean_event_type)
        df.dropna(inplace=True)

        if combinedDf is None:
            combinedDf = df
        else:
            combinedDf = pd.concat([combinedDf, df])

    return combinedDf


import rpyc
from english_words import *
from constCS import *

dns = rpyc.connect(DNS_HOST, port = DNS_PORT)

enc = dns.root.lookup(ENCRYPT_NAME)
dec = dns.root.lookup(DECRYPT_NAME)

if enc is None or dec is None:
	quit()

encrypter = rpyc.connect(enc[0], port = enc[1])
decrypter = rpyc.connect(dec[0], port = dec[1])

key = 15
for word in english_words_lower_set:
	encrypted = encrypter.root.encrypt(word, key)
	decrypted = decrypter.root.decrypt(encrypted, key)
	print(word, '->', encrypted, '->', decrypted)


"""

非常简单的10行代码推理MaskRCNN
"""

import torchvision
from PIL import Image
from torchvision.transforms import transforms as T
import cv2
from alfred.vis.image.common import get_unique_color_by_id
import numpy as np
import random
import glob
import os

COCO_INSTANCE_CATEGORY_NAMES = [
    '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus',
    'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'N/A', 'stop sign',
    'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow',
    'elephant', 'bear', 'zebra', 'giraffe', 'N/A', 'backpack', 'umbrella', 'N/A', 'N/A',
    'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
    'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket',
    'bottle', 'N/A', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl',
    'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
    'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed', 'N/A', 'dining table',
    'N/A', 'N/A', 'toilet', 'N/A', 'tv', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone',
    'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'N/A', 'book',
    'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'
]

model = torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True)
model.eval()
print('MaskRCNN model loaded.')

def random_colour_masks(image):
    colours = [[0, 255, 0], [0, 0, 255], [255, 0, 0], [0, 255, 255], [255, 255, 0], [
        255, 0, 255], [80, 70, 180], [250, 80, 190], [245, 145, 50], [70, 150, 250], [50, 190, 190]]
    r = np.zeros_like(image).astype(np.uint8)
    g = np.zeros_like(image).astype(np.uint8)
    b = np.zeros_like(image).astype(np.uint8)
    r[image == 1], g[image == 1], b[image ==
                                    1] = colours[random.randrange(0, 10)]
    coloured_mask = np.stack([r, g, b], axis=2)
    return coloured_mask

def instance_segmentation_api(img_path, threshold=0.5, rect_th=3, text_size=3, text_th=3):
    masks, boxes, pred_cls = get_prediction(img_path, threshold)
    img = cv2.imread(img_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    for i in range(len(masks)):
        rgb_mask = random_colour_masks(masks[i])
        img = cv2.addWeighted(img, 1, rgb_mask, 0.5, 0)
        cv2.rectangle(img, boxes[i][0], boxes[i][1],
                      color=(0, 255, 0), thickness=rect_th)
        cv2.putText(img, pred_cls[i], boxes[i][0], cv2.FONT_HERSHEY_SIMPLEX,
                    text_size, (0, 255, 0), thickness=text_th)
    cv2.imshow('aa', img)
    cv2.waitKey(0)

def get_prediction(img_path, threshold):
    img = Image.open(img_path)
    transform = T.Compose([T.ToTensor()])
    img = transform(img)
    pred = model([img])
    pred_score = list(pred[0]['scores'].detach().numpy())
    pred_t = [pred_score.index(x) for x in pred_score if x > threshold][-1]
    masks = (pred[0]['masks'] > 0.5).squeeze().detach().cpu().numpy()
    pred_class = [COCO_INSTANCE_CATEGORY_NAMES[i]
                  for i in list(pred[0]['labels'].numpy())]
    pred_boxes = [[(i[0], i[1]), (i[2], i[3])]
                  for i in list(pred[0]['boxes'].detach().numpy())]
    masks = masks[:pred_t+1]
    pred_boxes = pred_boxes[:pred_t+1]
    pred_class = pred_class[:pred_t+1]
    return masks, pred_boxes, pred_class

if __name__ == '__main__':
    imgs = glob.glob(os.path.join('images/*.png'))
    for img in imgs:
        instance_segmentation_api(img)


# services/server/project/api/libraries.py

from flask import Blueprint, request
from flask_restful import Resource, Api

from project import db
from project.api.models import Library

from project.api.functions import get_pypi_version

from sqlalchemy import exc

libraries_blueprint = Blueprint('libraries', __name__)
api = Api(libraries_blueprint)

class ServerHome(Resource):
    def get(self):
        return {
            'message': 'welcome!',
        }

class LibrariesList(Resource):
    def get(self):
        page = request.args.get('page', default=1, type=int)
        libraries = Library.query.order_by(Library.id.desc()).paginate(page, 25, False)
        response_object = {
            'status': 'success',
            'libraries': [library.to_json() for library in libraries.items]
        }
        return response_object, 200

class Libraries(Resource):
    def get(self, library_id):
        """Get single library details"""
        response_object = {
            'status': 'fail',
            'message': 'Library does not exist'
        }
        try:
            library = Library.query.filter_by(id=int(library_id)).first()
            if not library:
                return response_object, 400
            else:
                response_object = {
                    'status': 'success',
                    'library': library.to_json()
                }

                response_object = get_pypi_version(response_object)

                return response_object, 200
        except ValueError:
            return response_object, 400

    def put(self, library_id):
        """Update exisiting Library"""
        put_data = request.get_json()

        response_object = {
            'status': 'fail',
            'message': 'Invalid payload.'
        }

        if not put_data:
            return response_object, 400

        name = put_data.get('name')
        repository = put_data.get('repository')
        download_count = put_data.get('download_count')
        issue_count = put_data.get('issue_count')
        author = put_data.get('author')
        user_rating = put_data.get('user_rating')

        updated_library = Library.query.filter_by(id=library_id).first()

        if updated_library:
            if name:
                updated_library.name = name
            if repository:
                updated_library.repository = repository
            if download_count:
                updated_library.download_count = download_count
            if issue_count:
                updated_library.issue_count = issue_count
            if author:
                updated_library.author = author
            if user_rating:
                updated_library.user_rating = user_rating

            db.session.commit()
            response_object['status'] = 'success'
            response_object['message'] = f'Library {name} was updated!'
            return response_object, 204

        response_object['message'] = 'Sorry. That library does not exist'
        return response_object, 400

    def delete(self, library_id):
        """Delete exisiting Library"""
        Library.query.filter_by(id=library_id).delete()
        db.session.commit()
        response_object = {
            'status': 'success',
            'message': 'Library deleted'
        }
        return response_object, 200

class NewLibrary(Resource):
    def post(self):
        """Create new library"""
        post_data = request.get_json()

        response_object = {
            'status': 'fail',
            'message': 'Invalid payload.'
        }

        if not post_data:
            return response_object, 400

        name = post_data.get('name')
        repository = post_data.get('repository')
        download_count = post_data.get('download_count')
        issue_count = post_data.get('issue_count')
        author = post_data.get('author')
        user_rating = post_data.get('user_rating')

        try:
            library = Library.query.filter_by(name=name, repository=repository).first()
            if not library:
                db.session.add(
                    Library(
                        name=name,
                        repository=repository,
                        download_count=download_count,
                        issue_count=issue_count,
                        author=author,
                        user_rating=user_rating
                    )
                )
                db.session.commit()
                response_object['status'] = 'success'
                response_object['message'] = f'Library {name} was added!'
                return response_object, 201
            else:
                response_object['message'] = 'Sorry. That library already exists.'
                return response_object, 400
        except exc.DataError:
            db.session.rollback()
            return response_object, 400

api.add_resource(ServerHome, '/')
api.add_resource(LibrariesList, '/libraries')
api.add_resource(Libraries, '/library/<int:library_id>')
api.add_resource(NewLibrary, '/library')