import json

class DestinoCulinario:
    def __init__(self, id_destino, nombre, tipo_cocina, ingredientes, precio_minimo, precio_maximo, popularidad, disponibilidad, id_ubicacion, imagen):
        self.id = id_destino
        self.nombre = nombre
        self.tipo_cocina = tipo_cocina
        self.ingredientes = ingredientes
        self.precio_minimo = precio_minimo
        self.precio_maximo = precio_maximo
        self.popularidad = popularidad
        self.disponibilidad = disponibilidad
        self.id_ubicacion = id_ubicacion
        self.imagen = imagen

    #def __str__(self):
    #    return f"Destino Culinario: {self.nombre}, Tipo de cocina: {self.tipo_cocina}, \nPopularidad: {self.popularidad}, Disponibilidad: {self.disponibilidad}"

    def cambiar_disponibilidad(self, disponibilidad_nueva):
        self.disponibilidad = disponibilidad_nueva
    def a_json(self):
        return json.dumps(self.__dict__)

    @classmethod
    def de_json(cls, datos_json):
        datos = json.loads(datos_json)
        return cls(**datos)

    @staticmethod
    def cargar_destinos(archivo_json):
        with open(archivo_json, "r", encoding="utf-8") as archivo:
            datos = json.load(archivo)
        return [DestinoCulinario.de_json(json.dumps(dato)) for dato in datos]


import sys
sys.stdin = open("input.txt")

T = 1

# 두 사람의 촌수를 알아보기 위해 시작과 끝으로 나누어서 분석
def cal(start, end):
    # 방문했다는 것을 담기 위한 리스트 초기화
    visited = []
    # 현재 검사해야 하는 곳 초기화
    now = []
    # 촌수 초기화
    cnt = 0
    # 시작을 검사 리스트에 추가
    now.append(start)

    # 검사리스트에 존재할때까지 반복 - 가족관계가 있을때까지
    while now:
        # 있다면 일단 촌수 증가
        cnt += 1
        # 현재 검사해야하는 사람만큼 검사
        for _ in range(len(now)):
            # 현재 검사해야하는 사람을 추출
            temp = now.pop(0)
            # 만약 그사람이 목표한 사람이라면
            if temp == end:
                # 촌수에서 -1
                return cnt - 1
            # 해당 정보에 해당하는 가족관계를 검사
            for person in info[temp]:
                # 만약 그 사람이 검사한 사람이 아니라면
                if person not in visited:
                    # 검사 리스트에 추가
                    visited.append(person)
                    # 현재 검사할 리스트에 추가
                    now.append(person)
    # 만약 반복문이 끝났다면 관계가 없다는 것이므로 -1
    return -1

for tc in range(1, T+1):
    n = int(input())
    tar = list(map(int, input().split()))
    m = int(input())
    info = [[]for _ in range(n+1)]
    for _ in range(m):
        x, y = map(int, input().split())
        info[x].append(y)
        info[y].append(x)

    # 두대상을 계산하는 함수 사용
    print(cal(tar[0], tar[1]))


from django.conf.urls import url, include
from django.contrib import admin

from . import views

app_name = 'mini_url'
urlpatterns = [
    url(r'^home/$', views.ListRedirection_view.as_view(), name='home'),
    url(r'^redirect/(?P<code>\d+)/$', views.redirected_view, name='redirect'),
    url(r'^acces/(?P<code>\d+)/$', views.access_url, name='redirect'),
    url(r'^about/$', views.FAQView.as_view(), name='about'),
    url(r'^create_miniurl/$', views.CreateUrlView.as_view(), name="create-miniurl"),
]


# Use open function to read the contents of a file
f = open('sample.txt')  #by default the mode is r
f = open('sample.txt', 'r')
Data = f.read()
print(Data)
f.close()
Data = f.read(5)       #reads first 5 characters of file

#READLINE

f = open('sample.txt')    #by default the mode is r
Data = f.readline()
print(Data)

#reads 2nd line
Data = f.readline()
print(Data)
f.close()

# and so on....

# #Write a file
f = open("another.txt", "w")
f.write("Please write this to the data")
f.close()

#append a file
f = open("another.txt", "a")
f.write("Hey i am appending")
f.close()

f = open("sample.txt", "a")
f.write("\nHey i am appending")
f.close()

# with statement, we dont need to write close() in with statement
with open("another.txt", "w") as f:
    a = f.write("writing in with statement")
print(a)

Read & Write files/Read & Write files.py


#!/usr/bin/env python
# cogent/app/clustalw.py
"""Provides an application controller for the commandline version of:
CLUSTALW

Owner: Sandra Smit (sandra.smit@colorado.edu)

Status: Development

Revision History:
July 04-9/26/04: Written by Sandra Smit
3/7/2005 Micah Hamady: Fixed input handler to rsplit. fixes bug when relative path or when multiple extensions

"""
from old_cogent.app.parameters import FlagParameter, ValuedParameter, \
    MixedParameter
from old_cogent.app.util import CommandLineApplication, ResultPath

