#needed for CERTIFICATE_VERIFY_FAILED in downloading nltk
import ssl
try:
    _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    pass
else:
    ssl._create_default_https_context = _create_unverified_https_context
#####

from math import log10, sqrt
from linecache import getline
import nltk
import heapq

nltk.download('punkt')
nltk.download('stopwords')
nltk.download('wordnet')

from nltk.tokenize import RegexpTokenizer
from nltk.corpus import stopwords
from nltk.stem.snowball import SnowballStemmer

##---------------- UTILS: functions ----------------##

#merge between 2 posting lists
def intersect2lists(p1,p2):
    answer=[]
    i1=0
    i2=0
    while(i1 < len(p1) and i2<len(p2)):
        if(p1[i1][0]==p2[i2][0]):   #doc_ID1==doc_ID2
            answer.append([p1[i1][0]])    #doc_id
            i1=i1+1
            i2=i2+1
        elif(p1[i1][0]<p2[i2][0]):
            i1=i1+1
        else:
            i2=i2+1
    return answer

#merge between ALL postings
def boolean_search(query_terms,index):
    j=0
    n_query=len(query_terms)
    exception=True
    answer=[]
    while(exception):
        try:
            answer=index[query_terms[j]][1:]
            exception=False
        except:
            j=j+1
            if(j>n_query):
                answer=[]
                return answer
    for i in range(j+1,len(query_terms)):
        try:
            index[query_terms[i]]
            answer=intersect2lists(answer,index[query_terms[i]][1:])
        except:
            continue
    docs=[]
    for val in answer:
        docs.append(val[0])
    return docs

#union between 2 postings
def union2lists(p1,p2):
    answer=[]
    i1=0
    i2=0
    while(i1 < len(p1) and i2<len(p2)):
        if(p1[i1][0]==p2[i2][0]):   #doc_ID1==doc_ID2
            answer.append([p1[i1][0]])    #doc_id
            i1=i1+1
            i2=i2+1
        elif(p1[i1][0]<p2[i2][0]):
            answer.append([p1[i1][0]])
            i1=i1+1
        else:
            answer.append([p2[i2][0]])
            i2=i2+1

    #if one list terminated and the other not
    while(i1 < len(p1)):
        answer.append([p1[i1][0]])
        i1=i1+1
    while(i2 < len(p2)):
        answer.append([p2[i2][0]])
        i2=i2+1
    return answer

#return all docs with AT LEAST one query term
def union_search(query_terms,index):
    j=0
    n_query=len(query_terms)
    exception=True
    answer=[]
    while(exception):
        try:
            answer=index[query_terms[j]][1:]
            exception=False
        except:
            j=j+1
            if(j>n_query):
                answer=[]
                return answer
    for i in range(j+1,len(query_terms)):
        try:
            index[query_terms[i]]
            answer=union2lists(answer,index[query_terms[i]][1:])
        except:
            continue
    docs=[]
    for val in answer:
        docs.append(val[0])
    return docs

def search(query_terms, index, bool):
    if(bool):
        #AND of docIDs (docs containing all terms)
        return boolean_search(query_terms,index)
    else:
        #OR of docIDs (docs containing at least one term)
        return union_search(query_terms,index)

#computes query length
def query_len(query_terms,index,docs):
    score=0
    for term, occ in query_terms.items():
        try:
            tf_idf=log10(occ + 1)*log10(docs/index[term][0][0])
            score=score + tf_idf*tf_idf
        except:
            #term not in the index
            continue
    return sqrt(score)

#cosine similarity scores computation
def cos_sim(query_terms,index,n_docs,docs,query_len):
    scores={}
    for term, occ in query_terms.items():
        w_tq=log10(1+int(occ))
        df=0
        try:
            df=int(index[term][0][0])
        except:
            continue

        for posting in index[term][1:]:
            doc_id=posting[0]
            tf=posting[1]
            if doc_id not in docs:
                continue
            w_td=log10(1+int(tf))
            idf=log10(n_docs/df)
            scores[doc_id]=scores.get(doc_id,0) + float(w_td * idf * w_tq * idf)

    for doc in scores.keys():
        scores[doc]=scores[doc] /(float(lengths[doc-1])*query_len)

    return scores

def top_k(scores,k):
    l=0
    heap=[]
    for docID,score in scores.items():
        if(l<k):
            heapq.heappush(heap,(score,docID))
            l=l+1
        elif(score>=heap[0][0]):
            heapq.heappushpop(heap,(score,docID))

    sorted_docs=heapq.nlargest(k,heap)
    return sorted_docs

#loading the index from the file
def load_index():
    index= {}     #dictionary: (term,[postings list]), posting list=[docID,tf], posting list[0]=[df,0]
    with open("index_file.tsv", "r") as index_file:
        n_docs=0
        lengths=[]
        l=0
        for line in index_file:
            if(l==0):
                n_docs=int(line) #total number of documents
                l=l+1
                continue
            if(l==1):
                lengths=line.split("\t")[1:]
                l=l+1
                continue

            fields=line.split("\t")
            term=fields[0]
            df=int(fields[1])
            index[term]=[[df,0]]
            for i in range(2,2+df):
                posting=fields[i].split(",")
                doc_ID=int(posting[0])
                tf=int(posting[1])
                index[term].append([doc_ID,tf])
    return index, lengths, n_docs

##---------------- MAIN ----------------##

index, lengths, n_docs = load_index()

#query processing
stop_words = set(stopwords.words('italian'))
stemmer = SnowballStemmer(language='italian')
tokenizer = RegexpTokenizer(r"[a-zA-Z]+")

print(" ____________________________")
print("|                            |")
print("| Eva's simple search engine |")
print("|____________________________|")
print("This is a simple search engine for kijiji jobs announcements, \n feel free to insert queries or type 'q' if you want to quit \n Enjoy! =) \n")
while(1):
    query=input("What are you looking for? ")
    if(query=='q'):
        print("Bye, have a nice day!")
        break

    tokens = tokenizer.tokenize(query)
    query_terms={}
    for w in tokens:
        if w not in stop_words and len(w)>1:
            w=w.lower()
            term=stemmer.stem(w)
            if term not in query_terms:
                query_terms[term]=1
            else:
                occ=query_terms[term]
                query_terms[term]=occ+1

    keys=list(query_terms.keys())
    query_length=query_len(query_terms,index,n_docs)

    #docs=search(keys,index, True)      #if you want to test the search engine in boolean search (true)
    docs=search(keys,index, False)

    scored_docs=cos_sim(query_terms,index,n_docs,docs,query_length)
    top_10=top_k(scored_docs,10)

    #results
    results=len(top_10)
    if(results==0):
        print("Sorry, there is NO Document matching your query, try with another formulation!")
    else:
        print(str(len(docs))+" results found, showing the TOP-10:")

    for i in range(results):
        doc=top_10[i][1]
        score=top_10[i][0]
        print("------------------------------------")
        print(str(i+1)+". doc_ID: "+str(doc)+" score:"+"{0:.3f}".format(score))
        print(getline("jobs.tsv",doc))
        print("------------------------------------")


#!/usr/bin/python3
"""This module adds all arguments to a Python list and saves them to a file."""

import sys
from typing import List

def add_items_to_list_and_save(items: List[str], filename: str) -> None:
    save_to_json_file = __import__('5-save_to_json_file').save_to_json_file
    load_from_json_file = __import__('6-load_from_json_file').load_from_json_file

    try:
        current_items = load_from_json_file(filename)
    except FileNotFoundError:
        current_items = []

    updated_items = current_items + items
    save_to_json_file(updated_items, filename)

if __name__ == "__main__":
    args = sys.argv[1:]
    add_items_to_list_and_save(args, "add_item.json")


from PIL import Image
# loading labels and img info
class ImgInfo:
    def __init__(self, line):
       [num, info] = line.split(':')
       self.name = None
       self.left = 100000
       self.top = 100000
       self.right = 0
       self.bottom = 0
       self.label = ''
       self.set_name(num)
       self.identify_bounding_box_and_label(info)

    def set_name(self, num):
       self.name = num+'.png'

    def identify_bounding_box_and_label(self, info):
        #input argument info composes of multiple strings of "height, left, top, width;", delimited by semicolon
        digit_positions = info.split(";")
        for digit_position in digit_positions[:-1]:
            position_info = digit_position.split(",")
            # identify bounding box
            d_height = int(position_info[0])
            d_left = int(position_info[1])
            d_top = int(position_info[2])
            d_width = int(position_info[3])
            d_right = d_left+d_width
            d_bottom = d_top+d_height
            self.left = min(self.left, d_left)
            self.top = min(self.top, d_top)
            self.right = max(self.right, d_right)
            self.bottom = max(self.bottom, d_bottom)
            # identify label
            d_label = position_info[4]
            if d_label == '10':
                d_label = '0'
            self.label += d_label
        # now we identify the smallest area which covers all the digits in the image
        # expand the bounding box by 30% in both x and y directions
        width = self.right - self.left
        height = self.bottom - self.top
        self.left = int(self.left - width*0.15)
        self.top = int(self.top - height*0.15)
        self.right = int(self.right + width*0.15)
        self.bottom = int(self.bottom + height*0.15)

    def __str__(self):
       return "name: "+self.name+" label: "+self.label+" left: "+str(self.left)+" top: "+str(self.top)+" right: "+str(self.right)+" bottom: "+str(self.bottom)

def crop_images(image_path, image_info_file):
    counter = 0
    with open(image_info_file) as f:
        for line in f:
            counter+=1
            img_info = ImgInfo(line)
            print(img_info)
            img = Image.open(image_path+img_info.name)
            width, height = img.size
            img2 = img.crop((max(img_info.left, 0), max(img_info.top, 0), min(img_info.right, width), min(img_info.bottom, height)))
            img2 = img2.resize((64, 64), Image.ANTIALIAS)
            img2.save(str(counter)+'_'+img_info.label+'.png')

if __name__=="__main__":
    image_info_file = 'test_labels'
    image_path = '/home/lwy/test_process/images/'
    crop_images(image_path, image_info_file)


import heapq
from typing import List

class MeetingRoomsII:
    def minMeetingRooms(self, intervals: List[List[int]]) -> int:
        intervals.sort(key=lambda k:k[0])
        pq=[]

        for s,e in intervals:
            if pq and s>=pq[0]:
                heapq.heappushpop(pq, e)
            else:
                heapq.heappush(pq, e)
        return len(pq)

if __name__ == "__main__":
    init = MeetingRoomsII()
    print(init.minMeetingRooms([[0, 30], [5, 10], [15, 20]]))
    print(init.minMeetingRooms([[7, 10], [2, 4]]))


import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
from bullet import Bullet1

def run_game():
    # 初始化
    pygame.init()
    pygame.display.set_caption('Plane Battle')
    game_settings = Settings()
    screen = pygame.display.set_mode(
        (game_settings.screen_width, game_settings.screen_height))

    # 创造飞船
    ship = Ship(game_settings, screen)
    bullet1 = []
    BULLET1_NUM = 1
    for i in range(BULLET1_NUM):
        new_bullet = Bullet1(game_settings, screen, ship)
        bullet1.append(new_bullet)

    # 延迟
    delay = 100
    # 开始游戏主循环
    while True:
        # 监听键盘鼠标事件
        gf.check_events(ship)
        # 刷新飞船
        x = ship.update()

        if delay % 10:
            for bullet in bullet1:
                bullet.update(x)

        delay -= 1
        if not delay:
            delay = 100
        # 刷新页面
        gf.update_screen(game_settings, screen, ship, bullet1)

run_game()


# ************************** General Fixmes (In Order) *********************************
# Value Function Ideas:
# -- Adance in Mass: group clusters or two checkers next to each other?
# -- Take the Center of the Board: ??? Distance to Center if not a king and in your first row???
# -- Change distance to last row to either distance to most exposed last row piece or open last row space

# FIXME: MUST FIX VALUE FUNCTION TO HAVE AI CAPTURE PIECES WHEN THEY ARE FAR AWAY AT END OF GAME
# FIXME: MUST RESEARCH REINFORCEMENT LEARNING ALGORITHMS AND HOW TO SET REWARDS AND UPDATE FUNCTION
# FIXME: MUST RESEARCH WHAT OTHER PEOPLE HAVE DONE TO SEE IF I SHOULD USE A LINEAR MODEL OR A NEURAL NETWORK (ALONG WITH STRUCTURE)
# FIXME: MUST TRAIN MODEL VS MINIMAX SEARCH
# FIXME: MUST LOOKUP WHETHER OR NOT I CAN USE A CHECKERS API TO TEST MY MODEL
# FIXME: MUST LIMIT USER MOVE CHOICES SO MUST TAKE JUMP IF ONE IS AVAILABLE (ONLY THE AI HAS TO DO THIS NOW)
# **************************************************************************************

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Color
from kivy.core.window import Window
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.config import Config
from copy import deepcopy
from gc import collect
from sys import argv
#******************************
from config import windowSize, rows, cols, redMoveDir, blackMoveDir, pieceSize, dummyColor, \
    lightSqrColor, darkSqrColor, moveLimit, moveRate
from point import Point
from gamePiece import GamePiece, Pawn, King
from sqr import Sqr
from referee import Referee
from minimaxSearch import Tree, minimax, alphaMin, betaMax, randomMove
from testFunctions import ptListPrintStr
#******************************

# ***Important Notes***
# cols = x
# rows = y
# pieceGrid[x][y] = pieceGrid[col][row] = pieceGrid[j][i] (with j outer and i inner)
# for cols (for rows) = for x (for y)

dummyMove = (Point(-1, -1), [])

# *****Command Line Arguments******
normalMode = True
if len(argv) == 2:
    if str(argv[1]) == "random":
        normalMode = False
# *********************************