class Clustalw(CommandLineApplication):
    """ clustalw application controller

    The parameters are organized by function to give some idea of how the
    program works. However, no restrictions are put on any combinations
    of parameters. Misuse of parameters can lead to errors or otherwise
    strange results.

    You are supposed to choose one action for the program to perform. (align,
    profile, sequences, tree, or bootstrap). If you choose multiple, only the
    dominant action (see order above) will be executed. By DEFAULT, the -align
    parameter is turned on. If you decide to turn another one on, you should
    turn '-align' off IN ADDITION!

    Some references to help pages are available in the 'getHelp' method.
    Some might be useful to you.
    """
    _actions = {\
        '-align':FlagParameter('-','align',Value=True),
        '-profile':FlagParameter('-','profile'),
        '-sequences':FlagParameter('-','sequences'),
        '-tree':FlagParameter('-','tree'),
        '-bootstrap':MixedParameter('-','bootstrap',Delimiter='=')}

    #sequence file for alingment, or alignment file for bootstrap and tree
    #actions
    _input = {'-infile':ValuedParameter('-','infile',Delimiter='=')}

    _multiple_alignment={\
        '-quicktree':FlagParameter('-','quicktree'),
        '-type':ValuedParameter('-','type',Delimiter='='),
        '-matrix':ValuedParameter('-','matrix',Delimiter='='),
        '-dnamatrix':ValuedParameter('-','dnamatrix',Delimiter='='),
        '-gapopen':ValuedParameter('-','gapopen',Delimiter='='),
        '-gapext':ValuedParameter('-','gapext',Delimiter='='),
        '-endgaps':FlagParameter('-','endgaps'),
        '-gapdist':ValuedParameter('-',Name='gapdist',Delimiter='='),
        '-nopgap':FlagParameter('-','nopgap'),
        '-nohgap':FlagParameter('-','nohgap'),
        '-hgapresidues':ValuedParameter('-','hgapresidues',Delimiter='='),
        '-maxdiv':ValuedParameter('-',Name='maxdiv',Delimiter='='),
        '-negative':FlagParameter('-','negative'),
        '-transweight':ValuedParameter('-',Name='transweight',Delimiter='='),
        '-newtree':ValuedParameter('-','newtree',Delimiter='='),
        '-usetree':ValuedParameter('-','usetree',Delimiter='=')}

    _fast_pairwise={\
        '-ktuple':ValuedParameter('-',Name='ktuple',Delimiter='='),
        '-topdiags':ValuedParameter('-',Name='topdiags',Delimiter='='),
        '-window':ValuedParameter('-',Name='window',Delimiter='='),
        '-pairgap':ValuedParameter('-',Name='pairgap',Delimiter='='),
        '-score':ValuedParameter('-',Name='score',Delimiter='=')}

    _slow_pairwise={\
        '-pwmatrix':ValuedParameter('-',Name='pwmatrix',Delimiter='='),
        '-pwdnamatrix':ValuedParameter('-',Name='pwdnamatrix',Delimiter='='),
        '-pwgapopen':ValuedParameter('-',Name='pwgapopen',Delimiter='='),
        '-pwgapext':ValuedParameter('-',Name='pwgapext',Delimiter='=')}

    #plus -bootstrap
    _tree={\
        '-kimura':FlagParameter('-',Name='kimura'),
        '-tossgaps':FlagParameter('-',Name='tossgaps'),
        '-bootlabels':ValuedParameter('-',Name='bootlabels',Delimiter='='),
        '-seed':ValuedParameter('-',Name='seed',Delimiter='='),
        '-outputtree':ValuedParameter('-',Name='outputtree',Delimiter='=')}

    _output={\
        '-outfile':ValuedParameter('-',Name='outfile',Delimiter='='),
        '-output':ValuedParameter('-',Name='output',Delimiter='='),
        '-case':ValuedParameter('-',Name='case',Delimiter='='),
        '-outorder':ValuedParameter('-',Name='outorder',Delimiter='='),
        '-seqnos':ValuedParameter('-',Name='seqnos',Delimiter='=')}

    _profile_alignment={\
        '-profile1':ValuedParameter('-','profile1',Delimiter='='),
        '-profile2':ValuedParameter('-','profile2',Delimiter='='),
        '-usetree1':ValuedParameter('-','usetree1',Delimiter='='),
        '-usetree2':ValuedParameter('-','usetree2',Delimiter='='),
        '-newtree1':ValuedParameter('-','newtree1',Delimiter='='),
        '-newtree2':ValuedParameter('-','newtree2',Delimiter='=')}

    _structure_alignment={\
        '-nosecstr1':FlagParameter('-',Name='nosecstr1'),
        '-nosecstr2':FlagParameter('-',Name='nosecstr2'),
        '-helixgap':ValuedParameter('-',Name='helixgap',Delimiter='='),
        '-strandgap':ValuedParameter('-',Name='strandgap',Delimiter='='),
        '-loopgap':ValuedParameter('-',Name='loopgap',Delimiter='='),
        '-terminalgap':ValuedParameter('-',Name='terminalgap',Delimiter='='),
        '-helixendin':ValuedParameter('-',Name='helixendin',Delimiter='='),
        '-helixendout':ValuedParameter('-',Name='helixendout',Delimiter='='),
        '-strandendin':ValuedParameter('-',Name='strandendin',Delimiter='='),
        '-strandendout':ValuedParameter('-',Name='strandendout',Delimiter='='),
        '-secstrout':ValuedParameter('-',Name='secstrout',Delimiter='=')}

        #NOT SUPPORTED
        #'-help':FlagParameter('-','help'),
        #'-check':FlagParameter('-','check'),
        #'-options':FlagParameter('-','options'),
        #'-convert':FlagParameter('-','convert'),
        #'-batch':FlagParameter('-','batch'),
        #'-noweights':FlagParameter('-','noweights'),
        #'-novgap':FlagParameter('-','novgap'),
        #'-debug':ValuedParameter('-',Name='debug',Delimiter='='),

    _parameters = {}
    _parameters.update(_actions)
    _parameters.update(_input)
    _parameters.update(_multiple_alignment)
    _parameters.update(_fast_pairwise)
    _parameters.update(_slow_pairwise)
    _parameters.update(_tree)
    _parameters.update(_output)
    _parameters.update(_profile_alignment)
    _parameters.update(_structure_alignment)

    _command = 'clustalw'

    def getHelp(self):
        """Methods that points to the documentation"""
        help_str =\
        """
        There are several help pages available online. For example:
        http://searchlauncher.bcm.tmc.edu/multi-align/Help/clustalw_help_1.8.html
        http://hypernig.nig.ac.jp/homology/clustalw-e_help.html
        http://www.genebee.msu.su/clustal/help.html

        A page that give reasonable insight in use of the parameters:
        http://bioweb.pasteur.fr/seqanal/interfaces/clustalw.html
        """
        return help_str

    def _input_as_lines(self,data):
        if data:
            self.Parameters['-infile']\
                .on(super(Clustalw,self)._input_as_lines(data))
        return ''

    def _input_as_seqs(self,data):

        lines = []
        for i,s in enumerate(data):
            #will number the sequences 1,2,3,etc.
            lines.append(''.join(['>',str(i+1)]))
            lines.append(s)
        return self._input_as_lines(lines)

    def _input_as_string(self,data):
        """Makes data the value of a specific parameter

        This method returns the empty string. The parameter will be printed
        automatically once set.
        """
        if data:
            self.Parameters['-infile'].on(data)
        return ''

    def _absolute(self,path):
        if path.startswith('/'):
            return path
        else:
            return self.WorkingDir + path

    def _suffix(self):
        _output_formats={'GCG':'.msf',
                        'GDE':'.gde',
                        'PHYLIP':'.phy',
                        'PIR':'.pir',
                        'NEXUS':'.nxs'}

        if self.Parameters['-output'].isOn():
            return _output_formats[self.Parameters['-output'].Value]
        else:
            return '.aln'

    def _aln_filename(self,prefix):
        if self.Parameters['-outfile'].isOn():
            aln_filename = self._absolute(self.Parameters['-outfile'].Value)
        else:
            aln_filename = prefix + self._suffix()
        return aln_filename

    def _get_result_paths(self,data):

        #clustalw .aln is used when no or unkown output type specified
        _treeinfo_formats = {'nj':'.nj',
                            'dist':'.dst',
                            'nexus':'.tre'}

        result = {}
        par = self.Parameters
        abs = self._absolute

        if par['-align'].isOn():
            prefix = par['-infile'].Value.rsplit('.', 1)[0]
            #prefix = par['-infile'].Value.split('.')[0]
            aln_filename = self._aln_filename(prefix)
            if par['-newtree'].isOn():
                dnd_filename = abs(par['-newtree'].Value)
            elif par['-usetree'].isOn():
                dnd_filename = abs(par['-usetree'].Value)
            else:
                dnd_filename = abs(prefix + '.dnd')
            result['Align'] = ResultPath(Path=aln_filename,IsWritten=True)
            result['Dendro'] = ResultPath(Path=dnd_filename,IsWritten=True)
        elif par['-profile'].isOn():
            prefix1 = par['-profile1'].Value.rsplit('.', 1)[0]
            prefix2 = par['-profile2'].Value.rsplit('.', 1)[0]
            #prefix1 = par['-profile1'].Value.split('.')[0]
            #prefix2 = par['-profile2'].Value.split('.')[0]
            aln_filename = ''; aln_written = True
            dnd1_filename = ''; tree1_written = True
            dnd2_filename = ''; tree2_written = True
            aln_filename = self._aln_filename(prefix1)
            #usetree1
            if par['-usetree1'].isOn():
                tree1_written = False
            #usetree2
            if par['-usetree2'].isOn():
                tree2_written = False
            if par['-newtree1'].isOn():
                dnd1_filename = abs(par['-newtree1'].Value)
                aln_written=False
            else:
                dnd1_filename = abs(prefix1 + '.dnd')
            if par['-newtree2'].isOn():
                dnd2_filename = abs(par['-newtree2'].Value)
                aln_written=False
            else:
                dnd2_filename = abs(prefix2 + '.dnd')
            result['Align'] = ResultPath(Path=aln_filename,
                IsWritten=aln_written)
            result['Dendro1'] = ResultPath(Path=dnd1_filename,
                IsWritten=tree1_written)
            result['Dendro2'] = ResultPath(Path=dnd2_filename,
                IsWritten=tree2_written)
        elif par['-sequences'].isOn():
            prefix1 = par['-profile1'].Value.rsplit('.', 1)[0]
            prefix2 = par['-profile2'].Value.rsplit('.', 1)[0]
            #prefix1 = par['-profile1'].Value.split('.')[0] #alignment
            #prefix2 = par['-profile2'].Value.split('.')[0] #sequences
            aln_filename = ''; aln_written = True
            dnd_filename = ''; dnd_written = True

            aln_filename = self._aln_filename(prefix2)
            if par['-usetree'].isOn():
                dnd_written = False
            elif par['-newtree'].isOn():
                aln_written = False
                dnd_filename = abs(par['-newtree'].Value)
            else:
                dnd_filename = prefix2 + '.dnd'
            result['Align'] = ResultPath(Path=aln_filename,\
                IsWritten=aln_written)
            result['Dendro'] = ResultPath(Path=dnd_filename,\
                IsWritten=dnd_written)
        elif par['-tree'].isOn():
            prefix = par['-infile'].Value.rsplit('.', 1)[0]
            #prefix = par['-infile'].Value.split('.')[0]
            tree_filename = ''; tree_written = True
            treeinfo_filename = ''; treeinfo_written = False
            tree_filename = prefix + '.ph'
            if par['-outputtree'].isOn() and\
                par['-outputtree'].Value != 'phylip':
                treeinfo_filename = prefix +\
                    _treeinfo_formats[par['-outputtree'].Value]
                treeinfo_written = True
            result['Tree'] = ResultPath(Path=tree_filename,\
                IsWritten=tree_written)
            result['TreeInfo'] = ResultPath(Path=treeinfo_filename,\
                IsWritten=treeinfo_written)

        elif par['-bootstrap'].isOn():
            prefix = par['-infile'].Value.rsplit('.', 1)[0]
            #prefix = par['-infile'].Value.split('.')[0]
            boottree_filename = prefix + '.phb'
            result['Tree'] = ResultPath(Path=boottree_filename,IsWritten=True)

        return result

#SOME FUNCTIONS TO EXECUTE THE MOST COMMON TASKS
def alignUnalignedSeqs(seqs,add_seq_names=True,WorkingDir=None,\
    SuppressStderr=None,SuppressStdout=None):
    """Aligns unaligned sequences

    seqs: either list of sequence objects or list of strings
    add_seq_names: boolean. if True, sequence names are inserted in the list
        of sequences. if False, it assumes seqs is a list of lines of some
        proper format that the program can handle
    """
    if add_seq_names:
        app = Clustalw(InputHandler='_input_as_seqs',\
            WorkingDir=WorkingDir,SuppressStderr=SuppressStderr,\
            SuppressStdout=SuppressStdout)
    else:
        app = Clustalw(InputHandler='_input_as_lines',\
            WorkingDir=WorkingDir,SuppressStderr=SuppressStderr,\
            SuppressStdout=SuppressStdout)
    return app(seqs)

def alignUnalignedSeqsFromFile(filename,WorkingDir=None,SuppressStderr=None,\
    SuppressStdout=None):
    """Aligns unaligned sequences from some file (file should be right format)

    filename: string, the filename of the file containing the sequences
        to be aligned in a valid format.
    """
    app = Clustalw(WorkingDir=WorkingDir,SuppressStderr=SuppressStderr,\
        SuppressStdout=SuppressStdout)
    return app(filename)

def alignTwoAlignments(aln1,aln2,outfile,WorkingDir=None,SuppressStderr=None,\
    SuppressStdout=None):
    """Aligns two alignments. Individual sequences are not realigned

    aln1: string, name of file containing the first alignment
    aln2: string, name of file containing the second alignment
    outfile: you're forced to specify an outfile name, because if you don't
        aln1 will be overwritten. So, if you want aln1 to be overwritten, you
        should specify the same filename.
    WARNING: a .dnd file is created with the same prefix as aln1. So an
    existing dendrogram might get overwritten.
    """
    app = Clustalw({'-profile':None,'-profile1':aln1,\
        '-profile2':aln2,'-outfile':outfile},SuppressStderr=\
        SuppressStderr,WorkingDir=WorkingDir,SuppressStdout=SuppressStdout)
    app.Parameters['-align'].off()
    return app()

def addSeqsToAlignment(aln1,seqs,outfile,WorkingDir=None,SuppressStderr=None,\
        SuppressStdout=None):
    """Aligns sequences from second profile against first profile

    aln1: string, name of file containing the alingment
    seqs: string, name of file containing the sequences that should be added
        to the alignment.
    outfile: string, name of the output file (the new alignment)
    """
    app = Clustalw({'-sequences':None,'-profile1':aln1,\
        '-profile2':seqs,'-outfile':outfile},SuppressStderr=\
        SuppressStderr,WorkingDir=WorkingDir, SuppressStdout=SuppressStdout)
    app.Parameters['-align'].off()
    return app()

def buildTreeFromAlignment(filename,WorkingDir=None,SuppressStderr=None):
    """Builds a new tree from an existing alignment

    filename: string, name of file containing the seqs or alignment
    """
    app = Clustalw({'-tree':None,'-infile':filename},SuppressStderr=\
        SuppressStderr,WorkingDir=WorkingDir)
    app.Parameters['-align'].off()
    return app()

def align_and_build_tree(seqs, best_tree=False, params=None):
    """Returns an alignment and a tree from Sequences object seqs.

    seqs: an xxx.Sequences object, or data that can be used to build one.

    best_tree: if True (default:False), uses a slower but more accurate
    algorithm to build the tree.

    params: dict of parameters to pass in to the Clustal app controller.

    The result will be a tuple containing a xxx.Alignment and an xxx.Tree
    object (or None for the alignment and/or tree if either fails).
    """
    raise NotImplemented

def build_tree_from_alignment(aln, best_tree=False, params=None):
    """Returns a tree from Alignment object aln.

    aln: an xxx.Alignment object, or data that can be used to build one.

    best_tree: if True (default:False), uses a slower but more accurate
    algorithm to build the tree.

    params: dict of parameters to pass in to the Clustal app controller.

    The result will be an xxx.Alignment object, or None if tree fails.
    """
    raise NotImplemented

def add_seqs_to_alignment(seqs, aln, params=None):
    """Returns an Alignment object from seqs and existing Alignment.

    seqs: an xxx.Sequences object, or data that can be used to build one.

    aln: an xxx.Alignment object, or data that can be used to build one

    params: dict of parameters to pass in to the Clustal app controller.
    """
    raise NotImplemented

def align_two_alignments(aln1, aln2, params=None):
    """Returns an Alignment object from two existing Alignments.

    aln1, aln2: xxx.Alignment objects, or data that can be used to build them.

    params: dict of parameters to pass in to the Clustal app controller.
    """
    raise NotImplemented


from tkinter import *
from time import sleep
import tkinter.messagebox as mb

class rocket:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.object = canvas.create_rectangle(self.x - 7.5, self.y - 50, self.x + 7.5, self.y + 50, fill = 'black')

class Circle:
    def __init__(self):
        self.first_player = 0
        self.second_player = 0
        self.x = 300
        self.y = 300
        self.size = 12.5
        self.speed_x = 3
        self.speed_y = 2
        self.object = canvas.create_oval(self.x - self.size, self.y - self.size, self.x + self.size, self.y + self.size, fill = 'red')

    def check_collision(self):
        pos = canvas.coords(self.object)
        if pos[1] <= 0 or pos[3] >= 600:
            self.speed_y *= -1

        if (pos[0] <= canvas.coords(rocket1.object)[2] and pos[1] >= canvas.coords(rocket1.object)[1] and pos[1] <= canvas.coords(rocket1.object)[3]) or (pos[2] >= canvas.coords(rocket2.object)[0] and pos[3] >= canvas.coords(rocket2.object)[1] and pos[3] <= canvas.coords(rocket2.object)[3]):
            self.speed_x *= -1

        if pos[0] <= 0:
            mb.showinfo('Score', 'Player 2 scored!')
            canvas.move(self.object, 300 - self.x, 300 - self.y)
            self.x = 300
            self.y = 300
            self.second_player += 1
            self.speed_x *= -1

        if pos[2] >= 600:
            mb.showinfo('Score', 'Player 1 scored!')
            canvas.move(self.object, 300 - self.x, 300 - self.y)
            self.x = 300
            self.y = 300
            self.first_player += 1
            self.speed_x *= -1

    def move(self):
        self.x += self.speed_x
        self.y += self.speed_y
        canvas.move(self.object, self.speed_x, self.speed_y)
        self.check_collision()

def move_racket(event):
    if event.keysym == 'z':
        if canvas.coords(rocket1.object)[1] >= 3:
            rocket1.y -= 3
            canvas.move(rocket1.object, 0, -3)
    if event.keysym == 'x':
        if canvas.coords(rocket1.object)[3] <= 597:
            rocket1.y += 3
            canvas.move(rocket1.object, 0, 3)
    if event.keysym == 'comma':
        if canvas.coords(rocket2.object)[1] >= 3:
            rocket2.y -= 3
            canvas.move(rocket2.object, 0, -3)
    if event.keysym == 'period':
        if canvas.coords(rocket2.object)[3] <= 597:
            rocket2.y += 3
            canvas.move(rocket2.object, 0, 3)

root = Tk()

canvas = Canvas(root, width = 600, height = 600)

rocket1 = rocket(12.5, 300)
rocket2 = rocket(587.5, 300)

c = Circle()

canvas.bind_all('<KeyPress>', move_racket)

canvas.pack()

score = Label(root, text = f'{c.first_player} : {c.second_player}')
score.pack()

while True:
    score.config(text = f'{c.first_player} : {c.second_player}')
    if c.second_player == 5:
        c.second_player = 0
        c.first_player = 0
        answer = mb.askyesno('Game over', 'Player 2 Win. Continue?')
        if answer == False:
            root.destroy()
            break

    if c.first_player == 5:
        c.second_player = 0
        c.first_player = 0
        answer = mb.askyesno('Game over', 'Player 1 Win. Continue?')
        if answer == False:
            root.destroy()
            break
    c.move()
    root.update()
    sleep(0.03)

root.mainloop()


from dlclive import DLCLive, Processor

import math
from collections import deque
import os
import cv2
import numpy as np
import time
from csv import writer, DictReader
from reolinkapi import Camera # or hopefully another existing API for interfacing w/ your video feed/device
from math import atan2, pi