class CheckersGame(GridLayout):
    def __init__(self, **kwargs):
        super(CheckersGame, self).__init__(**kwargs)
        # first coordinate is x and second is y
        # 0,0 is the bottom left square
        self.gameGrid = []  # for centerpoints of squares
        self.pieceGrid = []  # for locs of pieces
        self.sqrGrid = []
        self.redList = []
        self.blackList = []
        self.board = RelativeLayout()
        self.board.pos = ((Window.height/10), (Window.height/10))
        self.board.size = (8*(Window.height/10), 8*(Window.height/10))
        self.add_widget(self.board)

        self.pieces = RelativeLayout()
        self.pieces.pos = ((Window.height/10), (Window.height/10))
        self.pieces.size = (8*(Window.height/10), 8*(Window.height/10))
        self.add_widget(self.pieces)

        self.selected = Point(-1, -1)
        self.referee = Referee()
        self.turn = "None"
        self.lightSqrs = []
        self.selectedSqr = Point(-1, -1)
        self.moveCount = 0
        self.alreadyCaptured = False
        self.isJumping = False
        self.prevMoveMax = dummyMove
        self.prevPrevMoveMax = dummyMove
        self.prevMoveMin = dummyMove
        self.prevPrevMoveMin = dummyMove
        self.tempCurrPtMin = Point(-1, -1)
        self.tempCurrEndPtsMin = []

        self.redPiecePt = Point(-1, -1)
        self.redEndPts = []

        fstColor = dummyColor
        fstColorName = "None"
        sndColor = dummyColor
        sndColorName = "None"
        for x in range(cols):
            currColGame = [] #append from bottom (y = 0) to top (y = 7)
            currColPiece = [] #for dummys in pieceGrid
            currColSqr = [] #for board square rectangles
            for y in range(int(rows/2)):
                if (x % 2) == 0:
                    fstColor = darkSqrColor
                    fstColorName = "dark"
                    sndColor = lightSqrColor
                    sndColorName = "light"
                else:
                    fstColor = lightSqrColor
                    fstColorName = "light"
                    sndColor = darkSqrColor
                    sndColorName = "dark"

                #Color(*fstColor)
                sqrPos = (x * (self.board.height / 8.0), (y * 2.0) * (self.board.height / 8.0))
                sqrSize = (self.board.height / 8.0, self.board.height / 8.0)
                currColSqr.append(Sqr(fstColorName, Point(x, y * 2), sqrPos, sqrSize, self.board.canvas))
                centerPt = Point(x * (self.board.height / 8.0) + (self.board.height / 8.0) / 2.0,  (y * 2.0) * (self.board.height / 8.0) + (self.board.height / 8.0) / 2.0)
                currColGame.append(centerPt)
                currColPiece.append(GamePiece(dummyColor, Point(x, (y * 2)), self.pieces.canvas, -1, self.pieceGrid, self.gameGrid))

                #Color(*sndColor)
                sqrPos = (x * (self.board.height / 8.0), (y * 2.0 + 1.0) * (self.board.height / 8.0))
                sqrSize = (self.board.height / 8.0, self.board.height / 8.0)
                currColSqr.append(Sqr(sndColorName, Point(x, (y * 2 + 1)), sqrPos, sqrSize, self.board.canvas))
                centerPt = Point(x * (self.board.height / 8.0) + (self.board.height / 8.0) / 2.0, (y * 2.0 + 1.0) * (self.board.height / 8.0) + (self.board.height / 8.0) / 2.0)
                currColGame.append(centerPt)
                currColPiece.append(GamePiece(dummyColor, Point(x, (y * 2 + 1)), self.pieces.canvas, -1, self.pieceGrid, self.gameGrid))

            self.gameGrid.append(currColGame)
            self.pieceGrid.append(currColPiece)
            self.sqrGrid.append(currColSqr)

        self.btn = Button(text='New Game', font_size=14, background_color=(1, 0, 0, 1), pos=(0, 0), size=(Window.height / 10, Window.height / 10))
        self.add_widget(self.btn)
        self.btn.bind(on_press=self.startingPieces)

    def clearPiece(self, pieceIn):
        self.pieces.canvas.remove(pieceIn.shape)
        return

    def startingPieces(self, instance):
        #handles pieceGrid, redList, and blackList
        #make sure board was cleared before if restarting
        self.clearBoard("dummy input")
        #create all pieces
        #creating black pieces
        firstY = 0
        lastY = 0
        if blackMoveDir == 1:
            firstY = 0
            lastY = 2
        else:
            firstY = 5
            lastY = 7
        pieceNum = 0
        for y in range(firstY, lastY + 1):
            for x in range(int(cols/2)):
                self.pieceGrid[x * 2 + (y % 2)][y] = Pawn("black", Point(x * 2 + (y % 2), y), self.pieces.canvas, pieceNum, self.pieceGrid, self.gameGrid)
                self.blackList.append(pieceNum)
                pieceNum += 1
        #creating red pieces
        if redMoveDir == -1:
            firstY = 5
            lastY = 7
        else:
            firstY = 0
            lastY = 2
        for y in range(firstY, lastY + 1):
            for x in range(int(cols / 2)):
                self.pieceGrid[x * 2 + (y % 2)][y] = Pawn("red", Point(x * 2 + (y % 2), y), self.pieces.canvas, pieceNum, self.pieceGrid, self.gameGrid)
                self.redList.append(pieceNum)
                pieceNum += 1
        print("Done creating pieces...")
        self.turn = "black"
        print(" { Black's Turn }")
        return

    def clearBoard(self, instance):
        #clear all current pieces from board
        # handles pieceGrid, redList, and blackList
        for x in range(cols):
            for y in range(rows):
                if (self.pieceGrid[x][y].type != "None"):
                    self.clearPiece(self.pieceGrid[x][y])
                    self.pieceGrid[x][y] = GamePiece(dummyColor, Point(x, y), self.pieces.canvas, -1, self.pieceGrid, self.gameGrid)
        #now must clear redList and blackList
        self.redList.clear()
        self.blackList.clear()
        self.selected = Point(-1, -1)
        self.turn = "None"
        self.lightSqrs = []
        self.selectedSqr = Point(-1, -1)
        self.moveCount = 0
        self.alreadyCaptured = False
        self.isJumping = False
        self.prevMoveMax = dummyMove
        self.prevPrevMoveMax = dummyMove
        self.prevMoveMin = dummyMove
        self.prevPrevMoveMin = dummyMove

        return

    def selectObj(self, pt):
        if (pt != Point(-1, -1)):
            #actual piece is selected
            if (self.pieceGrid[pt.x][pt.y].type != "None"):
                #game piece and not square
                if self.pieceGrid[pt.x][pt.y].type == "pawn":
                    self.pieces.canvas.remove(self.pieceGrid[pt.x][pt.y].shape)
                    self.pieces.canvas.add(Color(*self.pieceGrid[pt.x][pt.y].highlightColor))
                    self.pieces.canvas.add(self.pieceGrid[pt.x][pt.y].shape)
                else:
                    self.pieceGrid[pt.x][pt.y].shape.source = self.pieceGrid[pt.x][pt.y].highlightColor
                self.selected = pt
        return
    def deselectObj(self):
        if (self.selected != Point(-1, -1)):
            #actual piece or sqr is selected
            if self.pieceGrid[self.selected.x][self.selected.y].type != "None":
                #game piece selected
                if self.pieceGrid[self.selected.x][self.selected.y].type == "pawn":
                    self.pieces.canvas.remove(self.pieceGrid[self.selected.x][self.selected.y].shape)
                    self.pieces.canvas.add(Color(*self.pieceGrid[self.selected.x][self.selected.y].guiPColor))
                    self.pieces.canvas.add(self.pieceGrid[self.selected.x][self.selected.y].shape)
                else:
                    self.pieceGrid[self.selected.x][self.selected.y].shape.source = self.pieceGrid[self.selected.x][self.selected.y].guiPColor

                self.delHighlightSqrs()
                self.selected = Point(-1, -1)
        return

    def highlightSqrs(self, ptList):
        #highlight sqrs for possible moves based on selected piece
        for pt in ptList:
            self.board.canvas.remove(self.sqrGrid[pt.x][pt.y].shape)
            self.board.canvas.add(Color(*self.sqrGrid[pt.x][pt.y].highlightColor))
            self.board.canvas.add(self.sqrGrid[pt.x][pt.y].shape)
            self.lightSqrs.append(pt)
        return

    def delHighlightSqrs(self):
        #stored in self.lightSqrs
        if self.lightSqrs: #self.lightSqrs is not an empty list
            for pt in self.lightSqrs:
                self.board.canvas.remove(self.sqrGrid[pt.x][pt.y].shape)
                self.board.canvas.add(Color(*self.sqrGrid[pt.x][pt.y].normColor))
                self.board.canvas.add(self.sqrGrid[pt.x][pt.y].shape)
                self.lightSqrs = []
        return

    def on_touch_down(self, touch):
        #will check for possible moves before selecting here
        #will not select if no moves are possible or if its not the color's turn
        if (touch.x > self.board.pos[0]) and (touch.x < (Window.height - self.board.pos[0])) and (touch.y > self.board.pos[1]) and (touch.y < (Window.height - self.board.pos[1])):
            #determine which square for piece
            #get x pos
            print((touch.x, touch.y))
            x = (touch.x - self.board.pos[0]) / (self.board.height / 8.0)
            x = int(x)
            #get y pos
            y = (touch.y - self.board.pos[1]) / (self.board.height / 8.0)
            y = int(y)
            pt = Point(x, y)
            if self.selectedSqr == Point(-1, -1):
                if (self.pieceGrid[x][y].type != "None") and (self.isJumping == False):
                    # Clicked Piece"
                    if (self.pieceGrid[x][y].pColor == self.turn):
                        if (self.selected != pt):
                            #select object
                            #deselect selected piece
                            self.deselectObj()
                            #select new piece
                            self.selectObj(pt)
                            #now must highlightSqrs(list) any possible move sqrs
                            howCanMoveRslt = self.referee.howCanMove(pt, self.pieceGrid) #returns a list of possible moves (in pt form) for current piece at pt
                            endPts = howCanMoveRslt[0]
                            if endPts:
                                self.highlightSqrs(endPts)

                        else:
                            #second click to deselect already selected obj
                            self.deselectObj()
                            #now must deHighlightSqrs() any self.lightSqrs from prev. selection

                else:
                    # Clicked Sqr
                    #(must be able to select highlighted squares for next move)
                    if pt in self.lightSqrs:
                        # can select square
                        self.selectedSqr = pt
                        if self.tempCurrPtMin == Point(-1, -1):
                            self.tempCurrPtMin = self.selected
                        self.tempCurrEndPtsMin.append(pt)
                        #set self.isJumping to true if jumping here
                        if abs(self.selectedSqr.x - self.selected.x) > 1:
                            #jumping
                            self.isJumping = True

        elif (touch.x > 0) and (touch.x < self.board.pos[0]) and (touch.y > 0) and (touch.y < self.board.pos[1]):
            self.startingPieces("dummy instance")

        return

    def capture(self, pt):
        print(" * Piece Captured *")
        self.pieces.canvas.remove(self.pieceGrid[pt.x][pt.y].shape)
        if self.pieceGrid[pt.x][pt.y].pColor == "black":
            self.blackList.remove(self.pieceGrid[pt.x][pt.y].pieceNum)
        else:
            self.redList.remove(self.pieceGrid[pt.x][pt.y].pieceNum)
        self.pieceGrid[pt.x][pt.y] = GamePiece(dummyColor, pt, self.pieces.canvas, -1, self.pieceGrid, self.gameGrid)
        self.alreadyCaptured = True

    def pawnToKing(self):
        if self.pieceGrid[self.selected.x][self.selected.y].type == "pawn":
            samePColor = self.pieceGrid[self.selected.x][self.selected.y].pColor
            samePieceNum = self.pieceGrid[self.selected.x][self.selected.y].pieceNum
            self.pieces.canvas.remove(self.pieceGrid[self.selected.x][self.selected.y].shape)
            self.pieceGrid[self.selected.x][self.selected.y] = GamePiece(dummyColor, self.selected, self.pieces.canvas, -1, self.pieceGrid, self.gameGrid)
            self.pieceGrid[self.selected.x][self.selected.y] = King(samePColor, self.selected, self.pieces.canvas, samePieceNum, self.pieceGrid, self.gameGrid)

            self.selected = Point(-1, -1)
        else:
            print(" << ERROR: pawnToKing CALLED ON KING PIECE >>")

        return

    def movePiece(self):
        currCenterPt = Point(self.pieceGrid[self.selected.x][self.selected.y].pos[0] + (pieceSize[0] / 2), self.pieceGrid[self.selected.x][self.selected.y].pos[1] + (pieceSize[1] / 2))
        if currCenterPt != self.gameGrid[self.selectedSqr.x][self.selectedSqr.y]:
            # not there yet so keep moving piece
            xMoveDir = 0
            yMoveDir = 0
            if currCenterPt.x < self.gameGrid[self.selectedSqr.x][self.selectedSqr.y].x:
                xMoveDir = 1
            else:
                xMoveDir = -1
            if currCenterPt.y < self.gameGrid[self.selectedSqr.x][self.selectedSqr.y].y:
                yMoveDir = 1
            else:
                yMoveDir = -1
            xInc = 0
            yInc = 0
            if abs(xMoveDir * moveRate) < abs(self.gameGrid[self.selectedSqr.x][self.selectedSqr.y].x - currCenterPt.x):
                xInc = xMoveDir * moveRate
            else:
                xInc = self.gameGrid[self.selectedSqr.x][self.selectedSqr.y].x - currCenterPt.x
            if abs(yMoveDir * moveRate) < abs(self.gameGrid[self.selectedSqr.x][self.selectedSqr.y].y - currCenterPt.y):
                yInc = yMoveDir * moveRate
            else:
                yInc = self.gameGrid[self.selectedSqr.x][self.selectedSqr.y].y - currCenterPt.y
            currX = self.pieceGrid[self.selected.x][self.selected.y].pos[0]
            currY = self.pieceGrid[self.selected.x][self.selected.y].pos[1]
            self.pieceGrid[self.selected.x][self.selected.y].pos = (currX + xInc, currY + yInc)

            #handle collisions here
            if abs(self.selectedSqr.x - self.selected.x) > 1:
                if self.alreadyCaptured == False:
                    #jump so there will be a collision either now or after it has moved some
                    #collide_widget doesn't work
                    #find collision centerPt
                    collisionLoc = Point(self.selected.x + int((self.selectedSqr.x - self.selected.x) / 2), self.selected.y + int((self.selectedSqr.y - self.selected.y) / 2))
                    collisionCenterPt = self.gameGrid[collisionLoc.x][collisionLoc.y]
                    #check if moving piece is within a certain distance of centerPt
                    currCenterPt = Point(self.pieceGrid[self.selected.x][self.selected.y].pos[0] + (pieceSize[0] / 2), self.pieceGrid[self.selected.x][self.selected.y].pos[1] + (pieceSize[1] / 2))
                    if (abs(collisionCenterPt.x - currCenterPt.x) < ((pieceSize[0] / 2) - 10)) or (abs(collisionCenterPt.y - currCenterPt.y) < ((pieceSize[1] / 2) - 10)):
                        #close enough for capture
                        print("Capture!")
                        self.capture(collisionLoc)

        else:
            #done moving so reset everything
            #must handle multiple jumps by automatically selecting piece again and highlighting sqrs

            #* must update loc of piece and pieceGrid *
            self.pieceGrid[self.selected.x][self.selected.y].loc = self.selectedSqr
            self.pieceGrid[self.selectedSqr.x][self.selectedSqr.y] = self.pieceGrid[self.selected.x][self.selected.y]
            self.pieceGrid[self.selected.x][self.selected.y] = GamePiece(dummyColor, self.selected, self.pieces.canvas, -1, self.pieceGrid, self.gameGrid)
            self.selected = self.selectedSqr
            self.selectedSqr = Point(-1, -1)
            self.delHighlightSqrs()
            self.alreadyCaptured = False

            #check for another jump and if not then deselect and else keep selected and highlight new sqrs
            endPts = []
            if (self.isJumping == True):
                endPts = self.referee.nextJumps(self.selected, self.pieceGrid)
            if not endPts:
                #executes if was never jumping or is done jumping
                if (self.pieceGrid[self.selected.x][self.selected.y].type != "pawn") or (self.selected.y != self.pieceGrid[self.selected.x][self.selected.y].lastRow):
                    #normal
                    self.deselectObj()
                else:
                    #pawnToKing
                    self.pawnToKing()
                self.isJumping = False  # multiple jumps are over so can select/deselect a piece again
                if self.turn == "black":
                    self.prevPrevMoveMin = self.prevMoveMin
                    self.prevMoveMin = (self.tempCurrPtMin, self.tempCurrEndPtsMin)
                    self.tempCurrPtMin = Point(-1, -1)
                    self.tempCurrEndPtsMin = []
                    self.turn = "red"
                    print(" { Red's Turn }")
                    self.aiTurn()
                else:
                    self.turn = "black"
                    print(" { Black's Turn }")

            else:
                self.highlightSqrs(endPts)
                if self.turn == "black":
                    print(" { Still Black's Turn }")
                else:
                    print(" { Still Red's Turn }")
                    if self.redEndPts:
                        self.moveAI()
                    else:
                        print("***  ERROR: AI FINISHED JUMPING TOO SOON  ***")

            self.moveCount += 1
            #check for if red or black has won
            if (len(self.redList) == 0) and (len(self.blackList) > 0):
                # black has won!
                print("   *** BLACK WON! ***")
                print("   *** GAME OVER ***")
                App.get_running_app().stop()
            elif (len(self.blackList) == 0) and (len(self.redList) > 0):
                # red has won!
                print("   *** RED WON! ***")
                print("   *** GAME OVER ***")
                App.get_running_app().stop()
            if self.moveCount == moveLimit:
                #no winner!
                print("   *** MOVE LIMIT EXCEEDED! ***")
                print("   *** GAME OVER ***")
                App.get_running_app().stop()
        return

    def update(self, dt):
        if (self.selectedSqr != Point(-1, -1)):
            self.movePiece()
        return

    def moveAI(self):
        if self.redPiecePt != Point(-1, -1):
            self.prevPrevMoveMax = self.prevMoveMax
            self.prevMoveMax = (self.redPiecePt, deepcopy(self.redEndPts))
            endPt = self.redEndPts[0]
            if self.isJumping == False:
                self.selectObj(self.redPiecePt)
                # now must highlightSqrs(list) any possible move sqrs
                howCanMoveRslt = self.referee.howCanMove(self.redPiecePt, self.pieceGrid)
                endPts = howCanMoveRslt[0]
                if endPts:
                    self.highlightSqrs(endPts)
                else:
                    print("ERROR!!! CANNOT MOVE HERE")
            # (must be able to select highlighted squares for next move)
            if endPt in self.lightSqrs:
                # can select square
                self.selectedSqr = endPt
                # set self.isJumping to true if jumping here
                if abs(self.selectedSqr.x - self.selected.x) > 1:
                    # jumping
                    self.isJumping = True
            self.redEndPts.pop(0)
            self.redPiecePt = endPt
        else:
            # executes if AI looses because it has no legal moves available
            print("   *** RED HAS NO LEGAL MOVES ***")
            print("   *** BLACK WON! ***")
            print("   *** GAME OVER ***")
            App.get_running_app().stop()

        return

    def aiTurn(self):
        prevMoveStr = "[ "
        for pt in self.prevMoveMax[1]:
            prevMoveStr += pt.printStr()
            if pt != self.prevMoveMax[1][-1]:
                prevMoveStr += ", "
        prevMoveStr += " ]"
        prevPrevMoveStr = "[ "
        for pt in self.prevPrevMoveMax[1]:
            prevPrevMoveStr += pt.printStr()
            if pt != self.prevPrevMoveMax[1][-1]:
                prevPrevMoveStr += ", "
        prevPrevMoveStr += " ]"
        print(f'prevMove: {self.prevMoveMax[0].printStr()}  {prevMoveStr}    prevPrevMove: {self.prevPrevMoveMax[0].printStr()}  {prevPrevMoveStr}')
        tree = Tree(self.pieceGrid, self.prevMoveMax, self.prevPrevMoveMax, self.prevMoveMin, self.prevPrevMoveMin, "red")
        alpha = alphaMin
        beta = betaMax
        bestTup = (0, 0, 0)  # garbage init
        if normalMode == True:
            bestTup = minimax(tree.rootInd, tree, alpha, beta)
        else:
            bestTup = randomMove(tree)
        del tree
        collect()
        self.redPiecePt = bestTup[0]
        self.redEndPts = bestTup[1]
        print(f"Red Move Value: {bestTup[2]}")
        if self.redPiecePt != Point(-1, -1):
            print(f"Best Val: ( {self.redPiecePt.printStr()}, {ptListPrintStr(self.redEndPts)} )")
        self.moveAI()
        return