# TODO: in general this is big and could be broken into separate files
class PoopDetector():

    ''' v3
    - 0 spine1
    - 1 spine2
    - 2 spine3
    - 3 tailstart
    - 4 tailmid
    - 5 tailend
    - 6 butt
    '''

    def __init__(self, cast_service):
        self.cast_service = cast_service
        self.fps = 30
        self.next_frame = 0
        self.pooping_threshold = 0.65
        self.last_spine_location = None
        self.moving = False
        self.movement_timestamp = time.time()
        self.movement_threshold_pixels = 25
        self.seconds_to_determine_movement = 2
        self.pooping_timestamp = time.time()
        self.seconds_to_determine_pooping = 3

        # A rolling capped queue is used for resiliency against individual frames that look like pooping
        self.pooping_detected_queue = deque(maxlen=self.fps*self.seconds_to_determine_pooping)

         # update to your resolution, lower the better for performance-sake.
        self.frame_dim = (1280,720)
        self.dlc_live = DLCLive(
            '../exported-models/DLC_SecurityCamPooping_resnet_50_iteration-0_shuffle-1',
            display=True,
            display_radius=1.5,
            display_cmap='glasbey_light'
        )

    def slope(self, x1, y1, x2, y2):
        return (y2-y1) / (x2-x1)

    # angle in degrees between line through a -> b -> c,wrapping around b
    def angle(self, a, b, c):
        ang = math.degrees(
            math.atan2(c[1]-b[1], c[0]-b[0]) - math.atan2(a[1]-b[1], a[0]-b[0]))
        return ang + 360 if ang < 0 else ang

    # heuristics for poop tail, returns bool depending on whether poop tail found
    def check_for_poop_tail(self, pose):
        tail_detected = False if any(e < 0.8 for (e) in pose[3:6, 2]) else True
        if not tail_detected:
            return False

        # TODO: ew, cleanup & decouple hardcodings to original device
        # TODO: remove ambiguous index access
        if abs(self.angle([pose[3,0],pose[3,1]], [pose[4,0],pose[4,1]], [pose[5,0],pose[5,1]]) - 180) < 40:
            # if tail is straight up in Y direction (i.e. up while butt facing camera)
            # check whether it is in a straight line w/ the butt location... if so, dont return True
            if pose[6,2] > 0.8:
                # if tail end is within N points in either direction on X axis
                # if in top section of frame (way far back, less than 125px from top) dont cancel out
                if abs(pose[5,0] - pose[6,0]) < 5 and pose[6,1] > 125:
                    return False
            return True
        return False

    # simple heuristic checking for rounded spine, i.e. hunchback poop position lol
    def check_for_poop_spine(self, pose):
        spine_detected = False if any(e < 0.8 for (e) in pose[0:3, 2]) else True
        if not spine_detected:
            return False

        spine_section_1_slope = self.slope(pose[0,0],pose[0,1],pose[1,0],pose[1,1])
        spine_section_2_slope = self.slope(pose[1,0],pose[1,1],pose[2,0],pose[2,1])

        if abs(spine_section_1_slope - spine_section_2_slope) > 0.35: # this value may be different for your dog
            return True

        return False

    # return bool for whether the dog "is moving" or appears to be still
    # movement detection is based on spine location. If spine isn't present,
    # return False, i.e. not moving or just not present in frame
    def check_for_movement(self, pose):

        # for performance, just check for movement every N seconds
        should_check_movement = time.time() >= self.movement_timestamp + self.seconds_to_determine_movement

        if should_check_movement:
            self.movement_timestamp = time.time()
            spine_detected = False if pose[1, 2] < 0.8 else True
            if not spine_detected:
                self.moving = False
                return self.moving

            current_spine_location = (pose[1,0], pose[1,1])

            if self.last_spine_location is not None:
                x_diff = abs(current_spine_location[0] - self.last_spine_location[0])
                y_diff = abs(current_spine_location[1] - self.last_spine_location[1])

                if x_diff > self.movement_threshold_pixels or y_diff > self.movement_threshold_pixels:
                    self.moving = True
                else:
                    self.moving = False

            self.last_spine_location = current_spine_location

        return self.moving

    # leverage all the pooping heuristics to determine
    # whether pooping is detected in this frame
    def is_twinkie_pooping(self, pose):

        # 1) look for poop spine
        poop_spine = self.check_for_poop_spine(pose)

        # 2) look for pointy poop tail
        poop_tail = self.check_for_poop_tail(pose)

        # 3) not moving "for awhile"
        moving = self.check_for_movement(pose)

        # print([poop_spine, poop_tail, not moving])
        pooping = all([poop_spine, poop_tail, not moving])
        if pooping:
            return 1

        return 0

    def check_rolling_average(self, pose, img):
        # check rolling average
        if sum(self.pooping_detected_queue) / len(self.pooping_detected_queue) > self.pooping_threshold:
            print('\nPooping detected')
            # self.cast_service.play_sound()
            self.save_poop_location(pose,img)
            # clear once poop detected, helps w/ trailing additional poo detections due to filled queue
            self.pooping_detected_queue.clear()

    # This is great for debugging/testing with recorded video
    def beefy_boy(self):
        #####

        # For using with live camera, you'll need to replace the recorded images
        # with images streamed via RTSP (probably). Depending on your camera,
        # you'll need to find an API for connecting to it.

        #####
        cap = cv2.VideoCapture('path_to_sample_video.mp4')
        success, img = cap.read()
        fno = 0
        self.dlc_live.init_inference(self.maintain_aspect_ratio_resize(img, width=self.frame_dim[0], height=self.frame_dim[1])) # for some reason, gotta prime the pump
        while success:

            # this gnarliness is to throttle the video to process at your set fps
            frame = None
            while frame is None:
                cur_time = time.time()
                if cur_time > self.next_frame:
                    frame = img
                    self.next_frame = max(
                        self.next_frame + 1.0 / self.fps, cur_time + 0.5 / self.fps
                    )

            success, img = cap.read()

            if all(e is not None for e in [frame, img]):
                pose = self.dlc_live.get_pose(self.maintain_aspect_ratio_resize(img, width=self.frame_dim[0], height=self.frame_dim[1]))
                is_pooping = self.is_twinkie_pooping(pose)
                self.pooping_detected_queue.append(is_pooping)

                time_to_check_average = time.time() >= self.pooping_timestamp + self.seconds_to_determine_pooping
                if time_to_check_average:
                    self.pooping_timestamp = time.time()
                    print('\npooping likelihood: ', sum(self.pooping_detected_queue) / len(self.pooping_detected_queue), '\n')
                    self.check_rolling_average(pose, img)

    # This is should be broken up, but this does the following:
    # 1) store poop locations (x,y) in csv
    # 2) draw circle on "this" frame, beneath the base of the tail
    # 3) saves the image so you can access the picture from any device on LAN
    def save_poop_location(self, pose, img):
        # attempt to save under tail_start
        x, y = pose[3,0], pose[3,1] + 15
        poop_location = [x,y]

        write = True
        with open('poop_locations.csv') as f:
            reader = DictReader(f)
            for row in reader:
                # draw poop on image
                cv2.circle(img, (int(float(row['x'])), int(float(row['y']))), 15, (0,0,255), thickness=2, lineType=8)

                # dont write to csv if already detected poop
                distance = math.sqrt(((x - float(row['x'])) ** 2) + ((y - float(row['y'])) ** 2))
                if distance < 50:
                    write = False

            f.close()

        # save image
        if write: cv2.circle(img, (int(poop_location[0]), int(poop_location[1])), 15, (0,0,255), thickness=2, lineType=8)
        cv2.imwrite('poop_locations.jpg', img)

        if write:
            with open('poop_locations.csv', 'a', newline='', encoding='utf-8') as f:
                writer_object = writer(f)
                writer_object.writerow(poop_location)
                f.close()

    # Resizes a image and maintains aspect ratio
    def maintain_aspect_ratio_resize(self, image, width=None, height=None, inter=cv2.INTER_AREA):
        # Grab the image size and initialize dimensions
        dim = None
        (h, w) = image.shape[:2]

        # Return original image if no need to resize
        if width is None and height is None:
            return image

        # We are resizing height if width is none
        if width is None:
            # Calculate the ratio of the height and construct the dimensions
            r = height / float(h)
            dim = (int(w * r), height)
        # We are resizing width if height is none
        else:
            # Calculate the ratio of the 0idth and construct the dimensions
            r = width / float(w)
            dim = (width, int(h * r))

        # Return the resized image
        return cv2.resize(image, dim, interpolation=inter)


import os
import os.path as op
from arcana.data.file_format import text_format
from arcana.analysis import Analysis, AnalysisMetaClass
from arcana.data import (
    Fileset, InputFilesetSpec, FilesetSpec, Field)
from arcana.utils.testing import BaseMultiSubjectTestCase
from arcana.repository import Tree
from future.utils import with_metaclass
from arcana.utils.testing import BaseTestCase
from arcana.data.file_format import FileFormat

# A dummy format that contains a header
with_header_format = FileFormat(name='with_header', extension='.whf',
                                aux_files={'header': '.hdr'})

class DummyAnalysis(with_metaclass(AnalysisMetaClass, Analysis)):

    add_data_specs = [
        InputFilesetSpec('source1', text_format),
        InputFilesetSpec('source2', text_format),
        InputFilesetSpec('source3', text_format),
        InputFilesetSpec('source4', text_format,
                         optional=True),
        FilesetSpec('sink1', text_format, 'dummy_pipeline'),
        FilesetSpec('sink3', text_format, 'dummy_pipeline'),
        FilesetSpec('sink4', text_format, 'dummy_pipeline'),
        FilesetSpec('subject_sink', text_format, 'dummy_pipeline',
                    frequency='per_subject'),
        FilesetSpec('visit_sink', text_format, 'dummy_pipeline',
                    frequency='per_visit'),
        FilesetSpec('project_sink', text_format, 'dummy_pipeline',
                    frequency='per_dataset'),
        FilesetSpec('resink1', text_format, 'dummy_pipeline'),
        FilesetSpec('resink2', text_format, 'dummy_pipeline'),
        FilesetSpec('resink3', text_format, 'dummy_pipeline')]

    def dummy_pipeline(self):
        pass

class TestLocalFileSystemRepo(BaseTestCase):

    STUDY_NAME = 'local_repo'
    INPUT_FILESETS = {'source1': '1',
                      'source2': '2',
                      'source3': '3',
                      'source4': '4'}

    def test_get_fileset(self):
        pass

class TestDirectoryProjectInfo(BaseMultiSubjectTestCase):
    """
    This unittest tests out that extracting the existing scans and
    fields in a project returned in a Tree object.
    """

    DATASET_CONTENTS = {'ones': 1, 'tens': 10, 'hundreds': 100,
                        'thousands': 1000, 'with_header': {'.': 'main',
                                                           'header': 'header'}}

    def get_tree(self, dataset, sync_with_repo=False):
        filesets = [
            # Subject1
            Fileset('ones', text_format,
                    frequency='per_subject',
                    subject_id='subject1',
                    resource_name='text',
                    dataset=dataset),
            Fileset('tens', text_format,
                    frequency='per_subject',
                    subject_id='subject1',
                    resource_name='text',
                    dataset=dataset),
            # subject1/visit1
            Fileset('hundreds', text_format,
                    subject_id='subject1', visit_id='visit1',
                    resource_name='text',
                    dataset=dataset),
            Fileset('ones', text_format,
                    subject_id='subject1', visit_id='visit1',
                    resource_name='text',
                    dataset=dataset),
            Fileset('tens', text_format,
                    subject_id='subject1', visit_id='visit1',
                    resource_name='text',
                    dataset=dataset),
            Fileset('with_header', text_format,
                    frequency='per_session',
                    subject_id='subject1', visit_id='visit1',
                    resource_name='text',
                    dataset=dataset),
            # subject1/visit2
            Fileset('ones', text_format,
                    subject_id='subject1', visit_id='visit2',
                    resource_name='text',
                    dataset=dataset),
            Fileset('tens', text_format,
                    subject_id='subject1', visit_id='visit2',
                    resource_name='text',
                    dataset=dataset),
            # Subject 2
            Fileset('ones', text_format,
                    frequency='per_subject',
                    subject_id='subject2',
                    resource_name='text',
                    dataset=dataset),
            Fileset('tens', text_format,
                    frequency='per_subject',
                    subject_id='subject2',
                    resource_name='text',
                    dataset=dataset),
            # subject2/visit1
            Fileset('ones', text_format,
                    subject_id='subject2', visit_id='visit1',
                    resource_name='text',
                    dataset=dataset),
            Fileset('tens', text_format,
                    subject_id='subject2', visit_id='visit1',
                    resource_name='text',
                    dataset=dataset),
            # subject2/visit2
            Fileset('ones', text_format,
                    subject_id='subject2', visit_id='visit2',
                    resource_name='text',
                    dataset=dataset),
            Fileset('tens', text_format,
                    subject_id='subject2', visit_id='visit2',
                    resource_name='text',
                    dataset=dataset),
            # Visit 1
            Fileset('ones', text_format,
                    frequency='per_visit',
                    visit_id='visit1',
                    resource_name='text',
                    dataset=dataset),
            # Analysis
            Fileset('ones', text_format,
                    frequency='per_dataset',
                    resource_name='text',
                    dataset=dataset)]
        fields = [
            # Subject 2
            Field('e', value=3.33333,
                  frequency='per_subject',
                  subject_id='subject2',
                  dataset=dataset),
            # subject2/visit2
            Field('a', value=22,
                  subject_id='subject2', visit_id='visit2',
                  dataset=dataset),
            Field('b', value=220,
                  subject_id='subject2', visit_id='visit2',
                  dataset=dataset),
            Field('c', value='buggy',
                  subject_id='subject2', visit_id='visit2',
                  dataset=dataset),
            # Subject1
            Field('e', value=4.44444,
                  frequency='per_subject',
                  subject_id='subject1',
                  dataset=dataset),
            # subject1/visit1
            Field('a', value=1,
                  subject_id='subject1', visit_id='visit1',
                  dataset=dataset),
            Field('b', value=10,
                  subject_id='subject1', visit_id='visit1',
                  dataset=dataset),
            Field('d', value=42.42,
                  subject_id='subject1', visit_id='visit1',
                  dataset=dataset),
            # subject1/visit2
            Field('a', value=2,
                  subject_id='subject1', visit_id='visit2',
                  dataset=dataset),
            Field('c', value='van',
                  subject_id='subject1', visit_id='visit2',
                  dataset=dataset),
            # Visit 1
            Field('f', value='dog',
                  frequency='per_visit',
                  visit_id='visit1',
                  dataset=dataset),
            # Visit 2
            Field('f', value='cat',
                  frequency='per_visit',
                  visit_id='visit2',
                  dataset=dataset),
            # Analysis
            Field('g', value=100,
                  frequency='per_dataset',
                  dataset=dataset)]
        # Set URI and IDs if necessary for repository type
        if sync_with_repo:
            for fileset in filesets:
                fileset.get()
            for field in fields:
                field.get()
        tree = Tree.construct(self.dataset, filesets, fields)
        return tree

    @property
    def input_tree(self):
        return self.get_tree(self.local_dataset)

    def test_project_info(self):
        # Add hidden file (i.e. starting with '.') to local dataset at
        # project and subject levels to test ignore functionality
        a_subj_dir = os.listdir(self.project_dir)[0]
        open(op.join(op.join(self.project_dir, '.DS_Store')),
             'w').close()
        open(op.join(self.project_dir, a_subj_dir, '.DS_Store'), 'w').close()
        tree = self.dataset.tree
        for node in tree.nodes():
            for fileset in node.filesets:
                fileset.format = text_format
                fileset._resource_name = 'text'
        self.assertEqual(
            tree, self.local_tree,
            "Generated project doesn't match reference:{}"
            .format(tree.find_mismatch(self.local_tree)))


import cv2
from preprocessfunctions import illumination_compensation, remove_cursive_style
import numpy as np
from glob import glob
import csv
import os

#list of list into list
def flatten(t):
    return [item for sublist in t for item in sublist]

#returns dictionary with images and labels with train,validation,test partitions
def preprocess_iam(iam_image_filepaths, iam_label_filepath, trainset_path,validationset_path,testset_path, img_path="" , input_size=(1024,128,3)):

    def get_image_filenames(file, img_path=""):
        f = open(file)
        filenames = list(csv.reader(f))
        filenames = [''.join(name) for name in filenames]
        if img_path == "":
            pass
        else:
            file_paths=[glob(img_path + f"/**/{dir}*.png", recursive = True) for dir in filenames]
            path_list = flatten(file_paths)
            filenames = [os.path.basename(path).strip('.png') for path in path_list]
        f.close()
        return filenames

    #returns filepaths to corresponding filenames given by train,test,valid -set
    def get_image_filepaths(image_paths,image_filenames):
        filtered_paths = []

        for file in image_paths:
            if any(substring in file for substring in image_filenames):
                filtered_paths.append(file)
                continue

        return filtered_paths