class CheckersApp(App):
    def build(self):
        # print mode to terminal
        if normalMode == True:
            print("*** Using Normal AI ***")
        else:
            print("*** Using Random AI ***")
        Config.set('graphics', 'resizeable', '0')
        Window.size = windowSize
        game = CheckersGame()
        Clock.schedule_interval(game.update, 1.0 / 60.0)  # in 1.0 s 60.0 frames
        return game

CheckersApp().run()


from model import *
import sys
from io import StringIO
import pytest

def get_value(number):
    old_stdout = sys.stdout
    sys.stdout = StringIO()
    scope = Scope()
    Print(number).evaluate(scope)
    value = int(sys.stdout.getvalue())
    sys.stdout = old_stdout
    return value

class TestScope:
    def test_scope_simple(self):
        parent = Scope()
        numb1 = Number(10)
        parent['a'] = numb1
        assert parent['a'] is numb1
        numb2 = Number(-2)
        parent['b'] = numb2
        assert parent['b'] is numb2

    def test_scope_take_from_parent(self):
        parent = Scope()
        scope = Scope(parent)
        numb = Number(10)
        parent['a'] = numb
        assert scope['a'] is numb

    def test_scope_have_func(self):
        parent = Scope()
        numb = Function([], [])
        parent['f'] = numb
        assert parent['f'] is numb

class TestNumber:

    def test_number(self):
        scope = Scope()
        n = Number(43)
        assert get_value(n) == 43
        assert n.evaluate(scope) is n

class TestPrint:

    def test_print_number(self):
        n = Number(43)
        assert get_value(n) == 43

    def test_print_evaluate(self, monkeypatch):
        monkeypatch.setattr(sys, 'stdout', StringIO())
        scope = Scope()
        res = Print(BinaryOperation(Number(30),
                                    '+',
                                    Number(13))).evaluate(scope)
        assert get_value(res) == 43
        assert sys.stdout.getvalue() == '43\n'

class TestRead:
    def test_read(self, monkeypatch):
        monkeypatch.setattr(sys, 'stdin', StringIO('43\n'))
        monkeypatch.setattr(sys, 'stdout', StringIO())
        scope = Scope()
        read_res = Read('a').evaluate(scope)
        Print(Reference('a')).evaluate(scope)
        assert sys.stdout.getvalue() == '43\n'
        assert get_value(read_res) == 43

class TestUnaryOperation:

    def test_unary_operation_not(self):
        scope = Scope()
        n = Number(43)
        not_n = UnaryOperation('!', n).evaluate(scope)
        assert get_value(not_n) == 0
        n = Number(0)
        not_n = UnaryOperation('!', n).evaluate(scope)
        assert get_value(not_n) != 0

    def test_unary_operation_minus(self):
        scope = Scope()
        n = Number(43)
        minus_n = UnaryOperation('-', n).evaluate(scope)
        assert get_value(minus_n) == -43

    def test_unary_operation_evaluate(self):
        scope = Scope()
        n = Number(0)
        ev = UnaryOperation('-', UnaryOperation('!', n))
        assert get_value(ev) != 0
        n = Number(43)
        ev = UnaryOperation('-', UnaryOperation('-', n))
        assert get_value(ev) == 43

class TestBinaryOperation:

    def test_binary_operation_sum(self):
        a = Number(43)
        b = Number(10)
        res = BinaryOperation(a, '+', b)
        assert get_value(res) == 53

    def test_binary_operation_dif(self):
        a = Number(43)
        b = Number(10)
        res = BinaryOperation(a, '-', b)
        assert get_value(res) == 33

    def test_binary_operation_mult(self):
        a = Number(43)
        b = Number(10)
        res = BinaryOperation(a, '*', b)
        assert get_value(res) == 430

    def test_binary_operation_del(self):
        a = Number(43)
        b = Number(10)
        res = BinaryOperation(a, '/', b)
        assert get_value(res) == 4

    def test_binary_operation_ost(self):
        scope = Scope()
        a = Number(43)
        b = Number(10)
        res = BinaryOperation(a, '%', b)
        assert get_value(res) == 3

    def test_binary_operation_and(self):
        res = BinaryOperation(Number(43), '&&', Number(0))
        assert get_value(res) == 0

    def test_binary_operation_or(self):
        res = BinaryOperation(Number(43), '||', Number(0))
        assert get_value(res) != 0

    def test_binary_operation_more(self):
        res = BinaryOperation(Number(43), '>', Number(43))
        assert get_value(res) == 0

    def test_binary_operation_less(self):
        res = BinaryOperation(Number(43), '<', Number(53))
        assert get_value(res) != 0

    def test_binary_operation_more_or_eq(self):
        res = BinaryOperation(Number(43), '>=', Number(43))
        assert get_value(res) != 0

    def test_binary_operation_less_or_eq(self):
        res = BinaryOperation(Number(43), '<=', Number(42))
        assert get_value(res) == 0

    def test_binary_operation_eq(self):
        res = BinaryOperation(Number(43), '==', Number(33))
        assert get_value(res) == 0

    def test_binary_operation_not_eq(self):
        res = BinaryOperation(Number(43), '!=', Number(33))
        assert get_value(res) != 0

    def test_binary_operation_evaluate(self):
        scope = Scope()
        a = Number(43)
        b = Number(10)
        dif = BinaryOperation(a, '-', b)
        eq = BinaryOperation(dif, '==', Number(33))
        assert get_value(eq) != 0

class TestFunction:

    def test_function_empty_arguments(self):
        scope = Scope()
        func = Function([], [Number(43)])
        res = func.evaluate(scope)
        assert get_value(res) == 43

    def test_function_many_arguments_and_evaluate(self):
        scope = Scope()
        scope['a'] = Number(33)
        scope['b'] = Number(10)
        func = Function(('a', 'b'), [BinaryOperation(Reference('a'),
                                                     '+',
                                                     Reference('b'))])
        res = func.evaluate(scope)
        assert get_value(res) == 43

    def test_function_big_body(self, monkeypatch):
        monkeypatch.setattr(sys, 'stdout', StringIO())
        scope = Scope()
        scope['a'] = Number(33)
        scope['b'] = Number(10)
        func = Function(('a', 'b'),
                        [Print(Reference('a')),
                         Reference('a'),
                         Reference('b')])
        res = func.evaluate(scope)
        Print(res).evaluate(scope)
        assert sys.stdout.getvalue() == '33\n10\n'

    def test_function_empty_body(self, monkeypatch):
        scope = Scope()
        Function(('a'), []).evaluate(scope)

class TestFunctionDefinition:

    def test_function_definition_simple(self):
        scope = Scope()
        func = Function([], [BinaryOperation(Number(10), '+', Number(33))])
        func2 = FunctionDefinition('func', func).evaluate(scope)
        assert scope['func'] is func
        assert func2 is func

class TestReference:

    def test_reference_number(self, monkeypatch):
        scope = Scope()
        a = Number(43)
        scope['a'] = a
        a2 = Reference('a').evaluate(scope)
        assert a is a2

    def test_reference_function(self, monkeypatch):
        scope = Scope()
        func = Function([], [])
        scope['function'] = func
        func2 = Reference('function').evaluate(scope)
        assert func is func2

class TestConditional:

    def test_conditional_without_if_false(self, monkeypatch):
        monkeypatch.setattr(sys, 'stdout', StringIO())
        scope = Scope()
        res1 = Conditional(Number(1), [Print(Number(1))]).evaluate(scope)
        Conditional(Number(0), [Print(Number(1))]).evaluate(scope)
        assert sys.stdout.getvalue() == '1\n'
        assert get_value(res1) == 1

    def test_conditional_evaluate_condtion(self, monkeypatch):
        monkeypatch.setattr(sys, 'stdout', StringIO())
        scope = Scope()
        Conditional(BinaryOperation(Number(3), '==', Number(3)),
                    [Print(Number(1))],
                    [Print(Number(0))]).evaluate(scope)
        Conditional(BinaryOperation(Number(2), '==', Number(3)),
                    [Print(Number(1))],
                    [Print(Number(0))]).evaluate(scope)
        assert sys.stdout.getvalue() == '1\n0\n'

    def test_conditional_return(self, monkeypatch):
        monkeypatch.setattr(sys, 'stdout', StringIO())
        scope = Scope()
        res1 = Conditional(BinaryOperation(Number(3), '==', Number(3)),
                           [Number(1)],
                           [Number(0)]).evaluate(scope)
        res2 = Conditional(BinaryOperation(Number(2), '==', Number(3)),
                           [Number(1)],
                           [Number(0)]).evaluate(scope)
        assert get_value(res1) == 1
        assert get_value(res2) == 0

    def test_conditional_empty(self, monkeypatch):
        monkeypatch.setattr(sys, 'stdout', StringIO())
        scope = Scope()
        Conditional(Number(0),
                    [Print(Number(2))],
                    []).evaluate(scope)
        Conditional(Number(43),
                    [],
                    []).evaluate(scope)
        Conditional(Number(0),
                    [],
                    []).evaluate(scope)
        Conditional(Number(43),
                    [],
                    [Print(Number(3))]).evaluate(scope)
        assert sys.stdout.getvalue() == ''

    def test_conditional_empty_with_result(self):
        scope = Scope()
        res = Conditional(Number(43),
                          [Number(34)],
                          []).evaluate(scope)
        assert get_value(res) == 34
        res = Conditional(Number(0),
                          [],
                          [Number(334)]).evaluate(scope)
        assert get_value(res) == 334

    def test_conditional_big_body_if_true(self, monkeypatch):
        monkeypatch.setattr(sys, 'stdout', StringIO())
        scope = Scope()
        Conditional(Number(43),
                    [Print(Number(1)), Print(Number(2))],
                    [Print(Number(3)), Print(Number(4))]).evaluate(scope)
        assert sys.stdout.getvalue() == '1\n2\n'

    def test_conditional_big_body_if_false(self, monkeypatch):
        monkeypatch.setattr(sys, 'stdout', StringIO())
        scope = Scope()
        Conditional(Number(0),
                    [Print(Number(1)), Print(Number(2))],
                    [Print(Number(3)), Print(Number(4))]).evaluate(scope)
        assert sys.stdout.getvalue() == '3\n4\n'

class TestFunctionCall:

    def test_function_call_with_simple(self):
        parent = Scope()
        FunctionDefinition(
            'max',
            Function(('a', 'b'),
                     [Conditional(BinaryOperation(Reference('a'),
                                                  '>=',
                                                  Reference('b')),
                                  [Reference('a')],
                                  [Reference('b')])])
        ).evaluate(parent)
        n = FunctionCall(Reference('max'),
                         [Number(6), Number(5)]).evaluate(parent)
        assert get_value(n) == 6

    def test_function_call_very_tricky(self):
        parent = Scope()
        FunctionDefinition(
            'strange_max',
            Function(
                ('a', 'b'),
                [Conditional(
                    BinaryOperation(Reference('a'),
                                    '<=',
                                    Reference('b')),
                    [Reference('b')],
                    [FunctionCall(Reference('strange_max'),
                                  [Reference('b'),
                                  Reference('a')])]
                )]
            )
        ).evaluate(parent)
        n = FunctionCall(Reference('strange_max'),
                         [Number(6), Number(5)]).evaluate(parent)
        assert get_value(n) == 6

class TestIntegration:

    def test_factorial(self):
        parent = Scope()
        FunctionDefinition(
            'factorial',
            Function(
                ('a'),
                [Conditional(
                    BinaryOperation(Reference('a'),
                                    '<=',
                                    Number(1)),
                    [Reference('a')],
                    [BinaryOperation(FunctionCall(
                                        Reference('factorial'),
                                        [BinaryOperation(Reference('a'),
                                                         '-',
                                                         Number(1))]
                                     ),
                     '*', Reference('a'))]
                )]
            )
        ).evaluate(parent)
        n = FunctionCall(Reference('factorial'),
                         [Number(5)]).evaluate(parent)
        assert get_value(n) == 120

    def test_fibonacci(self):
        parent = Scope()
        FunctionDefinition(
            'fib',
            Function(
                ('a'),
                [Conditional(
                    BinaryOperation(Reference('a'),
                                    '<=',
                                    Number(1)),
                    [Reference('a')],
                    [BinaryOperation(
                        FunctionCall(
                            Reference('fib'),
                            [BinaryOperation(Reference('a'),
                                             '-',
                                             Number(1))]
                        ),
                        '+',
                        FunctionCall(Reference('fib'),
                                     [BinaryOperation(Reference('a'),
                                                      '-',
                                                      Number(2))]))]
                )]
            )
        ).evaluate(parent)
        n = FunctionCall(Reference('fib'),
                         [Number(8)]).evaluate(parent)
        assert get_value(n) == 21

    def test_average(self):
        parent = Scope()
        FunctionDefinition(
            'average',
            Function(('a', 'b'),
                     [BinaryOperation(BinaryOperation(Reference('a'),
                                                      '+',
                                                      Reference('b')),
                                      '/',
                                      Number(2))])
        ).evaluate(parent)
        n = FunctionCall(Reference('average'),
                         [Number(4), Number(6)]).evaluate(parent)
        assert get_value(n) == 5


import sys
from Bio.Blast import NCBIXML
if len(sys.argv) !=4:
    print ("Error, wrong number of arguments")
#command line arguments 1, 2 and 3 as indicated in midterm question
file1 = sys.argv[1]
file2 = sys.argv[2]
outfile= sys.argv[3]
"""In command line, input is <this file> <xml document 1> <xml document 2> <target txt file>"""
"""output: putitative orthologs between the two species in target txt file"""
#parse for BLAST on first file, using dictionary
with open (sys.argv[1]) as br1:
    blast_record_1=NCBIXML.parse(br1)
    D1={}
    E_VALUE_THRESH = 1e-20
    for blast_record in blast_record_1:
        for alignment in blast_record.alignments:
            for hsp in alignment.hsps:
                if hsp.expect < E_VALUE_THRESH:#making sure the e value is less than 1e-20
                    D1[hsp.match]=alignment.hit_def #the protein is added as a key to a dict with its matching sequence as a value.

#second xml parse for result, same as above
with open (sys.argv[2]) as br2:
    blast_record_2 = NCBIXML.parse(br2)
    D2={}
    E_VALUE_THRESH = 1e-20#ignores everything larger than 1e-20
    for blast_record in blast_record_2:
        for alignment in blast_record.alignments:
            for hsp in alignment.hsps:
                if hsp.expect < E_VALUE_THRESH: #making sure the e value is less than 1e-20
                    D2[hsp.match]=alignment.hit_def #the protein is added as a key to a dict with its matching sequence as a value.
outfile = open(sys.argv[3],'w')
for k in set(D1.keys()) & set(D2.keys()):#orthologous pairs need to be chosen, using dictionary comparison between values (hsp.match sequences)
    x = (D1[k],"\t",D2[k])
    print >>outfile, x#writes the keys (the names of the proteins) into the file
outfile.close()


from bs4 import BeautifulSoup

import requests

from openpyxl import Workbook

wb = Workbook()

sheet = wb.active

page_source = requests.get("https://www.totallyuselesswebsites.com/")

soup =  BeautifulSoup(page_source.text,'html.parser')

# print(soup.prettify())

all_links = soup.find_all('a')

for link in all_links:
    print(link.get('href'))

wb.save("demo.xlsx")


from typing import Tuple

import pandas as pd
import numpy as np

import torch

class VectorSimSearch:
  """
    A class for performing vector similarity search on a dataframe.
    Assume embedding vector is available
  """
  def __init__(self, df: pd.DataFrame, embedding_col=None, embedding_model=None, device=torch.device('cpu')):
    self.df = df.copy()    # take a copy to ensure original df is not altered.
    assert embedding_col is not None, 'embedding_col must be provided'
    self.embedding_col = embedding_col
    self.embeddings = np.array(self.df[self.embedding_col].values.tolist())

    self.embedding_model = embedding_model
    self.device = device

  def search(self, query: str, top_n=5) -> Tuple[np.ndarray, np.ndarray]:
    """
    Given a query string, return the top_n most similar.
    Returns: dataframe indices and their cosine similarity scores
    """
    assert self.embedding_model is not None, 'embedding_model must be provided'
    with torch.no_grad():
      query_embedding = self.embedding_model.encode(query, convert_to_tensor=True, device=self.device, normalize_embeddings=True)
      query_embedding = query_embedding.detach().cpu().numpy()

    cos_sim = query_embedding[None] @ self.embeddings.T

    sorted_sim = np.squeeze(np.sort(cos_sim))[::-1]
    rank = np.squeeze(np.argsort(cos_sim))[::-1]

    return rank[:top_n], sorted_sim[:top_n]

  def find_similar_item(self, indice: int, top_n=5) -> Tuple[np.ndarray, np.ndarray]:
    """
    Given an item's indice in the dataframe, return the top_n most similar.
    """
    try:
      query_embedding = self.df.loc[indice, self.embedding_col]
    except:
      raise ValueError(f'indice {indice} is out of range in dataframe which has size {self.df.shape[0]}')

    cos_sim = query_embedding[None] @ self.embeddings.T

    sorted_sim = np.squeeze(np.sort(cos_sim))[::-1]
    rank = np.squeeze(np.argsort(cos_sim))[::-1]

    return rank[:top_n], sorted_sim[:top_n]


from django.shortcuts import render
from rest_framework.decorators import api_view
from .models import Students, Score
from .serializers import StudentSerializer, ScoreSerializer
from rest_framework.response import Response
from rest_framework import status
from django.shortcuts import get_object_or_404
# Create your views here.

@api_view(['GET', 'POST'])
def StudentView(request):
    if request.method == 'GET':
        qs = Students.objects.all()
        serializer = StudentSerializer(qs, many=True)
        return Response(serializer.data)
    elif request.method == 'POST':
        serializer = StudentSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status = status.HTTP_201_CREATED)
        return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST)