#change to rwth aachen
    def preprocess_images(dataset):
        images = []

        for path in dataset:
            img = cv2.imread(path, cv2.IMREAD_UNCHANGED)
            h, w = img.shape    # ex: (89, 1661)
            w_new, h_new, _ = input_size  # (1024, 128, 1)

            scale = max((w / w_new), (h / h_new)) # scale either height or width to keep ratio
            scaled_w = int(max(min(w_new, w // scale), 0)) # ex: 1024
            scaled_h = int(max(min(h_new, h // scale), 0)) # ex: 89//1.62.. = 54
            scaled_size = (scaled_w, scaled_h) # ex : (1024, 54)

            img = illumination_compensation(img)  #standardizing imgs
            img = remove_cursive_style(img)
            img = cv2.resize(img, scaled_size) # ex: (54, 1024)

            pad = np.full((h_new, w_new), 255, dtype=np.uint8) # create white image with input size
            pad[0:scaled_size[1], 0:scaled_size[0]] = img # ex: (128, 1024), insert image into white image to creat padding # maybe get it centerd?
            #pad = np.roll(pad, h - scaled_h, axis=0) #center approach, h - scaled_h = center # wasnt so good bc not all pictures are at top?
            img = cv2.transpose(pad) # ex: (1024, 128)

            img = np.repeat(img[..., np.newaxis],3, -1) # ex: (1024, 128, 3) resnet compatibility

            images.append(img)
        return images

    def remove_whitespace(label):      # "***" problem , maybe with regex but is it nec.?           #standardizeing
        return label.replace( "|", " ").replace(" .", ".").replace(" ,", ",").replace("( ", "(") \
                    .replace(" :", ":").replace(" !", "!").replace(" ?", "?").replace(" )", ")") \
                    .replace(" '", "'")

    def preprocess_labels(label_file, image_filenames):
        f = open(label_file)
        lines = list(csv.reader(f, delimiter=" ", quoting=csv.QUOTE_NONE))[23:] #skip first 24 lines
        labels = []

        for line in lines:
            if any(substring in line[0] for substring in image_filenames):
                if len(line) > 10:    # errors in label file, problems with the delimiter
                    s = line[8] + line[9] + line[10]
                elif len(line) == 10:
                    s = line[8] + line[9]
                else:
                    s = line[8]
                clean_label = remove_whitespace(s)
                labels.append(clean_label)
                continue

        f.close()
        return labels

    def create_iam_dict(train_images,validation_images,test_images,train_labels,validation_labels,test_labels):
        iam_dict = dict()
        datasets = ['train', 'validation', 'test']

        for dataset in datasets:
            iam_dict[dataset] = {'image': [], 'label': []}

        iam_dict['train']['image'] = train_images
        iam_dict['train']['label'] = train_labels

        iam_dict['validation']['image'] = validation_images
        iam_dict['validation']['label'] = validation_labels

        iam_dict['test']['image'] = test_images
        iam_dict['test']['label'] = test_labels

        return iam_dict

    #get filepaths to corresponding images
    trainset = get_image_filepaths(iam_image_filepaths,get_image_filenames(trainset_path, img_path))
    validationset = get_image_filepaths(iam_image_filepaths,get_image_filenames(validationset_path, img_path))
    testset = get_image_filepaths(iam_image_filepaths,get_image_filenames(testset_path, img_path))
    #get labels from correct imagenames
    train_labels = preprocess_labels(iam_label_filepath, get_image_filenames(trainset_path, img_path))
    validation_labels = preprocess_labels(iam_label_filepath, get_image_filenames(validationset_path, img_path))
    test_labels = preprocess_labels(iam_label_filepath, get_image_filenames(testset_path, img_path))
    #get images
    train_images = preprocess_images(trainset)
    validation_images = preprocess_images(validationset)
    test_images = preprocess_images(testset)
    #fill dictionary
    iam_dict = create_iam_dict(train_images,validation_images,test_images,train_labels,validation_labels,test_labels)

    return iam_dict


from crypt import methods
from flask import Blueprint, jsonify, request
from flask_login import login_required, current_user
from app.models import Cart, Game, Order, User, db
from app.forms import GameForm
from app.models.order import OrderItem
from .auth_routes import validation_errors_to_error_messages

cart_routes = Blueprint('cart', __name__)

@cart_routes.route('/')
@login_required
def get_cart():
    """
    Get cart of current user
    """
    cart = Cart.query.filter(Cart.user_id==current_user.id).one()

    return jsonify(cart.to_dict())

@cart_routes.route('/', methods=['POST'])
@login_required
def add_to_cart():
    """
    Add free item to library of current user
    Add non-free item to cart of current user
    """
    item_id = request.json['item_id']

    game = Game.query.get(item_id)
    cart = Cart.query.filter(Cart.user_id==current_user.id).one()

    if game not in cart.items:
        if game.price == 0:
            new_order =  Order(
            customer=current_user,
            order_detail=[OrderItem(game=game, amount=game.price)],
            type='Purchase',
            total=0
            )
            current_user.games_owned.append(game)
            db.session.add(new_order)
            db.session.commit()
        else:
            cart.items.append(game)
            cart.total += game.price
            db.session.commit()

    return jsonify(cart.to_dict())

@cart_routes.route('/', methods=['PUT'])
@login_required
def remove_from_cart():
    """
    remove item from cart of current user
    """
    item_id = request.json['item_id']

    game = Game.query.get(item_id)
    cart = Cart.query.filter(Cart.user_id==current_user.id).one()

    if game in cart.items:
        cart.items.remove(game)
        cart.total -= game.price
        db.session.commit()

    return jsonify(cart.to_dict())

@cart_routes.route('/', methods=['DELETE'])
@login_required
def reset_cart():
    """
    checks if checking out to send to orders and
    empties all items from and reset price of cart of current user
    """
    checkout = request.json['checkout']

    # game = Game.query.get(item_id)
    cart = Cart.query.filter(Cart.user_id==current_user.id).one()

    if checkout:
        new_order = Order(
        customer=current_user,
        order_detail=[OrderItem(game=item, amount=item.price) for item in cart.items],
        type='Purchase',
        total=cart.total
        )
        current_user.games_owned.extend(cart.items)
        db.session.add(new_order)
        db.session.commit()
    cart.items = []
    cart.total = 0
    db.session.commit()
    return jsonify(cart.to_dict())
    # else:
    #     cart.items = []
    #     cart.total = 0
    #     db.session.commit()
    #     return jsonify(cart.to_dict())
        # return jsonify({'message': 'Order feature incoming'})


import os
import urllib
from datetime import timedelta, date
from urllib import request

import requests
from bs4 import BeautifulSoup
import time
import json

class Weather:
    def __init__(self):
        # Service Key 불러오기
        serviceKeyFile = open('./weather/servicekey.txt', 'r')
        self.dustKey = serviceKeyFile.readline()

        # Service Key 불러오기
        weatherServiceKeyFile = open('./weather/weatherservicekey.txt', 'r')
        self.weatherKey = weatherServiceKeyFile.readline()

        # base_date와 base_time을 위한 변수 선언
        self.time_date_Weather = time.strftime('%Y%m%d', time.localtime(time.time()))
        self.time_date_Dust = time.strftime('%Y-%m-%d', time.localtime(time.time()))

    def getWeatherHour(self):
        hours = (date.today() - timedelta(hours=2)).strftime('%H00')
        return hours

    def pm10Calculator(self, pm10):
        if pm10 == '-':
            return '없음'

        pm10 = int(pm10)

        if 0 <= pm10 <= 30:
            return '좋음'
        elif 31 <= pm10 <= 80:
            return '보통'
        elif 81 <= pm10 <= 150:
            return '나쁨'
        elif 151 <= pm10:
            return '매우 나쁨'
        else:
            return '알 수 없음'

    def pm25Calculator(self, pm25):
        if pm25 == '-':
            return '없음'

        pm25 = int(pm25)

        if 0 <= pm25 <= 15:
            return '좋음'
        elif 16 <= pm25 <= 35:
            return '보통'
        elif 36 <= pm25 <= 75:
            return '나쁨'
        elif 76 <= pm25:
            return '매우 나쁨'
        else:
            return '알 수 없음'

    def getWeatherInfo(self):
        # 날씨 크롤링을 위한 요청 메시지값들
        url = 'http://api.openweathermap.org/data/2.5/weather'
        queryParams_weather = '?' + \
                              'appid=' + self.weatherKey + \
                              '&id=1835848' + \
                              '&lang=kr' + \
                              '&units=metric'

        # 날씨 크롤링 출력
        result_weather = requests.get(url + queryParams_weather)
        bs_obj_weather = BeautifulSoup(result_weather.content, "html.parser")

        weatherJson = json.loads(str(bs_obj_weather))

        weatherData = weatherJson['weather'][0]

        mainData = weatherJson['main']

        returnData = {}
        returnData['weatherKR'] = weatherData['description']
        returnData['weather'] = weatherData['main']
        returnData['icon'] = weatherData['icon']
        returnData['temp'] = round(float(mainData['temp']))
        returnData['humidity'] = mainData['humidity']

        return returnData

    def getDustInfo(self):
        # 미세먼지 크롤링을 위한 요청 메시지값들
        url = 'http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getMsrstnAcctoRltmMesureDnsty'
        queryParams_dust = '?' + \
                           'ServiceKey=' + self.dustKey + \
                           '&returnType=' + 'JSON' + \
                           '&numOfRows=' + '1' + \
                           '&pageNo=' + '1' + \
                           '&stationName=복정동' + \
                           '&dataTerm=DAILY&ver=1.0'

        # 미세먼지 크롤링 출력
        result_dust = requests.get(url + queryParams_dust)
        bs_obj_dust = BeautifulSoup(result_dust.content, "html.parser")

        dustJson = json.loads(str(bs_obj_dust))

        dustDataList = dustJson['response']['body']['items']

        returnData = {}
        for dustData in dustDataList:
            returnData['so2'] = dustData['so2Value']
            returnData['co'] = dustData['coValue']
            returnData['o3'] = dustData['o3Value']
            returnData['no2'] = dustData['no2Value']
            returnData['pm10'] = dustData['pm10Value']
            returnData['pm25'] = dustData['pm25Value']
            break

        return returnData

    def getImage(self, weatherCode):
        url = 'http://openweathermap.org/img/wn/{0}@4x.png'.format(weatherCode)

        imageFromWeb = urllib.request.urlopen(url).read()

        return imageFromWeb


def integral_approx_estimator(x, y):
    """Integral approximation estimator for causal inference.

    :param x: input variable x 1D
    :param y: input variable y 1D
    :return: Return value of the IGCI model >0 if x->y otherwise if return <0
    """
    a, b = (0., 0.)
    x = np.array(x)
    y = np.array(y)
    idx, idy = (np.argsort(x), np.argsort(y))

    for x1, x2, y1, y2 in zip(x[[idx]][:-1], x[[idx]][1:], y[[idx]][:-1], y[[idx]][1:]):
        if x1 != x2 and y1 != y2:
            a = a + np.log(np.abs((y2 - y1) / (x2 - x1)))

    for x1, x2, y1, y2 in zip(x[[idy]][:-1], x[[idy]][1:], y[[idy]][:-1], y[[idy]][1:]):
        if x1 != x2 and y1 != y2:
            b = b + np.log(np.abs((x2 - x1) / (y2 - y1)))

    return (a - b)/len(x)


# -*- coding: utf-8 -*-
from django.utils.timezone import now
from celery import shared_task
from apps.core.models import Job, JobStatus

import json
import logging

logger = logging.getLogger(__name__)

@shared_task
def save_job_error(request, exc, traceback, job_id):
    """
    A handler task attached to the Celery chain. Any exception thrown along the
    chain will trigger this task, which logs the failure to the Job row so that
    the poling client will know that the run failed.

    To see failing task in Flower, follow instructions here:
    https://github.com/WikiWatershed/model-my-watershed/pull/551#issuecomment-119333146
    """
    error_message = 'Task {0} run from job {1} raised exception: {2}\n{3}'
    logger.error(error_message.format(str(request.id), str(job_id),
                                      str(exc),
                                      str(traceback)))
    try:
        job = Job.objects.get(id=job_id)
        job.error = exc
        job.traceback = traceback or 'No traceback'
        job.delivered_at = now()
        job.status = JobStatus.FAILED
        job.save()
    except Exception as e:
        logger.error('Failed to save job error status. Job will appear hung.'
                     f'Job Id: {job.id}')
        logger.error(f'Error: {e}')

@shared_task(bind=True)
def save_job_result(self, result, id, model_input):
    """
    Updates a job row in the database with final results.
    """
    job = Job.objects.get(id=id)
    job.result = json.dumps(result)
    job.delivered_at = now()
    job.uuid = self.request.id
    job.model_input = model_input
    job.status = JobStatus.COMPLETE
    job.save()


def remove_first(ol,value,**kwargs):
    '''
        from elist.jprint import pobj
        from elist.elist import *
        ol = [1,'a',3,'a',5,'a']
        id(ol)
        new = remove_first(ol,'a')
        ol
        new
        id(ol)
        id(new)
        ####
        ol = [1,'a',3,'a',5,'a']
        id(ol)
        rslt = remove_first(ol,'a',mode="original")
        ol
        rslt
        id(ol)
        id(rslt)
        ####array_remove is the same as remove_first
    '''
    if('mode' in kwargs):
        mode = kwargs["mode"]
    else:
        mode = "new"
    if(mode == "new"):
        new = copy.deepcopy(ol)
        new.remove(value)
        return(new)
    else:
        ol.remove(value)
        return(ol)


# Imports here
import sys
#% matplotlib inline
#% config InlineBackend.figure_format = 'retina'

import numpy as np
import matplotlib.pyplot as plt
import json

import torch
from torchvision import datasets, transforms, models
from torch import nn
from torch import optim
from collections import OrderedDict
from torch.autograd import Variable
from torch.optim import lr_scheduler

import helper
from PIL import Image
import time
import copy
import seaborn as seaborn

script = sys.argv[0]
data_dir = sys.argv[1]

gpu = False

for i in range(2,len(sys.argv),2):

    if sys.argv[i] == '--save_dir':
        save_dir = sys.argv[i+1]
    elif sys.argv[i] == '--arch':
        arch = sys.argv[i+1]
    elif sys.argv[i] == '--learning_rate':
        learning_rate = float(sys.argv[i+1])
    elif sys.argv[i] == '--hidden_units':
        hidden_units = int(sys.argv[i+1])
    elif sys.argv[i] == '--epochs':
        epochs = int(sys.argv[i+1])
    elif sys.argv[i] == '--gpu':
            gpu = True
    else:
        print("You have elected not to use all of the inputs available")

print("This is my script - ",script, type(script))
print("This is my data directory - ",data_dir, type(data_dir))
print("This is where I'll save my checkpoint - ",save_dir, type(save_dir))
print("This is my model architecture - ",arch, type(arch))
print("This is my learning rate - ",learning_rate, type(learning_rate))
print("These are my hidden units - ",hidden_units, type(hidden_units))
print("These is my number of epochs - ",epochs, type(epochs))
print("Do we use GPU? ",gpu, type(gpu))

# Define the directory and assign train, validation, and test folders
#data_dir = 'flowers'
train_dir = data_dir + '/train'
valid_dir = data_dir + '/valid'
test_dir = data_dir + '/test'

dirs = {'train' : train_dir,
        'valid' : valid_dir,
        'test' : test_dir}

# TODO: Define your transforms for the training, validation, and testing sets
data_transforms = {
    'train': transforms.Compose([
        transforms.RandomRotation(45),
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406],
                             [0.229, 0.224, 0.225])
    ]),
    'valid': transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406],
                             [0.229, 0.224, 0.225])
    ]),
    'test': transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406],
                             [0.229, 0.224, 0.225])
    ]),
}

# TODO: Load the datasets with ImageFolder
image_datasets = {x: datasets.ImageFolder(dirs[x],
transform = data_transforms[x]) for x in ['train', 'valid', 'test']}

# TODO: Using the image datasets and the trainforms, define the dataloaders
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x],
batch_size = 32, shuffle = True) for x in ['train', 'valid', 'test']}

dataset_sizes = {x: len(image_datasets[x])
                for x in ['train', 'valid', 'test']}

class_names = image_datasets['train'].classes

# Set model to use GPU if GPU was selected
if gpu == True:
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    model = model.to(device)

# Add label mapping
with open('cat_to_name.json', 'r') as f:
    cat_to_name = json.load(f)

# Import chosen model

if arch == 'vgg16':
    model = models.vgg16(pretrained=True)
elif arch == 'vgg19':
    model = models.vgg19(pretrained=True)

# Define classifier and append it to chosen model
classifier = nn.Sequential(OrderedDict([
                                ('fc1', nn.Linear(25088, 3136)),
                                ('relu', nn.ReLU()),
                                ('fc2', nn.Linear(3136, 392)),
                                ('relu', nn.ReLU()),
                                ('fc3', nn.Linear(392, 102)),
                                ('relu', nn.ReLU()),
                                ('output', nn.LogSoftmax(dim=1))
]))

for param in model.parameters():
    param.requires_grad = False

model.classifier = classifier

# Tell PyTorch to use cuda if available

model = model.to(device)

# Define how to train the model