@api_view(['GET',"POST"])
def ScoreView(request):
    qs = Score.objects.all()

    if request.method == "GET":
        serializer = ScoreSerializer(qs, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
       serializer = ScoreSerializer(data=request.data)
       if serializer.is_valid():
           serializer.save()
           return Response(serializer.data, status=status.HTTP_201_CREATED)
       return Response(serializer.error, status=status.HTTP_400_BAD_REQUEST)

@api_view(["GET","PUT","DELETE"])
def StudentDetailView(request, name):
    qs = get_object_or_404(Students, pk=name)

    if request.method == 'GET':
        serializer = StudentSerializer(qs)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = StudentSerializer(qs, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        qs.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

@api_view(["GET","PUT","DELETE"])
def ScoreDetailView(request, pk):
    qs = get_object_or_404(Score, pk=pk)
    print(qs)

    if request.method == 'GET':
        serializer = ScoreSerializer(qs)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = ScoreSerializer(qs, data=request.data)
        if serializer.is_valid():
           serializer.save()
           return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        qs.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


import pygame
import random
from enum import Enum
from collections import namedtuple

# ----- SETUP -----
pygame.init()
font = pygame.font.SysFont('arial', 25)

class Direction(Enum):
    """
    Represent direction snake is moving using enumeration
    """
    RIGHT = 1
    LEFT = 2
    UP = 3
    DOWN = 4

# represent a block
Block = namedtuple('Block', 'x, y')

# colors
WHITE = (255, 255, 255)
RED = (200, 0, 0)
LIGHT_BLUE = (0, 0, 255)
DARK_BLUE = (0, 100, 255)
BLACK = (0, 0, 0)

# game constants
BLOCK_SIZE = 20
SPEED = 20

# ----- GAME BEHAVIOR -----
class SnakeGame:
    """
    Represent a game of Snake
    """
    def __init__(self, w=640, h=480):
        # display
        self.w = w
        self.h = h
        self.display = pygame.display.set_mode((self.w, self.h))
        pygame.display.set_caption('Snake')
        self.clock = pygame.time.Clock()
        # game state
        self.direction = Direction.RIGHT
        self.head = Block(self.w / 2, self.h / 2)
        self.snake = [self.head,
                      Block(self.head.x - BLOCK_SIZE, self.head.y),
                      Block(self.head.x - (2 * BLOCK_SIZE), self.head.y)]
        self.score = 0
        self.food = None
        self._place_food()

    def _place_food(self):
        """
        Place food block randomly on display
        :return: None
        """
        x = random.randint(0, (self.w - BLOCK_SIZE) // BLOCK_SIZE) * BLOCK_SIZE
        y = random.randint(0, (self.h - BLOCK_SIZE) // BLOCK_SIZE) * BLOCK_SIZE
        self.food = Block(x, y)
        if self.food in self.snake:
            self._place_food()

    def play_step(self):
        """
        Update game state based upon user input
        :return: <tuple> (<bool> whether game is over, <int> current score)
        """
        # user input
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    self.direction = Direction.LEFT
                elif event.key == pygame.K_RIGHT:
                    self.direction = Direction.RIGHT
                elif event.key == pygame.K_UP:
                    self.direction = Direction.UP
                elif event.key == pygame.K_DOWN:
                    self.direction = Direction.DOWN
        # move
        self._move(self.direction)
        self.snake.insert(0, self.head)
        game_over = False
        # collision
        if self._is_collision():
            game_over = True
            return game_over, self.score
        # place new food or simply move
        if self.head == self.food:
            self.score += 1
            self._place_food()
        else:
            self.snake.pop()
        # update display
        self._update_ui()
        self.clock.tick(SPEED)
        return game_over, self.score

    def _is_collision(self):
        """
        Check whether there is a collision
        :return: True if collision, False if not
        """
        # hit boundary
        if self.head.x > self.w - BLOCK_SIZE or self.head.x < 0 or self.head.y > self.h - BLOCK_SIZE or self.head.y < 0:
            return True
        # hit self
        if self.head in self.snake[1:]:
            return True
        return False

    def _update_ui(self):
        """
        Update display with current game state
        :return: None
        """
        self.display.fill(BLACK)
        for pt in self.snake:
            pygame.draw.rect(self.display, LIGHT_BLUE, pygame.Rect(pt.x, pt.y, BLOCK_SIZE, BLOCK_SIZE))
            pygame.draw.rect(self.display, DARK_BLUE, pygame.Rect(pt.x + 4, pt.y + 4, 12, 12))
        pygame.draw.rect(self.display, RED, pygame.Rect(self.food.x, self.food.y, BLOCK_SIZE, BLOCK_SIZE))
        text = font.render("Score: " + str(self.score), True, WHITE)
        self.display.blit(text, [0, 0])
        pygame.display.flip()

    def _move(self, direction):
        """
        Move the snake based upon user input
        :param direction: <int> direction to move
        :return: None
        """
        x = self.head.x
        y = self.head.y
        if direction == Direction.RIGHT:
            x += BLOCK_SIZE
        elif direction == Direction.LEFT:
            x -= BLOCK_SIZE
        elif direction == Direction.DOWN:
            y += BLOCK_SIZE
        elif direction == Direction.UP:
            y -= BLOCK_SIZE
        self.head = Block(x, y)

# ----- GAME LOOP -----
if __name__ == '__main__':
    game = SnakeGame()
    while True:
        game_over, score = game.play_step()
        if game_over == True:
            break
    print('Final Score', score)
    pygame.quit()


#!/usr/bin/env python

from __future__ import print_function

# ------------------------------------------------------------------------
# Test client for the pyserv project. Encrypt test.

import  os, sys, getopt, signal, select, socket, time, struct
import  random, stat

#sys.path.append('../common')
#import support, pycrypt, pyservsup, pyclisup, syslog, comline, pypacker

# Set parent as module include path
current = os.path.dirname(os.path.realpath(__file__))
parent = os.path.dirname(current)
sys.path.append(parent)

from common import support, pycrypt, pyservsup, pyclisup
from common import pysyslog, comline, pypacker

version = "1.0"

optarr =  comline.optarr
optarr.append ( ["p:",  "port",  6666,   None, "Port to use (default: 9999)"] )
#                ["c:",  "comm",     "",     None],      \

conf = comline.Config(optarr)

# ------------------------------------------------------------------------

if __name__ == '__main__':

    args = conf.comline(sys.argv[1:])

    if len(args) == 0:
        ip = '127.0.0.1'
    else:
        ip = args[0]

    hand = pyclisup.CliSup()
    hand.verbose = conf.verbose
    hand.pgdebug = conf.pgdebug
    #hand.comm  = conf.comm

    #print("ip:", ip, "port", conf.port)
    try:
        resp2 = hand.connect(ip, conf.port)
    except:
        print( "Cannot connect to:", ip + ":" + str(conf.port), sys.exc_info()[1])
        sys.exit(1)

    #print ("Server initial:", resp2[1])

    resp3 = hand.client(["hello",] , "", False)
    if conf.verbose:
        print("Hello Response:", resp3)

    #sys.exit(0)

    cresp = hand.client(["crap", "this com"])
    print ("Server crap response:", cresp[1])

    cresp = hand.client(["ls", "out of order"])
    print ("Server ls response:", cresp[1])

    cresp = hand.client(["sess", "out of order"])
    print ("Server sess response:", cresp[1])

    cresp = hand.client(["user", "peter"])
    print ("Server user response:", cresp[1])

    cresp = hand.client(["pass", "12345"])
    print ("Server pass response:", cresp[1])

    qresp = hand.client(["quit"])
    #hand.close()
    print ("Server quit response:", qresp[1])

    sys.exit(0)

# EOF


from rest_framework import serializers
from order_app.models import Order,OrderInformation
from table_app.models import Table
from paymentmode_app.models import Payment
from cusine_app.models import Cusine
from dish_app.models import DishType,DishModel
from table_app.models import Table

class CusineSerializer(serializers.ModelSerializer):
    cusine_name = serializers.CharField(max_length=255)
    date_added = serializers.DateTimeField(read_only=True)

    class Meta:
        model = Cusine
        fields = ['cusine_name','date_added']

class TableSerializer(serializers.ModelSerializer):

    table_name = serializers.CharField(max_length=255)

    class Meta:
        model = Table
        fields = ["id","table_name","table_status"]

class DishTypeSerializer(serializers.ModelSerializer):
    dish_typename = serializers.CharField(max_length=255)
    dish_type_added = serializers.DateTimeField(read_only=True)

    class Meta:
        model = DishType
        fields = '__all__'

class AvailableDishSerializer(serializers.ModelSerializer):
    dish_id = serializers.IntegerField()
    cusine = CusineSerializer(source='cusine_id', read_only=True)
    dish_name = serializers.CharField(max_length=255)
    dish_image = serializers.ImageField(allow_empty_file=False, use_url=True)
    dish_type = DishTypeSerializer(read_only=True)
    dish_description = serializers.CharField(max_length=255)
    dish_price = serializers.DecimalField(decimal_places=2, max_digits=20)
    date_added = serializers.DateTimeField()

    class Meta:
        model = DishModel
        fields = '__all__'

class OrderInformationSerializer(serializers.ModelSerializer):
    order_info_id = serializers.PrimaryKeyRelatedField(queryset=Order.objects.all())
    customer_name = serializers.CharField(max_length=255)
    table = serializers.PrimaryKeyRelatedField(queryset=Table.objects.all())
    payment_mode = serializers.PrimaryKeyRelatedField(queryset=Payment.objects.all())

    class Meta:
        model = OrderInformation
        fields = ["order_info_id","customer_name","table","payment_mode","grand_total"]

class CreateOrderSerializer(serializers.ModelSerializer):
    order_dishname = serializers.PrimaryKeyRelatedField(queryset=DishModel.objects.all())
    order_quantity = serializers.IntegerField(default=0)
    order_status = serializers.CharField(max_length=50)

    class Meta:
        model = Order
        fields = ['order_dishname','order_quantity','order_status']

class OrderSerializer(serializers.ModelSerializer):
    order_dishname = serializers.SerializerMethodField()
    order_quantity = serializers.IntegerField(default=0)

    class Meta:
        model = Order
        fields = ['order_id','order_dishname','order_quantity','order_status']

    def get_order_dishname(self, obj):
        dish = obj.order_dishname
        serializer = AvailableDishSerializer(dish)
        return serializer.data

class PaymentSerializer(serializers.ModelSerializer):
    payment_mode = serializers.CharField(max_length=50)

    class Meta:
        model = Payment
        fields = ['id','payment_mode']


import logging
from selectorlib import Extractor
import requests
from base import Base, RESP_DEFAULT
import os
from dotenv import load_dotenv

load_dotenv()

pathfile = os.path.dirname(os.path.realpath(__file__))
DNS_WEB = "https://www.belk.com"

class Belk(Base):
    eP = Extractor.from_yaml_file("{}/selector_product.yml".format(pathfile))
    __instance = None

    def __init__(self, dns=DNS_WEB) -> None:
        if Belk.__instance != None:
            raise Exception("This is singleton class!!")
        self.dns = dns
        Belk.__instance = self

    @staticmethod
    def getInstance() -> object:
        """This is static method be called by class"""
        if Belk.__instance == None:
            Belk()
        return Belk.__instance

    def product(self, url) -> dict:
        try:
            logging.info("Downloading {}".format(url))
            proxyDict = {
                'http': os.getenv('HTTP_PROXY'),
                'https': os.getenv('HTTPS_PROXY')
            }
            r = requests.get(url, headers=self.headers,
                             timeout=10, proxies=proxyDict)
            if r.status_code > 500:
                if "To discuss automated access to Website data please contact" in r.text:
                    print(
                        "Page %s was blocked by Website. Please try using better proxies\n" % url)
                else:
                    print("Page %s must have been blocked by Website as the status code was %d" % (
                        url, r.status_code))
                return {}
            resp = Belk.eP.extract(r.text)
            resp.update({
                'price': resp["price"] or resp["price_standard"]
            })
            return resp
        except Exception as e:
            logging.error(e)
        return RESP_DEFAULT

    def __str__(self) -> str:
        return "Belk Model"


import numpy as np
import os
import glob
import json
import cv2
from scipy.spatial import distance
from pathlib import Path
import csv
from absl import flags
from absl import app
import pickle
import warnings

warnings.filterwarnings("ignore", category=np.VisibleDeprecationWarning)
flags.DEFINE_string('video_name', None, 'the name of the test video')
FLAGS = flags.FLAGS

class Preprocesser():
    def __init__(self, video_name):
        super().__init__()
        self.video_name = video_name
        self.root_dir = "/home/lin10/projects/SkatingApp/cache/jump/data/alphapose/alpha_pose_{}".format(video_name)
        self.output_file = "/home/lin10/projects/SkatingApp/cache/jump/data/pkl/{}.pkl".format(video_name)
        self.sample_list = []
        self.SKELETON_CONF_THRESHOLD = 0.0

    def writePickle(self):
        with open(self.output_file, "wb") as f:
            pickle.dump(self.sample_list, f)

    def get_main_skeleton(self):
        path_to_json = "{}/alphapose-results.json".format(self.root_dir)
        root_dir = self.root_dir
        frames = list(Path(os.path.join(self.root_dir, 'vis')).glob("*.jpg"))
        last_frame = sorted([int(os.path.split(frame)[1].replace('.jpg','')) for frame in frames])[-1]
        with open(path_to_json) as f:
            json_skeleton = json.load(f)

        # Get first image id
        prev_frame = int(json_skeleton[0]['image_id'].rstrip('.jpg'))
        score_list = []
        main_skeleton_list = []
        for skeleton in json_skeleton:
            # Get current image id
            cur_frame = int(skeleton['image_id'].rstrip('.jpg'))
            # Get all skeleton in current frame
            if cur_frame == prev_frame:
                score_list.append([skeleton['score'], np.reshape(skeleton['keypoints'], (17,3))])
            # Get the main skeleton in previous frame by score or distance
            else:
                if main_skeleton_list == []:
                    main_skeleton_list.append([prev_frame, np.array(max(score_list))])
                else:
                    dist_list = []
                    # Pick a skeleton that is the closest to the previous one
                    for score in score_list:
                        ske_distance = distance.euclidean(np.delete(score[1], (2), axis=1).ravel(), np.delete(main_skeleton_list[-1][1][1], (2), axis=1).ravel())
                        dist_list.append([ske_distance, score])
                    main_skeleton_list.append([prev_frame, np.array(min(dist_list)[1])])
                # Clear score list and append first skeleton for current frame
                score_list.clear()
                score_list.append([skeleton['score'], np.reshape(skeleton['keypoints'], (17,3))])
            prev_frame = cur_frame
        # append max score for the last frame
        main_skeleton_list.append([cur_frame, np.array(max(score_list))])
        main_skeleton_list = np.reshape(main_skeleton_list, (-1,2))

        keypoints_info = []
        for main_skeleton in main_skeleton_list:
            delete_pt = []
            keypoints = main_skeleton[1][1]
            for row in range(len(keypoints)):
                if keypoints[row][2] < self.SKELETON_CONF_THRESHOLD:
                    delete_pt.append(row)
            keypoints = np.delete(keypoints, (delete_pt), axis=0)
            keypoints_info.append([main_skeleton[0], keypoints])
        keypoints_info = np.array(keypoints_info)

        # Insert missing frame info
        for i in range(last_frame+1):
            if i not in keypoints_info[:,0]:
                insert_row = np.concatenate([[i],keypoints_info[i-1,1:]], axis=0)
                keypoints_info = np.insert(keypoints_info, i, insert_row, axis=0)
        return keypoints_info

    def subtract_features(self, keypoints):
        subtracted_keypoints = []
        for i in range(1, 17, 2):
            subtraction = keypoints[i][0] - keypoints[i+1][0]
            subtracted_keypoints.append(subtraction)
        return np.array(subtracted_keypoints)

    def load_data(self):
        frames = list(Path(os.path.join(self.root_dir, 'vis')).glob("*.jpg"))
        alphaposeResults = self.get_main_skeleton()
        assert len(frames) == len(alphaposeResults), "{} error".format(self.video_name)
        subtractions_list = [self.subtract_features(alphaposeResult[1]) for alphaposeResult in alphaposeResults]
        keypoints_list = [np.delete(alphaposeResult[1], 2, axis=1).reshape(-1) for alphaposeResult in alphaposeResults]
        subtraction_features_list = np.append(keypoints_list, subtractions_list, axis=1)
        features_list = keypoints_list
        sample = {"subtraction_features": subtraction_features_list, "features": features_list, "video_name": self.video_name}
        self.sample_list.append(sample)
        self.writePickle()

def main(_argv):
    preprocesser = Preprocesser(FLAGS.video_name)
    preprocesser.load_data()

if __name__ == '__main__':
    try:
        app.run(main)
    except SystemExit:
        pass


import thingy52
import sqlite3
import time
import binascii

class DBConnection:

  dataBase = 'environment'
  fileName = dataBase + '.db'

  def __init__(self):
    self.con = sqlite3.connect(self.fileName)
    self.cur = self.con.cursor()

  def saveData(self, measurement, time):

    self.addData(measurement['temperature'],
                 measurement['humidity'],
                 measurement['pressure'],
                 measurement['eco2'],
                 measurement['tvoc'],
                 measurement['battery'])

  def addData(self, temperature, humidity, pressure, eco2, tvoc, battery, timestamp = None):
    #add date/time
    id = 'F6:CD:CD:6D:62:09'
    if timestamp is None:
      timestamp = int(time.time())
    self.cur.execute(f"INSERT into {self.dataBase} VALUES ({timestamp},'{id}', {temperature},{humidity}, {pressure}, {eco2}, {tvoc}, {battery})")
    self.con.commit()

  def __del__(self):
    self.con.close()

class MyDelegate(thingy52.MyDelegate):

    def __init__(self):
      self.measurements = dict()
      self.measurements['eco2'] = 0
      self.measurements['tvoc'] = 0
      self.measurements['battery'] = 100
      self.measurements['temperature'] = 23.0
      self.measurements['pressure'] = 1000.0
      self.measurements['humidity'] = 60

    def addBatteryMeasurement(self, battery_level):
      self.measurements['battery'] = battery_level

    def getCurrentMeasurement(self):
      return self.measurements

    def handleNotification(self, handle, data):

        if (handle == thingy52.e_temperature_handle):
            teptep = binascii.b2a_hex(data)
            temperature = self._str_to_int(teptep[:-2]) + int(teptep[-2:], 16) * 0.01
            self.measurements['temperature'] = temperature

            print(f'Notification: Temp received:  {temperature} degCelsius')

        elif (handle == thingy52.e_pressure_handle):
            pressure_int, pressure_dec = self._extract_pressure_data(data)
            pressure = pressure_int + pressure_dec * 0.01
            self.measurements['pressure'] = pressure

            print(f'Notification: Pressure received: {pressure} hPa')

        elif (handle == thingy52.e_humidity_handle):
            humidity = int(binascii.b2a_hex(data),16)
            self.measurements['humidity'] = humidity

            print(f'Notification: Humidity received: {humidity} %')

        elif (handle == thingy52.e_gas_handle):
            eco2, tvoc = self._extract_gas_data(data)
            self.measurements['eco2'] = eco2
            self.measurements['tvoc'] = tvoc

            print(f'Notification: Gas received: eCO2 ppm: {eco2}, TVOC ppb: {tvoc} %')

        else:
            print(f'Notification: UNKOWN: handle {handle}')

def main():
    thingy = thingy52.Thingy52('F6:CD:CD:6D:62:09')
    delegate = MyDelegate()
    thingy.setDelegate(delegate)

    db = DBConnection()

    try:

      thingy.ui.enable()
      thingy.ui.set_led_mode_off()

      thingy.environment.enable()

      second_to_ms = 1000
      thingy.environment.configure(temp_int =  5* 60 * second_to_ms,
                                  press_int = 5 * 60 * second_to_ms,
                                  humid_int = 5 * 60 * second_to_ms,
                                  gas_mode_int = 3)
      thingy.environment.set_temperature_notification(True)
      thingy.environment.set_gas_notification(True)
      thingy.environment.set_humidity_notification(True)
      thingy.environment.set_pressure_notification(True)

      thingy.battery.enable()

      last_snapshot = time.time()
      while True:

        now = time.time()

        interval = 20
        if int(now - last_snapshot) > interval :
          delegate.addBatteryMeasurement(thingy.battery.read())
          print("saving data to DB")
          last_snapshot = now
          db.saveData(delegate.getCurrentMeasurement(), now)

        thingy.waitForNotifications(10)

    except Exception as e:
      print (e)
      thingy.disconnect()

def test():
  db = DBConnection()

  db.addData(1,2,3,4, int(time.time()-60))
  db.addData(2,1,3,10, int(time.time()-120))
  db.addData(3,1,3,10, int(time.time()-240))
  db.addData(1,0,3,4, int(time.time()-300))

main()


from collections import UserDict
from datetime import datetime, date
import json
import re

class WrongPhone(Exception):
    pass

class WrongDate(Exception):
    pass

class WrongEmail(Exception):
    pass

class WrongDays(Exception):
    pass

class NoName(Exception):
    pass

class Field:
    def __init__(self, value):
        self._value = value

    def __str__(self):
        return str(self._value)

    def __repr__(self):
        return str(self)

    def __eq__(self, other):
        if self.__class__ == other.__class__:
            return self._value == other.value
        return False

    def __hash__(self):
        return hash(self._value)

class Name(Field):
    @staticmethod
    def is_valid_name(name):
        if name.strip() == '':
            return False
        else:
            return True

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        if self.is_valid_name(val):
            self._value = val
        else:
            raise NoName("You missed to enter name. "
                             "Please check the value and try again")

class Phone(Field):

    @staticmethod
    def is_valid_phone(phone):
        if phone == '':
            return True
        match = re.search(r"^\+?[1-9][\d]{11}$", phone)
        return bool(match)

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        if self.is_valid_phone(val):
            self._value = val
        else:
            raise WrongPhone("You tried to enter an invalid phone number. "
                             "Please check the value and try again")

class Birthday(Field):

    @staticmethod
    def is_valid_date(date):
        try:
            if date == '':
                return True
            datetime.strptime(str(date), "%d.%m.%Y")
            return True
        except ValueError:
            return False

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        if self.is_valid_date(val):
            self._value = val
        else:
            raise WrongDate(
                "Invalid date. Please enter birthday in format 'DD.MM.YYYY'.")

class Address:
    def __init__(self, street="", city="", country="", postcode=""):
        self.street = street
        self.city = city
        self.country = country
        self.postcode = postcode

    def __str__(self):
        return f"{self.street},{self.city},{self.country},{self.postcode}"

    def __repr__(self):
        return f"Address(street='{self.street}', city='{self.city}', country='{self.country}', postcode='{self.postcode}')"

class Email:
    def __init__(self, value=""):
        self.value = value

    @staticmethod
    def is_valid_email(email):
        if email == '':
            return True
        match = re.search(
            r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", email)
        return bool(match)

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        if self.is_valid_email(val):
            self._value = val

        else:
            raise WrongEmail(
                "Invalid email address. Please enter a correct email address")

    def __str__(self) -> str:
        return self.value

    def __repr__(self) -> str:
        return str(self)

class Record:
    def __init__(self, name, phones=None, birthday=None, address=None, email=None):
        self.name = name
        self.phones = phones
        self.birthday = birthday
        self.address = address
        self.email = email

    def __str__(self):
        phones = ", ".join([str(phone) for phone in self.phones])
        birthday = f"Birthday: {self.birthday}" if self.birthday.value else "Birthday:"
        address_str = f"Address: {self.address}" if self.address else ""
        email_str = f"Email: {self.email}" if self.email else ""
        return f"{self.name.value}: {phones}, {birthday}, {address_str}, {email_str}"

    def __repr__(self):
        return str(self)

    def add_phone(self, phone: Phone):
        if phone in self.phones:
            return f"User {self.name.value} already has {phone} phone number."
        else:
            self.phones.append(phone)
        self.phones = list(set(self.phones))
        return f"Phone number {phone} is added successfully for user {self.name.value}."

    def change_phone(self, old_number: Phone, new_number: Phone):
        if old_number not in self.phones:
            return f"Number {old_number} not found."
        else:
            phone_number_index = self.phones.index(old_number)
            self.phones[phone_number_index] = new_number
            return f"The phone number {old_number} for the user {self.name} "\
                f"has been changed to {new_number}"

    def delete_phone(self, phone):
        try:
            self.phones.remove(phone)
            return f"Phone number {phone} for user {self.name} deleted successfully."
        except ValueError:
            return f"Phone number {phone} for user {self.name} not found"

    def days_to_birthday(self):
        try:
            birthday = datetime.strptime(str(self.birthday), "%d.%m.%Y").date()
        except ValueError:
            return f"No birthday for user {self.name.value}"

        today = date.today()
        birthday = birthday.replace(year=today.year)
        if birthday < today:
            birthday = birthday.replace(year=today.year+1)
        result = (birthday - today).days
        birthday_str = birthday.strftime("%d %B")
        return f"The birthday of user {self.name} will be in {result} days, {birthday_str}"

    def change_birthday(self, birthday: Birthday):
        self.birthday = birthday
        return f"Birthday date for user {self.name.value} is changed to {birthday} successfully."

    def change_address(self, address: Address):
        self.address = address
        return f"Address {address} for user {self.name.value} is changed successfully."

    def change_email(self, new_email: Email):
        self.email = new_email
        return f"Email {new_email} for user {self.name.value} is changed successfully."

class AddressBook(UserDict):
    def add_record(self, record):
        self[record.name.value] = record

    def delete_record(self, name: Name):
        del self[name.value]

    def change_record(self, name, new_record):
        self[new_record.name.value] = new_record

    def search(self, field: str, text: str) -> list[Record]:
        result = []
        if field.lower() == "name":
            for record in self.data.values():
                if text in record.name.value:
                    result.append(record)
        elif field.lower() == "phone":
            for record in self.data.values():
                for phone in record.phones:
                    if text in phone.value:
                        result.append(record)
        elif field.lower() == "email":
            for record in self.data.values():
                if text.lower() in record.email.value.lower():
                    result.append(record)
        return result

    def show_birthday(self, days: int):
        result_list = []
        result_to_print = []
        now = datetime.today()
        start_date = now.replace(hour=0, minute=0, second=0, microsecond=0)
        for record in self.data.values():
            if record.birthday.value:
                birthday = datetime.strptime(str(record.birthday.value), "%d.%m.%Y")
                birthday = birthday.replace(year=start_date.year)
                if birthday < start_date:
                    birthday = birthday.replace(year=start_date.year+1)
                gap = birthday - start_date
                gap = gap.days
                result_list.append([str(record.name.value), birthday, gap])
        result_list = sorted(result_list, key=lambda person: person[2])
        result_to_print = [f'{value[1].strftime("%d.%m.%Y")}: {value[0]}' for value in result_list if value[2] <= days]
        if result_to_print:
            print(f"Birthdays today and within {days} next day(s):")
            print(*result_to_print, sep='\n')
        else:
            if days == 1:
                return f"There are no birthdays to show within {days} day"
            else:
                return f"There are no birthdays to show within {days} days"
        return None

    @classmethod
    def open_file(cls, filename):
        """Take as input filename. Return AddressBook"""
        try:
            with open(filename, encoding="utf-8") as file:
                json_data = json.load(file)
                data = cls()
                for name, record in json_data.items():
                    name = Name(name)
                    phones = [Phone(phone) for phone in record["phones"]]
                    birthday = Birthday(record["birthday"])
                    address = Address(**record["address"])
                    email = Email(record["email"])

                    data.add_record(
                        Record(name, phones, birthday, address, email))
        except FileNotFoundError:
            data = cls()
        return data

    def write_to_file(self, filename: str):
        json_data = {}

        for name, record in self.data.items():
            json_data[name] = {
                "phones": [phone.value for phone in record.phones],
                "birthday": record.birthday.value if record.birthday is not None else '',
                "address": {
                    "street": record.address.street if record.address is not None else '',
                    "city": record.address.city if record.address is not None else '',
                    "country": record.address.country if record.address is not None else '',
                    "postcode": record.address.postcode if record.address is not None else '',
                },
                "email": record.email.value if record.email is not None else ''
            }
        with open(filename, "w", encoding="utf-8") as file:
            json.dump(json_data, file, indent=4, ensure_ascii=False)

    def __iter__(self):
        self.current_page = 1
        self.page_size = 10
        self.start_index = (self.current_page - 1) * self.page_size
        self.end_index = self.start_index + self.page_size
        return self

    def __next__(self):
        if self.start_index >= len(self.data):
            raise StopIteration

        page_records = list(self.data.values())[
            self.start_index:self.end_index]
        self.start_index = self.end_index
        self.end_index = self.start_index + self.page_size
        self.current_page += 1

        return page_records

if __name__ == "__main__":
    pass


import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from weather_gui import Ui_MainWindow

app = QtWidgets.QApplication([])

class MainApplication(QtWidgets.QMainWindow, Ui_MainWindow):

    def __init__(self, *args, **kwargs):
        super(MainApplication, self).__init__(*args, **kwargs)
        self.setupUi(self)

        self.show()

window = MainApplication()
window.show()

sys.exit(app.exec_())


import sys
from PIL import Image

CENTER = Image.open('center.bmp')
N = Image.open('N.bmp')
S = Image.open('S.bmp')
W = Image.open('W.bmp')
E = Image.open('E.bmp')
NW = Image.open('NW.bmp')
NE = Image.open('NE.bmp')
SW = Image.open('SW.bmp')
SE = Image.open('SE.bmp')
WIDTH = 32
HEIGHT = 32

def do():
    if len(sys.argv) != 3:
        print('Bad argument count')
        return
    width = int(sys.argv[1])
    height = int(sys.argv[2])
    result = Image.new('RGBA', (width*WIDTH, height*HEIGHT), (0, 0, 0, 0))
    result.paste(NW, (0, 0))
    result.paste(NE, ((width-1)*WIDTH, 0))
    result.paste(SW, (0, (height-1)*HEIGHT))
    result.paste(SE, ((width-1)*WIDTH, (height-1)*HEIGHT))
    # left
    for i in range(height-2):
        result.paste(W, (0, (i+1)*HEIGHT))
    # right
    for i in range(height-2):
        result.paste(E, ((width-1)*WIDTH, (i+1)*HEIGHT))
    # top
    for i in range(width-2):
        result.paste(N, ((i+1)*WIDTH, 0))
    # bottom
    for i in range(width-2):
        result.paste(S, ((i+1)*WIDTH, (height-1)*HEIGHT))
    # center
    for i in range(height-2):
        for j in range(width-2):
            result.paste(CENTER, ((j+1)*WIDTH, (i+1)*HEIGHT))

    result.save('result.bmp')

do()


from django import forms
from .models import *
from django.utils import timezone
from django.forms import ModelForm, Textarea, TextInput
from ckeditor.widgets import CKEditorWidget
from django.core.files.images import get_image_dimensions
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from django.forms.widgets import FileInput, EmailInput

class TopicoForm(ModelForm):
    class Meta:

        fields = '__all__'
        exclude = ['data_postagem']
        widgets = {
            'text': CKEditorWidget()
        }

    def clean_titulo(self):
        titulo = self.cleaned_data['titulo']
        if not titulo:
            raise ValidationError(_("Это поле является обязательным."), code='invalid')
        return titulo

    def clean_texto(self):
        texto = self.cleaned_data['texto']
        if not texto:
            raise ValidationError(_("Это поле является обязательным."), code='invalid')
        return texto

class RespostaForm(ModelForm):
    class Meta:
        model = Resposta
        fields = '__all__'
        exclude = ['data_postagem']
        widgets = {
            'texto': CKEditorWidget()
        }

    def clean_texto(self):
        texto = self.cleaned_data['texto']
        if not texto:
            raise ValidationError(_("Это поле является обязательным."), code='invalid')
        return texto

class UserForm(ModelForm):
    class Meta:
        model = User
        fields = ['avatar', 'username', 'password', 'first_name', 'last_name', 'email']

    def clean_avatar(self):
        avatar = self.cleaned_data['avatar']
        if avatar:
            try:
                w, h = get_image_dimensions(avatar)

                max_width = 800
                max_height = 600
                if w > max_width or h > max_height:

                    raise ValidationError(_('Максимальное разрешение изображения 800x600.'), code='invalid')

                main, sub = avatar.content_type.split('/')
                if not (main == 'image' and sub in ['jpeg', 'pjpeg', 'gif', 'png']):
                    raise ValidationError(_('Доступные форматы изображения JPEG, GIF и PNG.'), code='invalid')

                #valida o tamanho da imagem
                if len(avatar) > (40 * 1024):
                    raise ValidationError(_('Максимальный размер изображения 40k.'), code='invalid')

            except AttributeError:
                pass

            return avatar

    def clean_username(self):
        username = self.cleaned_data['username']
        #verifica se o usuario já existe
        if User.objects.filter(username=username).exists():
            raise ValidationError(_("Имя пользователя занято, выберите другой!"), code='invalid')

        return username

    def clean_email(self):
        email = self.cleaned_data['email']

        if not email:
            raise ValidationError(_("Это поле является обязательным."), code='invalid')

        #verifica se o email já foi usado
        if User.objects.filter(email=email).exists():
            raise ValidationError(_("Этот адрес электронной почты уже связан с учетной записью."), code='invalid')
        return email

class UserUpdateForm(ModelForm):
    class Meta:
        model = User
        fields = ['avatar', 'first_name', 'last_name', 'email']

    def clean_email(self):
        email = self.cleaned_data['email']
        if not email:
            raise ValidationError(_("Это поле является обязательным."), code='invalid')
        return email

    def clean_avatar(self):
        avatar = self.cleaned_data['avatar']
        if avatar:
            try:
                w, h = get_image_dimensions(avatar)

                #verifica a resolucao da imagem
                max_width = 800
                max_height = 600
                if w > max_width or h > max_height:

                    raise ValidationError(_('Максимальное разрешение изображения 800x600.'), code='invalid')

                #valida o formato da imagem
                main, sub = avatar.content_type.split('/')
                if not (main == 'image' and sub in ['jpeg', 'pjpeg', 'gif', 'png']):
                    raise ValidationError(_('Доступные форматы изображения  JPEG, GIF и PNG.'), code='invalid')

                #valida o tamanho da imagem
                if len(avatar) > (40 * 1024):
                    raise ValidationError(_('Максимальный размер изображения 40k.'), code='invalid')

            except AttributeError:
                pass
        return avatar


# Package imports
import pandas as pd
import glob
import pickle
from tqdm import tqdm

# Create data
files = glob.glob("data/processed/Graphs/*")
cols = ['time', 'time_to_reservation', 'park_location_lat', 'park_location_long', 'leave_location_lat', 'leave_location_long','park_zone', 'leave_zone', 'park_fuel', 'leave_fuel', 'engine', 'moved','prev_customer', 'next_customer',
        'movedTF', 'action', 'weekend', 'Time_Cos', 'Time_Sin', 'mean_temp', 'mean_wind_speed', 'acc_precip', 'bright_sunshine', 'mean_pressure', 'mean_relative_hum', 'mean_cloud_cover', 'dist_to_station', 'degree']
df = pd.DataFrame(columns = cols)

i = 0
for f in tqdm(files):
    with open(f, 'rb') as day_file:
        day = pickle.load(day_file)

    for attr, adj in day.values():
        df.loc[i] = list(attr.iloc[-1].values)+[adj.getrow(-1).sum()]
        i += 1

df['timeh'] = df.time.round('h').dt.hour
trafic_index = dict(df.groupby('timeh').mean()['time_to_reservation'])
df.drop(columns = ['timeh'], inplace=True)
df['hour_index'] = df.time.dt.hour.map(trafic_index)

# Only to customers
df = df[df.next_customer]
df.drop(columns=['prev_customer', 'next_customer'], inplace = True)

# No more than 2 days
df = df[df.time_to_reservation < 48]

# Remove zones with too little support
df = df[~df.leave_zone.isin((df.leave_zone.value_counts() < 30).index[df.leave_zone.value_counts() < 30])]

# One hot encoding
df = pd.get_dummies(df, columns = ['engine','leave_zone'], prefix=['eng','lz'])

# Drop those far away
df = df[df['dist_to_station'] <= 7000]

# Drop some columns
df.drop(columns=['park_location_lat', 'park_location_long', 'leave_location_lat', 'leave_location_long', 'park_fuel', 'park_zone', 'moved', 'movedTF', 'action'], inplace = True)

# Reset index
df = df.reset_index(drop=True)

# Save
df.to_csv('data/processed/SimpleNNData.csv')


from Drive import GoogleDrive, Watcher, bcolors
import sys
from termcolor import cprint
import argparse

def main():
    parser = argparse.ArgumentParser(description="Sync folder with Google Drive")
    parser.add_argument('--name', '-n', type=str, required=True, dest='name', help="Exact name of the GDrive folder")
    parser.add_argument('--dir', '-d', type=str, required=True, dest='path', help="Path to the local folder")
    args = parser.parse_args()
    my_drive = GoogleDrive('client_id.json')
    my_drive.authenticate()
    watcher = Watcher(args.name, args.path, my_drive)
    print("\033[95m Syncing files \033[0m")
    watcher.pull()
    watcher.push()

if __name__ == "__main__":
    main()