def train_model(model, criteria, optimizer, scheduler,
                                      num_epochs=10, device='cuda'):
    since = time.time()

    best_model_wts = copy.deepcopy(model.state_dict())
    best_acc = 0.0

    for epoch in range(num_epochs):
        print('Epoch {}/{}'.format(epoch, num_epochs - 1))
        print('-' * 10)

        # Each epoch has a training and validation phase
        for phase in ['train', 'valid']:
            if phase == 'train':
                scheduler.step()
                model.train()  # Set model to training mode
            else:
                model.eval()   # Set model to evaluate mode

            running_loss = 0.0
            running_corrects = 0

            # Iterate over data.
            for inputs, labels in dataloaders[phase]:
                inputs =inputs.float()
                inputs = inputs.to(device)
                labels = labels.to(device)

                # zero the parameter gradients
                optimizer.zero_grad()

                # forward
                # track history if only in train
                with torch.set_grad_enabled(phase == 'train'):
                    outputs = model(inputs)
                    _, preds = torch.max(outputs, 1)
                    loss = criteria(outputs, labels)

                    # backward + optimize only if in training phase
                    if phase == 'train':
                        loss.backward()
                        optimizer.step()

                # statistics
                running_loss += loss.item() * inputs.size(0)
                running_corrects += torch.sum(preds == labels.data)

            epoch_loss = running_loss / dataset_sizes[phase]
            epoch_acc = running_corrects.double() / dataset_sizes[phase]

            print('{} Loss: {:.4f} Acc: {:.4f}'.format(
                phase, epoch_loss, epoch_acc))

            # deep copy the model
            if phase == 'valid' and epoch_acc > best_acc:
                best_acc = epoch_acc
                best_model_wts = copy.deepcopy(model.state_dict())

        print()

    time_elapsed = time.time() - since
    print('Training complete in {:.0f}m {:.0f}s'.format(
        time_elapsed // 60, time_elapsed % 60))
    print('Best val Acc: {:4f}'.format(best_acc))

    # load best model weights
    model.load_state_dict(best_model_wts)
    return model

# Define model inputs

criteria = nn.NLLLoss()

# Observe that all parameters are being optimized
optim = optim.Adam(model.classifier.parameters(), lr=learning_rate)

# Decay LR by a factor of 0.1 every 4 epochs
sched = lr_scheduler.StepLR(optim, step_size=4, gamma=0.1)

# Number of epochs
eps=epochs

# Train the model

model_trained = train_model(model, criteria, optim, sched, eps, 'cuda')

# TODO: Do validation on the test set

# Define accuracy evaluation

def calc_accuracy(model, data, cuda=False):
    model.eval()
    model.to(device='cuda')

    with torch.no_grad():
        for idx, (inputs, labels) in enumerate(dataloaders[data]):
            if cuda:
                inputs, labels = inputs.cuda(), labels.cuda()
            # get model outputs
            outputs = model.forward(inputs)
            # convert outputs to predictions
            _, predicted = outputs.max(dim=1)

            if idx == 0:
                print(predicted) # class
                print(torch.exp(_)) # probability
            equals = predicted == labels.data
            if idx == 0:
                print(equals)
            print(equals.float().mean())

# Check accuracy on validation set
calc_accuracy(model, 'test', True)

# TODO: Save the checkpoint
model.class_to_idx = image_datasets['train'].class_to_idx
model.cpu()
torch.save({'arch': arch,
            'state_dict': model.state_dict(),
            'class_to_idx': model.class_to_idx},
            save_dir)


from core.datasetmanager import DatasetManager

datasetName = 'sample:1'
print('Print %s' % (datasetName))
with DatasetManager.open('sample:1') as f:
    print('- Data ----------')
    print(f.read())

datasetName = 'data:1'
print('Print %s' % (datasetName)  )
with DatasetManager.open('data:1') as f:
    print('- Data ----------')
    print(f.read())

#print( DatasetManager.open('sample:lastest').read() )

experiment1 = {
     "inputA": "sample",
     "output1": "preprocessed",
     "log": "zz"
}

#print( DatasetManager.getDataset('${experiment1.inputA}' ))
#with DatasetManager.open('${experiment1.inputA}') as f:
#    print(f.read())


"""added new columns ot_start_datetime, ot_end_datetime into ot_compensation_rate table

Revision ID: 84f06a175104
Revises: 9f44a49274c5
Create Date: 2021-11-04 09:41:21.190013

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '84f06a175104'
down_revision = '9f44a49274c5'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('ot_compensation_rate', sa.Column('ot_end_datetime', sa.DateTime(timezone=True), nullable=True))
    op.add_column('ot_compensation_rate', sa.Column('ot_start_datetime', sa.DateTime(timezone=True), nullable=True))
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('ot_compensation_rate', 'ot_start_datetime')
    op.drop_column('ot_compensation_rate', 'ot_end_datetime')
    # ### end Alembic commands ###


def combinefiles(filepath):
    """ Joins first and second read file names """
    ## unpack seq files in filepath
    fastqs = glob.glob(filepath)
    firsts = [i for i in fastqs if "_R1_" in i]

    ## check names
    if not firsts:
        raise IPyradWarningExit("First read files names must contain '_R1_'.")

    ## get paired reads
    seconds = [ff.replace("_R1_", "_R2_") for ff in firsts]
    return zip(firsts, seconds)


import tensorflow.compat.v1 as tf

FLAGS = tf.flags.FLAGS

tf.flags.DEFINE_string("input_graph", "model/frozen_graph.pb",
                       "File name for the frozen graph data.")

tf.flags.DEFINE_string("logs_dir", "model/Hugh/logs",
                       "Output logs directory.")

with tf.Session() as sess:
    with tf.io.gfile.GFile(FLAGS.input_graph, 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        g_in = tf.import_graph_def(graph_def)

    train_writer = tf.summary.FileWriter(FLAGS.logs_dir)
    train_writer.add_graph(sess.graph)

print('You can now run tensorboard --logdir model/Hugh/logs')


import json
import logging
from logging.handlers import RotatingFileHandler
from flask import Flask
from flask import request
from operator import add, sub, mul, div

app = Flask(__name__)

OPS = {'add': add, 'subtract': sub, 'multiply': mul, 'divide': div}
ERROR = 'error'
RESULT = 'result'

@app.route('/equals', methods=['POST'])
def calc_endpoint():
    x = request.args.get('x')
    y = request.args.get('y')
    op = request.args.get('op')
    if not (x and y and op):
        return json.dumps({ERROR: 'Missing an operand or operator.'}), 500
    if op not in OPS:
        return json.dumps({ERROR: 'Invalid operator.'}), 500
    try:
        result = OPS[op](float(x), float(y))
    except ValueError as e:
        return json.dumps({ERROR: 'Operands must be numbers.'}), 500
    return json.dumps({RESULT: result})

def main():
    handler = RotatingFileHandler('logs/caas.log', maxBytes=1024*10, backupCount=10)
    handler.setLevel(logging.INFO)
    log = logging.getLogger('werkzeug')
    log.setLevel(logging.INFO)
    log.addHandler(handler)
    app.run(host='0.0.0.0', port=5000, debug=False)

if __name__ == '__main__':
    main()


from functools import partial
from typing import (List,
                    Optional,
                    Tuple)

from ground.hints import (Box,
                          Scalar)
from hypothesis import strategies

from locus.core.hilbert import MAX_COORDINATE
from locus.r import Tree
from tests.strategies import (scalars_strategies,
                              to_boxes,
                              to_points)
from tests.utils import (Point,
                         Strategy)

MIN_BOXES_SIZE = 2
max_children_counts = (strategies.sampled_from([2 ** power
                                                for power in range(1, 10)])
                       | strategies.integers(2, MAX_COORDINATE))
boxes_strategies = scalars_strategies.map(to_boxes)
boxes_lists = (boxes_strategies
               .flatmap(partial(strategies.lists,
                                min_size=MIN_BOXES_SIZE)))
trees = strategies.builds(Tree,
                          boxes_lists,
                          max_children=max_children_counts)

def scalars_to_trees_with_boxes(scalars: Strategy[Scalar],
                                *,
                                min_size: int = MIN_BOXES_SIZE,
                                max_size: Optional[int] = None
                                ) -> Strategy[Tuple[Tree, Box]]:
    boxes = to_boxes(scalars)
    return strategies.tuples(
            strategies.builds(Tree,
                              strategies.lists(boxes,
                                               min_size=min_size,
                                               max_size=max_size),
                              max_children=max_children_counts),
            boxes)

trees_with_boxes = scalars_strategies.flatmap(scalars_to_trees_with_boxes)

def scalars_to_trees_with_points(scalars: Strategy[Scalar],
                                 *,
                                 min_size: int = MIN_BOXES_SIZE,
                                 max_size: Optional[int] = None
                                 ) -> Strategy[Tuple[Tree, Point]]:
    return (strategies.tuples(
            strategies.builds(Tree,
                              strategies.lists(to_boxes(scalars),
                                               min_size=min_size,
                                               max_size=max_size),
                              max_children=max_children_counts),
            to_points(scalars)))

trees_with_points = scalars_strategies.flatmap(scalars_to_trees_with_points)

def scalars_to_trees_with_points_and_sizes(
        scalars: Strategy[Scalar],
        *,
        min_size: int = MIN_BOXES_SIZE,
        max_size: Optional[int] = None) -> Strategy[Tuple[Tree, Point, int]]:
    def boxes_with_point_to_trees_with_points_and_sizes(
            boxes_with_point: Tuple[List[Box], Point]
    ) -> Strategy[Tuple[Tree, Point, int]]:
        boxes, point = boxes_with_point
        return strategies.tuples(
                strategies.builds(Tree,
                                  strategies.just(boxes),
                                  max_children=max_children_counts),
                strategies.just(point),
                strategies.integers(1, len(boxes)))

    return (strategies.tuples(
            strategies.lists(to_boxes(scalars),
                             min_size=min_size,
                             max_size=max_size),
            to_points(scalars))
            .flatmap(boxes_with_point_to_trees_with_points_and_sizes))

trees_with_points_and_sizes = (
    scalars_strategies.flatmap(scalars_to_trees_with_points_and_sizes))