#!/usr/local/bin/python3

import os, sys, pprint, logging
import Inventory_Modules
import argparse, boto3
from colorama import init,Fore,Back,Style
from botocore.exceptions import ClientError, NoCredentialsError

init()

parser = argparse.ArgumentParser(
	description="We\'re going to find all resources within any of the profiles we have access to.",
	prefix_chars='-+/')
parser.add_argument(
	"-p","--profile",
	dest="pProfile",
	metavar="profile to use",
	help="To specify a specific profile, use this parameter. Default will be ALL profiles, including those in ~/.aws/credentials and ~/.aws/config")
parser.add_argument(
	"-f","--fragment",
	dest="pstackfrag",
	metavar="CloudFormation stack fragment",
	default=["all"],
	help="String fragment of the cloudformation stack or stackset(s) you want to check for.")
parser.add_argument(
	"-s","--status",
	dest="pstatus",
	metavar="CloudFormation status",
	default="active",
	help="String that determines whether we only see 'CREATE_COMPLETE' or 'DELETE_COMPLETE' too")
parser.add_argument(
	"-r","--region",
	nargs="*",
	dest="pregion",
	metavar="region name string",
	default=["us-east-1"],
	help="String fragment of the region(s) you want to check for resources.")
parser.add_argument(
	'-v',
	help="Be verbose",
	action="store_const",
	dest="loglevel",
	const=logging.ERROR, # args.loglevel = 40
	default=logging.CRITICAL) # args.loglevel = 50
parser.add_argument(
	'-vv', '--verbose',
	help="Be MORE verbose",
	action="store_const",
	dest="loglevel",
	const=logging.WARNING, # args.loglevel = 30
	default=logging.CRITICAL) # args.loglevel = 50
parser.add_argument(
	'-d',
	help="Print debugging statements",
	action="store_const",
	dest="loglevel",
	const=logging.INFO,	# args.loglevel = 20
	default=logging.CRITICAL) # args.loglevel = 50
parser.add_argument(
	'-dd', '--debug',
	help="Print LOTS of debugging statements",
	action="store_const",
	dest="loglevel",
	const=logging.DEBUG,	# args.loglevel = 10
	default=logging.CRITICAL) # args.loglevel = 50
args = parser.parse_args()

pProfile=args.pProfile
pRegionList=args.pregion
pstackfrag=args.pstackfrag
pstatus=args.pstatus
verbose=args.loglevel
logging.basicConfig(level=args.loglevel, format="[%(filename)s:%(lineno)s:%(levelname)s - %(funcName)20s() ] %(message)s")

SkipProfiles=["default"]
ChildAccounts=Inventory_Modules.find_child_accounts2(pProfile)

NumStacksFound=0
##########################
ERASE_LINE = '\x1b[2K'

print()
fmt='%-20s %-15s %-15s %-50s'
print(fmt % ("Account","Region","Status","StackSet Name"))
print(fmt % ("-------","------","------","-------------"))
RegionList=Inventory_Modules.get_ec2_regions(pRegionList)

sts_session = boto3.Session(profile_name=pProfile)
sts_client = sts_session.client('sts')
for account in ChildAccounts:
	role_arn = "arn:aws:iam::{}:role/AWSCloudFormationStackSetExecutionRole".format(account['AccountId'])
	logging.info("Role ARN: %s" % role_arn)
	try:
		account_credentials = sts_client.assume_role(
			RoleArn=role_arn,
			RoleSessionName="Find-StackSets")['Credentials']
	except ClientError as my_Error:
		if str(my_Error).find("AuthFailure") > 0:
			print(profile+": Authorization Failure for account {}".format(account['AccountId']))
	for region in RegionList:
		try:
			StackSets = None
			print(ERASE_LINE,Fore.RED+"Checking Account: ",account['AccountId'],"Region: ",region+Fore.RESET,end="\r")
			StackSets=Inventory_Modules.find_stacksets2(account_credentials,region,account['AccountId'],pstackfrag)
			logging.warning("Account: %s | Region: %s | Found %s Stacksets", account['AccountId'], region, len(StackSets))
			if not StackSets == []:
				print(ERASE_LINE,Fore.RED+"Account: ",account['AccountId'],"Region: ",region,"Found",len(StackSets),"Stacksets"+Fore.RESET,end="\r")
			for y in range(len(StackSets)):
				StackName=StackSets[y]['StackSetName']
				StackStatus=StackSets[y]['Status']
				print(fmt % (account['AccountId'],region,StackStatus,StackName))
				NumStacksFound += 1
		except ClientError as my_Error:
			if str(my_Error).find("AuthFailure") > 0:
				print(account['AccountId']+": Authorization Failure")
print(ERASE_LINE)
print(Fore.RED+"Found",NumStacksFound,"Stacksets across",len(ChildAccounts),"accounts across",len(RegionList),"regions"+Fore.RESET)
print()
print("Thanks for using this script...")


dict_history = [];

def binary_search(list, item):
    # array indices
    low = 0
    high = len(list) - 1
    global dict_history;

    def print_dic(dict):
        for val in dict:
            # print(val)  # prints dict at index    # {'item': 9, 'low': 0, 'high': 100, 'mid': 50, 'guess': 50}

            # prints in nicely formatted python2
            #     search val: 9    low: 0          high: 100        mid: 50          guess: 50
            print('search val: %s  \t low: %s  \t high: %s  \t  mid: %s  \t   guess: %s' % (val['item'], val['low'], val['high'], val['mid'], val['guess']))
                # this will print out val
            for k, v in val.items(): # we can use any variable for key, value positions
                # print(f'\t Key: {k} \t Value: {v}')   # python 3
                print("\t Key: %s \t Value: %i " % (k, v))

    while low <= high:
        # print(f'search val: {item}   low: {low} high: {high} mid: {mid}')
        mid = (low + high) // 2    # gives floor, rounded down val
        guess = list[mid]     # check the middle val
            # python3 syntax
        # print(f'search val: {item}  \t low: {low}  \t high: {high}  \t  mid: {mid}  \t   guess: {guess}')
            # python2 syntax
        # print('search val: %s  \t low: %s  \t high: %s  \t  mid: %s  \t   guess: %s' % (item, low, high, mid, guess))
        # dict_history.append({item: item, low: low ,high: high, mid: mid,  guess: guess})   # saves k &v as same e.g.     { 9: 9, 50: 50, ...}
        dict_history.append({'item': item, 'low': low, 'high': high, 'mid': mid, 'guess': guess})
        if guess == item:
            #  return mid     # middle is actual item    --> use with # print(binary_search(test_list, find))
            # python 3 syntax
            #return print(f' item located: {guess}')
                # python 2 syntax
            print("item located {} after {} iterations".format(guess, len(dict_history)) )
            print_dic(dict_history)
            return None
        elif guess > item:
            high = mid - 1  # look in lower half
        else:
            low = mid + 1   # look in upper half
    return None

test_list =  list(range(0,101))   # generate list 1 to 100
find = 9

# print(binary_search(test_list, find))
binary_search(test_list, find)


import requests
from bs4 import BeautifulSoup
from lxml import html
from lxml import etree
import pandas as pd
import numpy as np
from pprint import PrettyPrinter
from re import sub

# my pp
pp = PrettyPrinter()

# # This code is meant to import screenplays from imsdb.com (Futurama) and automatically import all of them for preprocessing.
#
# I've tested the current function and this works with separating names from characters for two scripts.

def data_scrape(link, sname):
    # Get page and make soup
    page = requests.get(link) #Go to IMSDB link
    soup = BeautifulSoup(page.content, features="lxml") #Pull the content
    anchors = soup.find_all('a') #Pull links

    # Splinter cell
    blacklist = [
        'The Internet Movie Script Database',
        'Internet Movie Script Database (IMSDb)'
    ]

    # titles
    links = []
    for anchor in anchors:
        title = anchor.get('title')
        if (title is not None) and ('Script' in title) and (title not in blacklist):
            link = title.replace(' ', '-')
            link = link.rstrip('-Script')
            link = f'https://www.imsdb.com/transcripts/{sname}-{link}.html'
            if link not in links:
                links.append(link)

    return links

    # titles = []
    # for title in links:
    #     temp = title.get('title') #only pull links with the word title in them
    #     if (temp is not None) and ('Script' in temp): #Only Pull values that are not none and with the words script in them
    #         if temp not in titles:
    #             titles.append(temp)
    # titles=titles[1:-1] #ignore the first and last lines
    # nlink=[]
    # for index in range(len(titles)):
    #     titles[index]=titles[index].split('Script')[0]
    #     nlink.append(titles[index])
    #     nlink[index]=nlink[index].replace(" ","-")
    #     nlink[index]=nlink[index].strip("-")
    #     nlink[index]="https://www.imsdb.com/transcripts/"+sname+'-'+nlink[index]+".html"
    # return np.asarray(nlink), np.asarray(titles)

def gscrnplay(link):
    page = requests.get(link)
    soup = BeautifulSoup(page.content, features="lxml")
    text = soup.find('td', class_='scrtext').get_text()
    text = text.split('THE END')[0] #We don't need anything below 'THE END'
    temp=text.split('\n\n') #Separates the Title Sequence since it's unneeded.
    ### Need to fix this so that it's automated. Sectioned 8 might not be used for all TV scripts
    scrnplay = ''.join(temp[8:]) #Connect the strings back together, except the title sequence
    return scrnplay

def gcharnames(scrnplay):
    characters = scrnplay.split(' \n') #Remove lines that have issues
    #names is a list of the characters in the dialogue.
    names = []; #Create empty list
    for test in characters:
        scr = test.split('\n') #Separate more lines
        if len(scr) > 1:
            pname=(scr[0].strip()).split('\n') #Remove spaces and the more lines to separate the character names from dialogue
            for n in pname:
                if n.isupper() is True: #Characters are separated from dialogue via uppercase.
                    n= n.split('[')
                    n = n[0]
                    n = ''.join(u for u in n if u not in ("."))
                    n = n.strip()
                    n = n.strip('"')
                    if n not in names:
                        names.append(n)
    return names

if __name__ == '__main__':
    links = data_scrape('https://www.imsdb.com/TV/Futurama.html', 'Futurama')
    pp.pprint(links)

    data = [];
    for link in links:
        info = {};
        scrnplay = gscrnplay(link)
        data.append({
            "title" : link,
            "scrnplay" : scrnplay,
            "characters" : gcharnames(scrnplay)
        })

    script = data[0]['scrnplay']
    test = script.split('\n');
    for i in range(len(test)):
        test[i] = test[i].strip();
    test_list = [i for i in test if i]


def commonCharacterCount(s1, s2):
    #return sum([min(s1.count(c),s2.count(c)) for c in set(s1) & set(s2)])
    d1 = {}
    d2 = {}
    for c in s1:
        d1[c] = d1.get(c, 0) + 1
    for c in s2:
        d2[c] = d2.get(c, 0) + 1

    t = 0
    for i in range(ord('a'), ord('z')+1):
        t += min(d1.get(chr(i), 0), d2.get(chr(i), 0))

    return t


import json
import subprocess
import time
import argparse
import datetime

def main(a):
    if not a.json:
        return
    data = json.load(open(a.json))
    data = sorted(data, key=lambda x: x["score"] / x["g_cost"])
    for result in data:
        print("{seed}:".format(seed=result["seed"]))
        print("S = {S}".format(S=result["S"]))
        print("guess = {guess}".format(guess=result["guess"]))
        print("look = {look}".format(look=result["look"]))
        print("score = {score}".format(score=("%.5f" % (result["score"] / result["g_cost"]))))
        print()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='This script is ...')
    parser.add_argument('-f', '--json',
                        action='store',
                        nargs=None,
                        const=None,
                        default=None,
                        type=str,
                        choices=None,
                        help='Directory path where your taken photo files are located.',
                        metavar=None)
    args = parser.parse_args()
    main(args)


# O(N) time | O(1) space
class Solution:
    def floodFill(self, image: List[List[int]], sr: int, sc: int, color: int) -> List[List[int]]:
        ROWS, COLS = len(image), len(image[0])

        def dfs(row, col, startColor=image[sr][sc]):
            if not 0 <= row < ROWS or not 0 <= col < COLS or image[row][col] != startColor:
                return

            image[row][col] = color

            dfs(row - 1, col)
            dfs(row, col + 1)
            dfs(row + 1, col)
            dfs(row, col - 1)

        if image[sr][sc] != color:
            dfs(sr, sc)

        return image


#!/usr/bin/env python3

# File: webserver.py
# Description: cn-atda6 socket programming assignment 1, python version
#              a simple webserver which accepts a file path and return that file
#              in a http response
# Author: Burgess Wong
# Created Date: 2013-9-26

import io
import mimetypes
import socket

def resolve_request(request):
    request_line, sep, request = request.partition(b'\r\n')
    method, url, version = request_line.split(b' ')

    return (url, version)

def generate_response(version, status_code, phrase, content_type, file_contents):
    status_line = version + b' ' + ' '.join([status_code, phrase]).encode('ASCII')
    connection_line = b'Connection: close'
    content_length_line = ('Content-Length: ' + str(len(file_contents))).encode('ASCII')
    content_type_line = ('Content-Type: ' + content_type).encode('ASCII')
    response_body = file_contents

    return b'\r\n'.join([status_line, connection_line, content_length_line, content_type_line + b'\r\n', response_body])

if __name__ == '__main__':

    # initialize the sock
    server_ip = ''
    server_port = 8080
    server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_sock.bind((server_ip, server_port))
    server_sock.listen(1)

    # infinite loop waiting for and processing requests
    while 1:
        print('---Listening---\n')

        connect_sock, address = server_sock.accept()
        request = connect_sock.recv(4096)

        print('---Request comes from IP: ' + str(address[0]))

        # ignore empty request
        if len(request) == 0:
            print('---Empty request, ignore')
            print('')
            continue

        # resolve the request
        url, version = resolve_request(request)
        path = url.decode('ASCII')

        print('---Requested file path: ' + path)

        # try to open the file in the filesystem
        try:
            file_contents = open(path, 'rb').read()
            status_code = '200'
            phrase = 'OK'
            content_type = mimetypes.guess_type(path)[0]
            if not content_type:
                content_type = 'text/plain'
            print('---File ' + path + ' found, generate 200 OK response')
        except IOError:
            file_contents = b'404: Page Not Found - by Burgess Wong'
            status_code = '404'
            phrase = 'Not Found'
            content_type = 'text/html'
            print('---File ' + path + ' not found, generate 404 Not Found response')

        # make the response message
        response = generate_response(version, status_code, phrase, content_type, file_contents)

        # send the response and close the socket
        connect_sock.send(response)

        print('---Response sent')

        connect_sock.close()

        print('---Connection with IP ' + str(address[0]) + ' closed\n')


from yxsim.action import Action
from yxsim.cards.base import Card
from yxsim.combat import combat
from yxsim.player import Player
from yxsim.resources import Sect

class CardType(Card):
    display_name = 'Normal Attack'
    phase = 1
    sect = Sect.CLOUD

    def play(self, attacker: Player, defender: Player, **kwargs) -> Action:
        return Action(
            card=self,
            source=attacker,
            target=defender,
            damage=self.damage
        ).execute()

    def test_card(self):
        card_user, opponent = self.generate_test_data()
        combat(card_user, opponent, limit=1)
        action = card_user.actions[0]
        assert isinstance(action, Action)
        assert action.card.id == self.id
        assert action.source == card_user
        assert action.target == opponent
        assert action.damage == 3
        assert action.executed is True
        assert action.success is True
        assert opponent.health == opponent.max_health - 3


import unittest

from profile_chrome import profiler

from devil.android import device_utils
from devil.android.sdk import intent

class BaseControllerTest(unittest.TestCase):
  def setUp(self):
    devices = device_utils.DeviceUtils.HealthyDevices()
    self.browser = 'stable'
    self.package_info = profiler.GetSupportedBrowsers()[self.browser]
    self.device = devices[0]

    self.device.ForceStop(self.package_info.package)
    self.device.StartActivity(
        intent.Intent(activity=self.package_info.activity,
                      package=self.package_info.package),
        blocking=True)


''' Chapter 11.26 '''

def main():
    m = []
    createMatrix(m)
    sortRows(m)
    print("The row-sorted list is ")
    printMatrix(m)

# 0.15 0.875 0.375
# 0.55 0.005 0.225
# 0.30 0.12 0.4

def createMatrix(m):
    print("Enter a 3-by-3 matrix row by row:")
    number0 = input()
    number1 = input()
    number2 = input()

    elements0 = number0.split()
    elements1 = number1.split()
    elements2 = number2.split()

    m.append([eval(x) for x in elements0])
    m.append([eval(y) for y in elements1])
    m.append([eval(z) for z in elements2])

def sortRows(m):
    rows = len(m)
    columns = len(m[0])

    for i in range(0, rows):
        for j in range(0, columns - 1):
            if(m[i][j] > m[i][j + 1]):
                temp = m[i][j + 1]
                m[i][j + 1] = m[i][j]
                m[i][j] = temp

def printMatrix(m):
    rows = len(m)
    columns = len(m[0])

    for i in range(0, rows):
        for j in range(0, columns):
            print(format(m[i][j],".3f"), end = " ")
        print()

if __name__ == "__main__":
    main()


#Window Server Code
#2. server.py

import cv2
import imagezmq

share = imagezmq.ImageHub()

while True:
    rasp,iamge = share.recv_image()
    cv2.imshow(rasp, image)
    if cv2.WaitKey(1) == ord('q'):
        break
    image.send_reply(b'ok')


import pymysql

db=pymysql.connect('localhost','root','123456','java1')
cur=db.cursor()
sql='SELECT * FROM node'
try:
    cur.execute(sql)
    res=cur.fetchall()
    for i in res:
        number=i[0]
        xcoord=i[1]
        ycoord=i[2]
        print('number=%d xcoord=%d ycoord=%d'%(number,xcoord,ycoord))
except :
    print('数据错误')

db.close()


from PyQt5.QtCore import Qt, QRect
from PyQt5.QtGui import QPixmap, QPainter, QFont, QColor
from Picture import Picture

class MiddlePicture(Picture):
    # A middle picture is consisted of a background picture
    # a caption and a subtitle
    def __init__(self, size : int):
        super().__init__()
        self.caption_text = ""
        self.subtitle_text = ""
        self.background_alpha = 0.25
        self.background_color = QColor("white")
        self.size = size
        self.caption_font = QFont()
        self.subtitle_font = QFont()
        self.caption_color = QColor("black")
        self.subtitle_color = QColor("black")
        self.caption_offset = 0
        self.edit_enabled = False

    def set_size(self, size : int):
        self.size = size

    def set_background_alpha(self, alpha : float):
        self.background_alpha = alpha
        self.changed = True

    def set_background_color(self, color : QColor):
        self.background_color = color
        self.changed = True

    def set_caption_font(self, font : QFont):
        # Set the font and font size of the caption
        self.caption_font = font
        self.changed = True

    def set_subtitle_font(self, font : QFont):
        # Set the font and font size of the subtitle
        self.subtitle_font = font
        self.changed = True

    def set_caption_text(self, text : str):
        # Set the text of the caption
        self.caption_text = text
        self.changed = True

    def set_caption_color(self, color : QColor):
        # Set the color of the caption
        self.caption_color = color
        self.changed = True

    def set_subtitle_color(self, color : QColor):
        # Set the color of the subtitle
        self.subtitle_color = color
        self.changed = True

    def set_subtitle_text(self, text : str):
        # Set the text of the subtitle
        self.subtitle_text = text
        self.changed = True

    def set_caption_offset(self, offset : int):
        # Set the offset of the caption
        # The caption will be moved by `offset` upwards,
        # and the subtitle will be moved `offset` downwards
        self.caption_offset = offset
        self.changed = True

    def set_edit_enabled(self, editable : bool):
        # Set whether the middle picture is going to be edited
        self.edit_enabled = editable
        self.changed = True

    def automatic_adjust_on(self, image : QPixmap):
        # This fits and crops the background picture into its size and
        if image == None:
            raise FileExistsError("Background image file not found or not loaded.")
        if image.width() > image.height():
            # Horizontal image, fit height to size
            image = image.scaledToHeight(self.size, Qt.SmoothTransformation)
        elif image.height() >= image.width():
            # Vertical image, fit width to size
            image = image.scaledToWidth(self.size, Qt.SmoothTransformation)
        # Crop to its center square
        image = self.crop(image, QRect(image.width()//2-self.size//2, image.height()//2-self.size//2, self.size, self.size))
        return image

    def automatic_adjust(self):
        self.processed_image = self.automatic_adjust_on(self.processed_image)
        self.width = self.processed_image.width
        self.height = self.processed_image.height
        self.changed = True

    def set_color(self, color : str):
        self.background_color = color
        self.changed = True

    def render_image_on(self, image : QPixmap):
        # Render the image
        if image == None:
            raise FileExistsError("Background image file not found or not loaded.")
        if image.width() != image.height():
            print(f"Image width {image.width()} but image height {image.height()}")
            raise Exception("The background is not a square! Please adjust.")

        rendered_img = QPixmap(self.size, self.size)
        rendered_img.fill(self.background_color)
        draw = QPainter(rendered_img)
        # Blend the image with background
        draw.setOpacity(self.background_alpha)
        draw.drawPixmap(0, 0, image)
        # Add the caption to the image
        # Currently just add the caption to the center
        draw.setFont(self.caption_font)
        draw.setOpacity(1.0)
        caption_bound = draw.fontMetrics().boundingRect(self.caption_text)
        caption_x = self.size // 2 - caption_bound.width() // 2
        caption_y = self.size // 2 - caption_bound.height() - self.caption_offset
        draw.setPen(self.caption_color)
        draw.drawText(caption_x, caption_y, caption_bound.width(), caption_bound.height(), Qt.AlignLeft, self.caption_text)

        draw.setFont(self.subtitle_font)
        subtitle_bound = draw.fontMetrics().boundingRect(self.subtitle_text)
        subtitle_x = self.size // 2 - subtitle_bound.width() // 2
        subtitle_y = self.size // 2 + self.caption_offset
        draw.setPen(self.subtitle_color)
        draw.drawText(subtitle_x, subtitle_y, subtitle_bound.width(), subtitle_bound.height(), Qt.AlignLeft, self.subtitle_text)

        draw.end()
        return rendered_img

    def render_image(self):
        self.processed_image = self.automatic_adjust_on(self.original_image)
        if self.edit_enabled:
            self.processed_image = self.render_image_on(self.processed_image)
        self.changed = True

    def draw_image_preview(self):
        # Draw preview - overridden
        image_preview = self.original_image.copy()
        image_preview = self.automatic_adjust_on(image_preview)
        if self.edit_enabled:
            image_preview = self.render_image_on(image_preview)
        return image_preview

    def split_into_nine(self):
        # TODO: Implement function to split the central picture into 9 pics
        # Make the image 3 times larger
        image_to_be_splitted = self.draw_image_preview()
        image_to_be_splitted = image_to_be_splitted.scaled(3*self.size, 3*self.size)
        image_splitted_list = []
        for i in range(3):
            for j in range(3):
                image_piece = self.crop(image_to_be_splitted, QRect(j*self.size, i*self.size, self.size, self.size))
                image_splitted_list.append(image_piece)
        return image_splitted_list


import re

"""
#expect two digits from the given input
# allow only 0-5

"""

#pattern = "hi{1,2}";
pattern = "[0-5]{2}";

test_strings = ['hi123bye', 'Apple', 'cat', '---B---', '1313','!@#!#!#!#','6789','hi123hibye','hii','hi hi hi hi']

test_strings = ['1','99','11111']

for testStr in test_strings:
  result = re.search(pattern, testStr)

  if result:
    print(testStr, " - valid successful.")
  else:
    print(testStr, " -Invalid.")


# Exercise 1 Chapter 10 Page 135
inp = input("Please enter the filename: ")
if len(inp)<1:
    inp = 'mbox.txt'
try:
    fhand = open(inp)
except:
    print("Cannot open the file:",inp)
    quit()
count_dict = dict()
for line in fhand:
    words = line.split()
    length = len(words)
    if line.startswith("From") and length > 1:
        count_dict[words[1]] = count_dict.get(words[1],0) + 1
#print(count_dict)
#Find the most commits
count_list = list()
for (key,value) in list(count_dict.items()):
    count_list.append((value,key))
count_list.sort(reverse = True)
print('The person has the most commits is',count_list[0][1],'who has',count_list[0][0],'commits')


# -*- coding: utf-8 -*-
"""
Created on Mon Jul 26 12:27:48 2021

@author: bjorn

Traininer and Evaluation loops functioning with WandB
"""
import torch
import time
from tqdm import tqdm
import wandb
import numpy as np
from sklearn.metrics import confusion_matrix
from model_utils import get_rri, plot_grad_flow

def train(args, model, optimizer, criterion):
    model.train() # Turn on the train mode
    total_loss = 0.
    batch_nr = 0
    start_time = time.time()
    # src_mask = model.generate_square_subsequent_mask(bptt).to(device)
    # for batch, i in enumerate(range(0, train_data.size(0) - 1, bptt)):
        # data, targets = get_batch(train_data, i)
    for batch in tqdm(train_loader):
        batch_nr += 1
        data, targets = batch
        data = data[:,:,0]
        # plt.plot(data[0,:])
        # plt.show()
        rri = get_rri(data)
        data, rri, targets = torch.tensor(data, dtype=torch.float, device=device), torch.tensor(rri, dtype=torch.float, device=device), torch.tensor(targets, dtype=torch.float, device=device)
        optimizer.zero_grad()
        # if data.size(0) != bptt:
        #     src_mask = model.generate_square_subsequent_mask(data.size(0)).to(device)
        # print(data.shape)
        # print(src_mask.shape)
        # output = model(data) # if n_class>2, and use cross entropy loss
        output = model(data, rri)[:,0] # if n_class==2
        # output = torch.argmax(output, dim=1)
        # output = torch.tensor(output, dtype=torch.float, device=device, requires_grad=True)
        # print('output:', output)
        # print('targets:', targets)
        loss = criterion(output, targets)
        loss.backward()
        # plot_grad_flow(model.named_parameters())
        # torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=2.0 , norm_type=2)
        optimizer.step()

        total_loss += loss.item()
        log_interval = 50
        if batch_nr % log_interval == 0 and batch_nr > 0:
            cur_loss = total_loss / log_interval
            elapsed = time.time() - start_time
            # print('| epoch', epoch,
            #       '| train loss', np.round(cur_loss, 4),
            #       '| ms/batch', np.round(elapsed*1000/log_interval, 3),
            #       '| lr', np.round(scheduler.get_last_lr()[0], 4)
            #       )
            total_loss = 0.
            start_time = time.time()

    # scheduler.step()
    wandb.log({
    "Train Loss": cur_loss})
    return model, cur_loss

def evaluate(args, eval_model, data_source, criterion):
    true_label = np.array([])
    predictions = np.array([])
    loss_list = []
    eval_model.eval() # Turn on the evaluation mode
    tot_val_loss = 0.
    val_batch_nr = 0
    # src_mask = model.generate_square_subsequent_mask(bptt).to(device)
    with torch.no_grad():
        # for i in range(0, data_source.size(0) - 1, bptt):
        #     data, targets = get_batch(data_source, i)
        for batch in data_source:
            data, targets = batch
            data = data[:,:,0]
            rri = get_rri(data)
            data, rri, targets = torch.tensor(data, dtype=torch.float, device=device), torch.tensor(rri, dtype=torch.float, device=device), torch.tensor(targets, dtype=torch.float, device=device)
            # if data.size(0) != bptt:
            #     src_mask = model.generate_square_subsequent_mask(data.size(0)).to(device)
            output = eval_model(data, rri)[:,0]
            # output = torch.argmax(output, dim=1)
            # output = torch.tensor(output, dtype=torch.float, device=device, requires_grad=True)
            loss = criterion(output, targets)
            tot_val_loss += loss.item()
            val_batch_nr+=1
            preds = np.round(torch.sigmoid(output).cpu().detach())
            # print('val preds:', preds)
            # print('val targets:', targets.cpu().detach())
            predictions = np.append(predictions, preds)
            true_label = np.append(true_label, targets.cpu().detach())
    # Get losses and accuracy
    cm = confusion_matrix(true_label, predictions, labels=[0,1])
    acc = np.sum(np.diag(cm))/np.sum(cm)
    TN, FP, FN, TP = cm.ravel()
    # FP = cm.sum(axis=0) - np.diag(cm)
    # FN = cm.sum(axis=1) - np.diag(cm)
    # TP = np.diag(cm)
    # TN = cm.sum() - (FP + FN + TP)
    # Sensitivity, hit rate, recall, or true positive rate
    # TPR = np.round(TP/(TP+FN), 4)
    TPR = TP/(TP+FN)
    # print(TPR.item())
    # print(type(TPR.item()))
    # Specificity or true negative rate
    TNR = TN/(TN+FP)
    # print(TNR)

    wandb.log({
    "Test Accuracy": 100*acc,
    "Test Sensitivity": 100*TPR,
    "Test Specificity": 100*TNR,
    "Test Loss": tot_val_loss/val_batch_nr})
    return tot_val_loss/val_batch_nr, cm, acc, TPR, TNR


"""
    Author: Jiajie Chen
    Date: Apr 24, 2016
"""

import numpy as np
from scipy.optimize import fmin_ncg

class logisticRegression(object):
    def __init__(self, theta=None, lambd=0.0,
                 cost=0.0, max_iter=100, tol=1e-5, solver='newton-cg',
                 verbose=False):
        self.theta = theta
        self.lambd = lambd
        self.cost = cost
        self.max_iter = max_iter
        self.tol = tol
        self.solver=solver
        self.verbose=verbose

    def fit(self, X, y):
        X_c = np.column_stack((np.ones(X.shape[0]),X))
        self.theta = np.zeros(X.shape[1]+1)
        if self.solver == 'newton-cg':
            self.theta = fmin_ncg(self.costFunction, self.theta,
                                  fprime=self.gradient, args=(X_c, y),
                                  maxiter=self.max_iter, avextol=self.tol,
                                  disp=self.verbose)
        else:
            pass
        self.cost = self.costFunction(self.theta, X_c, y)

    def get_prob(self, X):
        X_c = np.column_stack((np.ones(X.shape[0]),X))
        return self.sigmoid(X_c.dot(self.theta))

    def predict(self, X):
        return (self.get_prob(X)>0.5).astype(int)

    def accuracy(self, y_pred, y_true):
        if isinstance(y_pred, list): y_pred=np.array(y_pred)
        if isinstance(y_true, list): y_pred=np.array(y_true)
        return np.mean(y_pred == y_true)

    def sigmoid(self, z):
        """z can be a matrix, vector or scalar"""
        if isinstance(z, list): z=np.array(z)
        return 1/(1+np.exp(-z))

    def costFunction(self, theta, X_c, y):
        n_row = X_c.shape[0]
        J = (1.0/n_row)*(-np.log(self.sigmoid(X_c.dot(theta))).dot(y)
                         -np.log(1-self.sigmoid(X_c.dot(theta))).dot(1-y))\
             + ((1.0*self.lambd)/(2*n_row))*np.sum(theta[1:]**2)
        return J

    def gradient(self, theta, X_c, y):
        n_row, n_col = X_c.shape
        grad = np.empty(theta.shape)
        grad[0] = (1.0/n_row)*X_c[:,0].T.dot(self.sigmoid(X_c.dot(theta))-y)
        grad[1:] = (1.0/n_row)*X_c[:,1:].T.dot(self.sigmoid(X_c.dot(theta))-y)+(float(self.lambd)/n_row)*theta[1:]
        return grad
# end


import gym
from gym import Wrapper
from gym import spaces
import d4rl

import torch
import numpy as np

from src.config import conf

class SkillWrapper(gym.Wrapper):
  """
  gym wrapper that augment the state with random chosen skill index
  """
  def __init__(self, env, n_skills, max_steps=1000, ev=False, sample_freq=None):
    # Call the parent constructor, so we can access self.env later
    super(SkillWrapper, self).__init__(env)

    # skills distribution
    self.n_skills = n_skills
    self.skills_dist = torch.randint
    low, high = env.observation_space.low, env.observation_space.high
    low, high= np.concatenate((low, [0]*n_skills)), np.concatenate((high, [1]*n_skills))
    shape = env.observation_space.shape[0]
    self.observation_space = gym.spaces.Box(low=low, high=high, dtype=np.float32, shape=[shape+n_skills,])
    self.env._max_episode_steps = max_steps
    self.max_steps = max_steps
    self.ev = ev
    self.t = 0
    # if ev:
    #     self.seeds = [0, 10, 1234, 5, 42]
    #     self.i = 0

  def reset(self):
    """
    Reset the environment
    """
    # if self.ev:
    #     self.i = (self.i+1) % 5
    #     self.env.seed(self.seeds[self.i])
    # pick a random skill uniformly
    self.skill = self.skills_dist(low=0, high=self.n_skills, size=(1,)).item()

    obs = self.env.reset()
    onehot = self.one_hot(self.skill)
    obs = np.array(list(obs) + list(onehot)).astype(np.float32)
    return obs

  def step(self, action):
    """
    :param action: ([float] or int) Action taken by the agent
    :return: (np.ndarray, float, bool, dict) observation, reward, is the episode over?, additional informations
    """
    self.t += 1
    # if self.t % 100 == 0:
    #     # print(f"New sampled skill at t={self.t}")
    #     self.skill = self.skills_dist(low=0, high=self.n_skills, size=(1,)).item()
    obs, reward, done, info = self.env.step(action)
    onehot = self.one_hot(self.skill)
    obs = np.array(list(obs.copy()) + list(onehot)).astype(np.float32)
    return obs, reward, done, info

  def one_hot(self, index):
    onehot = np.zeros(self.n_skills)
    onehot[index] = 1
    return onehot

class SkillWrapperVideo(gym.Wrapper):
  """
  gym wrapper that augment the state with random chosen skill index
  """
  def __init__(self, env, n_skills, max_steps=1000):
    super(SkillWrapperVideo, self).__init__(env)

    # skills distribution
    self.n_skills = n_skills
    self.skill = torch.randint(low=0, high=self.n_skills, size=(1,)).item()
    low, high = env.observation_space.low, env.observation_space.high
    low, high= np.concatenate((low, [0]*n_skills)), np.concatenate((high, [1]*n_skills))
    shape = env.observation_space.shape[0]
    self.observation_space = gym.spaces.Box(low=low, high=high, dtype=np.float32, shape=[shape+n_skills,])
    self.env._max_episode_steps = max_steps

  def reset(self):
    """
    Reset the environment
    """
    obs = self.env.reset()
    onehot = self.one_hot(self.skill)
    obs = np.array(list(obs) + list(onehot)).astype(np.float32)
    self.t = 0
    return obs

  def step(self, action):
    """
    :param action: ([float] or int) Action taken by the agent
    :return: (np.ndarray, float, bool, dict) observation, reward, is the episode over?, additional informations
    """
    obs, reward, done, info = self.env.step(action)
    onehot = self.one_hot(self.skill)
    obs = np.array(list(obs.copy()) + list(onehot)).astype(np.float32)
    self.t += 1
    if self.t > self.env._max_episode_steps:
      done = True
    return obs, reward, done, info

  def one_hot(self, index):
    onehot = np.zeros(self.n_skills)
    onehot[index] = 1
    return onehot

class RewardWrapper(gym.Wrapper):
  """
  gym wrapper that augment the state with random chosen skill index
  """
  def __init__(self, env, discriminator, n_skills, parametrization="MLP", batch_size=128):
    # Call the parent constructor, so we can access self.env later
    super(RewardWrapper, self).__init__(env)

    # save the discriminator

    self.discriminator = discriminator
    self.n_skills = n_skills
    self.reward = 0
    self.t = 0
    self.parametrization = parametrization
    self.batch_size = batch_size

  def reset(self):
    self.t = 0
    return self.env.reset()

  def step(self, action):
    """
    :param action: ([float] or int) Action taken by the agent
    :return: (np.ndarray, float, bool, dict) observation, reward, is the episode over?, additional informations
    """
    obs, reward, done, info = self.env.step(action)

    env_obs, skill = self.split_obs(obs)
    obs_t = torch.FloatTensor(env_obs, device=conf.device)
    self.t += 1
    if self.parametrization in ["MLP", "Linear"]:
        self.discriminator.eval()
        # print(f"hereeee in timestep: {self.t}")
        reward = (torch.log_softmax(self.discriminator(obs_t).detach(), dim=-1)[int(skill)] - np.log(1/self.n_skills)).item()
    elif self.parametrization in ["Separable", "Concat"]:
        with torch.no_grad():
            self.discriminator.eval()
            skills_onehot = self.one_hot(skill)
            reward = self.discriminator(obs_t.unsqueeze(0), skills_onehot.unsqueeze(0)).mean().item()
        # print(f"reward in the skill wrapper: {reward}")
    if self.t >= self.env.max_steps:
        done = True
    else:
        done = False
    return obs, reward, done, info

  def split_obs(self, obs):
    env_obs = obs[: -self.n_skills]
    skill, = np.where( obs[-self.n_skills: ] == 1 )
    return env_obs, skill[0]

  def one_hot(self, skill):
    onehot = torch.zeros(self.n_skills, device=conf.device)
    onehot[skill] = 1
    return onehot

class SkillWrapperFinetune(gym.Wrapper):
  """
  gym wrapper that augment the state with random chosen skill index
  """
  def __init__(self, env, n_skills, skill, seed=None, max_steps=1000, l=None):
    super(SkillWrapperFinetune, self).__init__(env)
    # skills distribution
    # print("Hello I am here")
    self.n_skills = n_skills
    self.env = env
    self.skill = skill
    low, high = env.observation_space.low, env.observation_space.high
    low, high= np.concatenate((low, [0]*n_skills)), np.concatenate((high, [1]*n_skills))
    shape = env.observation_space.shape[0]
    self.observation_space = gym.spaces.Box(low=low, high=high, dtype=np.float32, shape=[shape+n_skills,])
    self.env._max_episode_steps = max_steps
    self.env.seed(seed)
    self.l = l
    # seeds for the 5 evaluation runs

  def reset(self):
    """
    Reset the environment
    """
    obs = self.env.reset()
    self.t = 0
    # print("I am here")
    onehot = self.one_hot(self.skill)
    obs = np.array(list(obs) + list(onehot)).astype(np.float32)
    # self.total = 0
    return obs

  def step(self, action):
    """
    :param action: ([float] or int) Action taken by the agent
    :return: (np.ndarray, float, bool, dict) observation, reward, is the episode over?, additional informations
    """
    self.t += 1
    obs, reward, done, info = self.env.step(action)
    # self.total += reward
    onehot = self.one_hot(self.skill)
    obs = np.array(list(obs.copy()) + list(onehot)).astype(np.float32)
    # print(self.l)
    # print(f"action: {action}")
    # print(f"obs: {obs}")
    # print(f"reward: {reward}")
    # print(f"total reward: {self.total}")
    # print(f"total steps: {self.t}")
    # input()
    return obs, reward, done, info

  def one_hot(self, index):
    onehot = np.zeros(self.n_skills)
    onehot[index] = 1
    return onehot

class TimestepsWrapper(gym.Wrapper):
  """
  gym wrapper that augment the state with random chosen skill index
  """
  def __init__(self, env, max_steps=1000):
    super(TimestepsWrapper, self).__init__(env)

    # skills distribution
    self.env = env
    self.max_steps = 1000
    self.t = 0

  def reset(self):
    """
    Reset the environment
    """
    self.t = 0
    return self.env.reset()

  def step(self, action):
    """
    :param action: ([float] or int) Action taken by the agent
    :return: (np.ndarray, float, bool, dict) observation, reward, is the episode over?, additional informations
    """
    obs, reward, done, info = self.env.step(action)
    self.t += 1
    if self.t >= self.env._max_episode_steps:
      done = True
    else:
      done = False
    # print(f"Timestep:{self.t} and done: {done}")
    return obs, reward, done, info

class EvalWrapper(gym.Wrapper):
  """
  gym wrapper that augment the state with random chosen skill index
  """
  def __init__(self, env, max_steps=1000):
    super(EvalWrapper, self).__init__(env)

    # skills distribution
    self.env = env
    self.max_steps = 1000
    self.t = 0

  def reset(self):
    """
    Reset the environment
    """
    self.t = 0
    return self.env.reset()

  def step(self, action):
    """
    :param action: ([float] or int) Action taken by the agent
    :return: (np.ndarray, float, bool, dict) observation, reward, is the episode over?, additional informations
    """
    obs, reward, done, info = self.env.step(action)
    self.t += 1
    if self.t >= self.env._max_episode_steps:
      done = True
    else:
      done = False
    # print(f"Timestep:{self.t} and done: {done}")
    return obs, reward, done, info

class RGBArrayAsObservationWrapper(Wrapper):
    """
    Use env.render(rgb_array) as observation
    rather than the observation environment provides
    """
    def __init__(self, env, num_skills, n_stack):
        '''
        env: Gym environment object
        num_skills: number of skill in pretraing
        n_stack: size of the frame stack
        '''
        self.vector_size = num_skills
        self.env = env
        self.num_skills = num_skills
        self.n_stack = n_stack

        dummy_obs = env.render("rgb_array")
        self.observation_space_img  = spaces.Box(low=0, high=255, shape=dummy_obs.repeat(n_stack, axis=0).shape, dtype=dummy_obs.dtype)
        self.observation_space_vec  = spaces.Box(low=0, high=1, shape=(num_skills, ), dtype=np.float32)
        self.observation_space = spaces.Dict(
            spaces={
                "img": self.observation_space_img,
                "vec": self.observation_space_vec
            }
        )

        self.action_space = self.env.action_space

    def reset(self, **kwargs):
        skill = np.random.randint(0,self.num_skills )
        self.env.reset()
        self.skill_vec = self.onehot(skill)
        img = self.env.render("rgb_array")
        self.frames_buffer = np.zeros((self.n_stack, *img.shape ))
        obs = {
            "img": self.update_frames_buffer(img),
            "vec": self.skill_vec}
        return obs

    def step(self, action):
        obs, reward, done, info = self.env.step(action)
        obs = {
            "img":self.update_frames_buffer(self.env.render("rgb_array")),
            "vec": self.skill_vec}
        return obs, reward, done, info

    def onehot(self, skill):
      skill_vec = np.zeros((self.num_skills))
      skill_vec[skill] = 1
      return skill_vec

    def update_frames_buffer(self, obs):
      self.frames_buffer[:-1] = self.frames_buffer[1:]
      self.frames_buffer[-1] = obs
      return self.frames_buffer


import unittest

import numpy
import six

import chainer
from chainer import cuda
from chainer import gradient_check
from chainer import testing
from chainer.testing import attr
from chainer.testing import condition

class TestAccuracy(unittest.TestCase):

    def setUp(self):
        self.x = numpy.random.uniform(-1, 1, (10, 3)).astype(numpy.float32)
        self.t = numpy.random.randint(3, size=(10,)).astype(numpy.int32)

    def check_forward(self, x_data, t_data):
        x = chainer.Variable(x_data)
        t = chainer.Variable(t_data)
        y = chainer.functions.accuracy(x, t)
        self.assertEqual(y.data.dtype, numpy.float32)
        self.assertEqual((), y.data.shape)

        count = 0
        for i in six.moves.range(self.t.size):
            pred = self.x[i].argmax()
            if pred == self.t[i]:
                count += 1

        expected = float(count) / self.t.size
        gradient_check.assert_allclose(expected, cuda.to_cpu(y.data))

    @condition.retry(3)
    def test_forward_cpu(self):
        self.check_forward(self.x, self.t)

    @attr.gpu
    @condition.retry(3)
    def test_forward_gpu(self):
        self.check_forward(cuda.to_gpu(self.x), cuda.to_gpu(self.t))

testing.run_module(__name__, __file__)


import asyncio
from aioauth_client import YandexClient
import settings
from datetime import datetime
import ujson

yandex = YandexClient(
    client_id=settings.client_id,
    client_secret=settings.client_secret,
    access_token=settings.access_token
)

@asyncio.coroutine
def get_counters():
    current_date = datetime.now().strftime('%Y%m%d')
    stat_url = 'https://api-metrika.yandex.ru/stat/traffic/summary.json?id={}'\
        '&date1={}'
    res = yield from yandex.request(
        'GET', 'https://api-metrika.yandex.ru/counters.json')
    data = yield from res.read()
    data = ujson.loads(data)
    counters = []
    for counter in data.get('counters', []):
        cid = counter['id']
        res = yield from yandex.request('GET', stat_url.format(cid,
                                                               current_date))
        stat = yield from res.read()
        stat = ujson.loads(stat)
        if stat['data']:
            counters.append({'name': counter['name'],
                             'visits': stat['data'][0]['visits']})
    return counters


import keras
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Input, Dense, Activation
from keras.layers import Reshape, Lambda
from keras.models import Model, load_model
from keras.layers import Bidirectional
from keras.layers import LSTM
from keras.optimizers import Adam
from generate_data import TextImageGenerator

def ctc_lambda_func(args):
    y_pred, labels, input_length, label_length = args
    # the 2 is critical here since the first couple outputs of the RNN tend to be garbage:
    y_pred = y_pred[:, 2:, :]
    return keras.backend.ctc_batch_cost(labels, y_pred, input_length, label_length)

def train(img_w, load=False):
    # Input Parameters
    img_h = 64

    # Network parameters
    conv_filters = 16
    kernel_size = (3, 3)
    pool_size = 2
    time_dense_size = 32
    rnn_size = 512

    if keras.backend.image_data_format() == 'channels_first':
        input_shape = (1, img_w, img_h)
    else:
        input_shape = (img_w, img_h, 1)

    batch_size = 32
    downsample_factor = pool_size ** 2
    tiger_train = TextImageGenerator('./train/', img_w, img_h, batch_size, downsample_factor)
    tiger_train.build_data()
    tiger_test = TextImageGenerator('./test/', img_w, img_h, batch_size, downsample_factor)
    tiger_test.build_data()

    act = 'relu'
    input_data = Input(name='the_input', shape=input_shape, dtype='float32')
    inner = Conv2D(conv_filters, kernel_size, padding='same',
                   activation=act, kernel_initializer='he_normal',
                   name='conv1')(input_data)
    inner = MaxPooling2D(pool_size=(pool_size, pool_size), name='max1')(inner)
    inner = Conv2D(conv_filters, kernel_size, padding='same',
                   activation=act, kernel_initializer='he_normal',
                   name='conv2')(inner)
    inner = MaxPooling2D(pool_size=(pool_size, pool_size), name='max2')(inner)

    conv_to_rnn_dims = (img_w // (pool_size ** 2), (img_h // (pool_size ** 2)) * conv_filters)
    inner = Reshape(target_shape=conv_to_rnn_dims, name='reshape')(inner)

    # cuts down input size going into RNN:
    inner = Dense(time_dense_size, activation=act, name='dense1')(inner)

    gru_1 = LSTM(rnn_size, return_sequences=True, name='gru1')
    gru_1b = LSTM(rnn_size, return_sequences=True, go_backwards=True, name='gru1_b')
    gru1_merged = Bidirectional(gru_1, backward_layer=gru_1b)(inner)
    gru_2 = LSTM(rnn_size, return_sequences=True, kernel_initializer='he_normal', name='gru2')
    gru_2b = LSTM(rnn_size, return_sequences=True, go_backwards=True, kernel_initializer='he_normal', name='gru2_b')
    gru2_merged = Bidirectional(gru_2, backward_layer=gru_2b)(gru1_merged)
    # transforms RNN output to character activations:
    inner = Dense(tiger_train.get_output_size(), kernel_initializer='he_normal',
                  name='dense2')(gru2_merged)
    y_pred = Activation('softmax', name='softmax')(inner)
    Model(inputs=input_data, outputs=y_pred).summary()

    labels = Input(name='the_labels', shape=[tiger_train.max_text_len], dtype='float32')
    input_length = Input(name='input_length', shape=[1], dtype='int64')
    label_length = Input(name='label_length', shape=[1], dtype='int64')

    # Keras doesn't currently support loss funcs with extra parameters
    # so CTC loss is implemented in a lambda layer
    loss_out = Lambda(ctc_lambda_func, output_shape=(1,), name='ctc')([y_pred, labels, input_length, label_length])

    sgd = Adam()
    if load:
        model = load_model('./tmp_model.h5', compile=False)
    else:
        model = Model(inputs=[input_data, labels, input_length, label_length], outputs=loss_out)

    # the loss calc occurs elsewhere, so use a dummy lambda func for the loss
    model.compile(loss={'ctc': lambda y_true, y_pred: y_pred}, optimizer=sgd)
    model.summary()
    if not load:
        # captures output of softmax so we can decode the output during visualization
        #test_func = tf.keras.backend.function([input_data], [y_pred])

        model.fit_generator(generator=tiger_train.next_batch(),
                        steps_per_epoch=tiger_train.n,
                        epochs=1,
                        validation_data=tiger_test.next_batch(),
                        validation_steps=tiger_test.n)

    return model

model = train(128, load=False)
extracted_layers = model.layers[:-4]
new_model = keras.Sequential(extracted_layers)
new_model.save('ocr_model.h5', include_optimizer=False)


import datetime, threading, time

class Car():

    def __init__(self, type):
        self.type = type
        self.speed = 0
        self.acceleration = 0
        self.gear_num = 0
        self.distance = 0
        self.start_time = time.time()
        if self.type == "manual":
            self.manual_gear_up_logic()

    def accelerate(self, magnitude):
        if magnitude > 10:
            return Exception("Accelerate only between 0-10")
        else:
            if self.type == "automatic":
                self.acceleration = magnitude
                self.automatic_gear_logic()
                self.speed = magnitude * 10
            else:
                self.acceleration = magnitude
                self.speed = magnitude * 10
                self.manual_gear_check()

    def automatic_gear_logic(self):
        if self.acceleration <= 2:
            self.gear(1)
        elif self.acceleration <= 4:
            self.gear(2)
        elif self.acceleration <= 6:
            self.gear(3)
        elif self.acceleration <= 8:
            self.gear(4)
        elif self.acceleration <= 10:
            self.gear(5)

    def manual_gear_up_logic(self):
        input_gear = input("enter gear 1-5: ")
        if int(input_gear) > 5:
            return Exception("Gears only till 5th")
        self.gear_num = int(input_gear)
        input_accelerate = input("Accelerate between 0-10: ")
        self.accelerate(int(input_accelerate))

    def manual_gear_down_logic(self):
        gear_down = input("Reduce the gear to: ")
        self.gear(int(gear_down))

    def gear(self, gear):
        if gear >= 5:
            return Exception(f"no {gear}th gear found")
        self.gear_num = gear

    def manual_gear_check(self):
        if self.gear_num*2 != self.acceleration:
            print("Grr gRRR grrrRRR")
            print("car not in correct gear and acceleration")
            self.manual_gear_up_logic()

    def breaks(self, magnitude):
        if magnitude > 10:
            return Exception("Break only between 0-10")
        else:
            if magnitude > self.acceleration:
                magnitude = self.acceleration
                if self.type == "manual":
                    self.manual_gear_down_logic()
            else:
                magnitude = self.acceleration - magnitude
                if self.type == "manual":
                    self.manual_gear_down_logic()
            self.accelerate(magnitude)

    def dist(self):
        now_time = time.time()
        time_elapsed = now_time - self.start_time
        self.distance = self.speed * time_elapsed
        threading.Timer(5, self.dist).start()

x = Car('manual')
x.dist()
while True:
    print(f"speed is: {x.speed}")
    print(f"gear is: {x.gear_num}")
    print(x.distance)
    y = input("Accelerate, Break or cruise (A/B/C): ")
    if x.type == 'manual':
        if y == "a":
            x.manual_gear_up_logic()

        elif y == "b":
            magnitude = input("break magnitude: ")
            x.breaks(int(magnitude))


import time

from elasticsearch_dsl import connections
from protobuf_to_dict import dict_to_protobuf
from protobufs.services.post import containers_pb2 as post_containers
from protobufs.services.profile import containers_pb2 as profile_containers
from protobufs.services.search.containers import entity_pb2
from protobufs.services.search.containers import search_pb2
from protobufs.services.team import containers_pb2 as team_containers
from ..stores.es import types
import service.control
import yaml

from services.test import mocks

from .base import ESTestCase

_fixtures = None
_executed = False

class Test(ESTestCase):

    def setUp(self):
        super(Test, self).setUp()
        organization_id = _fixtures['profiles'][0]['organization_id']
        self.organization = mocks.mock_organization(id=organization_id)
        self.profile = mocks.mock_profile(organization_id=self.organization.id)
        token = mocks.mock_token(profile_id=self.profile.id, organization_id=self.organization.id)
        self.client = service.control.Client('search', token=token)
        self.mock.instance.dont_mock_service('search')
        global _executed
        if not _executed:
            self._setup_fixtures(_fixtures)
            _executed = True

    @classmethod
    def setUpClass(cls):
        super(Test, cls).setUpClass()
        with open('search/fixtures/acme.yml') as read_file:
            global _fixtures
            _fixtures = yaml.load(read_file)

    def _update_entities(self, entity_type, containers):
        self.client.call_action(
            'update_entities',
            type=entity_type,
            ids=[c.id for c in containers],
        )
        # give the documents time to index
        time.sleep(1)

    def _setup_profile_fixtures(self, profile_fixtures):
        if not profile_fixtures:
            return

        containers = [dict_to_protobuf(f, profile_containers.ProfileV1) for f in profile_fixtures]
        self.mock.instance.register_mock_object(
            service='profile',
            action='get_profiles',
            return_object=containers,
            return_object_path='profiles',
            mock_regex_lookup='profile:get_profiles:.*',
        )
        self._update_entities(entity_pb2.PROFILE, containers)

    def _setup_team_fixtures(self, team_fixtures):
        if not team_fixtures:
            return

        containers = [dict_to_protobuf(f, team_containers.TeamV1) for f in team_fixtures]
        self.mock.instance.register_mock_object(
            service='team',
            action='get_teams',
            return_object=containers,
            return_object_path='teams',
            mock_regex_lookup='team:get_teams:.*',
        )
        self._update_entities(entity_pb2.TEAM, containers)

    def _setup_post_fixtures(self, post_fixtures):
        if not post_fixtures:
            return

        containers = [dict_to_protobuf(f, post_containers.PostV1) for f in post_fixtures]
        self.mock.instance.register_mock_object(
            service='post',
            action='get_posts',
            return_object=containers,
            return_object_path='posts',
            mock_regex_lookup='post:get_posts:.*',
        )
        self._update_entities(entity_pb2.POST, containers)

    def _setup_fixtures(self, fixtures):
        es = connections.connections.get_connection()
        es.indices.delete('*')
        self.client.call_action('create_index')
        self._setup_profile_fixtures(fixtures.get('profiles', []))
        self._setup_team_fixtures(fixtures.get('teams', []))
        self._setup_post_fixtures(fixtures.get('posts', []))

    def verify_top_results(
            self,
            result_object_type,
            fields,
            results,
            top_results=3,
            query=None,
            should_be_present=True,
        ):
        present = False
        for result in results[:top_results]:
            result_object = getattr(result, result_object_type)
            all_match = False
            for field, expected_value in fields.iteritems():
                value = getattr(result_object, field)
                if callable(expected_value) and expected_value(value):
                    all_match = True
                elif value == expected_value:
                    all_match = True
            if all_match:
                present = True
                break

        if should_be_present:
            message = 'Expected a match in the top %s results for: %s%s' % (
                top_results,
                fields,
                ' (query: %s)' % (query,) if query else '',
            )
            self.assertTrue(present, message)
        else:
            message = 'Didn\'t expect a match in the top %s results for: %s%s' % (
                top_results,
                fields,
                ' (query: %s)' % (query,) if query else '',
            )
            self.assertFalse(present, message)

    def test_search_query_required(self):
        with self.assertFieldError('query', 'MISSING'):
            self.client.call_action('search_v2')

    #def test_search_profile_email(self):
        #response = self.client.call_action('search_v2', query='meghan@acme.com')
        #results = response.result.results
        ## should only have 1 result since this is an exact match
        #self.assertEqual(len(results), 1)
        #top_hit = results[0]
        #profile = top_hit.profile
        #self.assertEqual(profile.email, 'meghan@acme.com')
        #self.assertEqual(profile.display_title, 'Customer Service Agent (Customer Support)')
        #self.assertEqual(profile.full_name, 'Meghan Ward')

    def test_search_profile_partial_full_name(self):
        response = self.client.call_action('search_v2', query='meg')
        self.verify_top_results(
            'profile',
            {'email': 'meghan@acme.com', 'full_name': 'Meghan Ward'},
            response.result.results,
        )

    def test_search_profile_first_name(self):
        response = self.client.call_action('search_v2', query='Meghan')
        self.verify_top_results(
            'profile',
            {'email': 'meghan@acme.com'},
            response.result.results,
        )

    def test_search_profile_last_name(self):
        response = self.client.call_action('search_v2', query='Ward')
        self.verify_top_results(
            'profile',
            {'email': 'meghan@acme.com'},
            response.result.results,
        )

    def test_search_profile_name_title(self):
        response = self.client.call_action('search_v2', query='Meg Customer Service Agent')
        self.verify_top_results(
            'profile',
            {'email': 'meghan@acme.com'},
            response.result.results,
            top_results=1,
        )

    def test_search_profile_name_department(self):
        response = self.client.call_action('search_v2', query='Meg in Customer Support')
        self.verify_top_results(
            'profile',
            {'email': 'meghan@acme.com'},
            response.result.results,
        )

    def test_search_profile_nick_name_last_name(self):
        response = self.client.call_action('search_v2', query='Meg Ward')
        self.verify_top_results(
            'profile',
            {'email': 'meghan@acme.com'},
            response.result.results,
            top_results=1,
        )

    def test_search_team_name(self):
        response = self.client.call_action('search_v2', query='Customer Support')
        self.verify_top_results(
            'team',
            {'name': 'Customer Support'},
            response.result.results,
            top_results=1,
        )

    def test_search_team_partial_name(self):
        response = self.client.call_action('search_v2', query='Customer')
        self.verify_top_results(
            'team',
            {'name': 'Customer Support'},
            response.result.results,
            top_results=1,
        )
        response = self.client.call_action('search_v2', query='Support')
        self.verify_top_results(
            'team',
            {'name': 'Customer Support'},
            response.result.results,
        )
        response = self.client.call_action('search_v2', query='Cust')
        self.verify_top_results(
            'team',
            {'name': 'Customer Support'},
            response.result.results,
        )

    def test_search_post_phising_email(self):
        _verify = lambda response, query: self.verify_top_results(
            'post',
            {'title': lambda y: 'phishing' in y},
            response.result.results,
            top_results=1,
            query=query,
        )

        queries = [
            'phishing',
            'phishing email',
            'suspicious email',
            'suspicious call',
        ]
        for query in queries:
            response = self.client.call_action('search_v2', query=query)
            _verify(response, query)

    def test_search_post_travel_request(self):
        _verify = lambda response, query: self.verify_top_results(
            'post',
            {'title': lambda y: 'go somewhere for work' in y},
            response.result.results,
            top_results=1,
            query=query,
        )

        queries = [
            'travel request',
            'booking travel',
            'booking flight',
            'booking hotel',
            'travelling for work',
            'going to a conference',
        ]
        for query in queries:
            response = self.client.call_action('search_v2', query=query)
            _verify(response, query)

    def test_search_post_arbiter_how_to(self):
        _verify = lambda response, query: self.verify_top_results(
            'post',
            {'title': lambda y: 'What is Arbiter?'},
            response.result.results,
            query=query,
        )

        queries = [
            'Arbiter',
            'website testing framework',
        ]
        for query in queries:
            response = self.client.call_action('search_v2', query=query)
            _verify(response, query)

    def test_search_category_profiles(self):
        # verify a normal search returns a team
        response = self.client.call_action('search_v2', query='Customer Support')
        self.verify_top_results(
            'team',
            {'name': 'Customer Support'},
            response.result.results,
            top_results=1,
        )

        response = self.client.call_action(
            'search_v2',
            query='Customer Support',
            category=search_pb2.PROFILES,
        )
        self.verify_top_results(
            'profile',
            {'display_title': lambda x: 'Customer Support' in x},
            response.result.results,
            top_results=1,
        )

    def test_search_category_teams(self):
        # verify a normal search returns a person
        response = self.client.call_action('search_v2', query='Customer Support')
        self.verify_top_results(
            'profile',
            {'display_title': lambda x: 'Customer Support' in x},
            response.result.results,
            top_results=10,
        )

        response = self.client.call_action(
            'search_v2',
            query='Customer Support',
            category=search_pb2.TEAMS,
        )
        self.verify_top_results(
            'profile',
            {'display_title': lambda x: 'Customer Support' in x},
            response.result.results,
            top_results=10,
            should_be_present=False,
        )

    def test_search_category_posts(self):
        # verify a normal search returns a person
        response = self.client.call_action('search_v2', query='Taylor')
        self.verify_top_results(
            'profile',
            {'full_name': lambda x: 'Taylor' in x},
            response.result.results,
        )

        response = self.client.call_action(
            'search_v2',
            query='Taylor',
            category=search_pb2.POSTS,
        )
        self.verify_top_results(
            'profile',
            {'full_name': lambda x: 'Taylor' in x},
            response.result.results,
            top_results=10,
            should_be_present=False,
        )

    def test_search_hashtags(self):
        response = self.client.call_action('search_v2', query='#engineering')
        self.verify_top_results(
            'post',
            {'title': 'Hashtag'},
            response.result.results,
        )

    def test_search_partial_email_shouldnt_rank_higher_than_partial_name(self):
        """Several partial matches on a name should rank higher than on an email.

        Given the following two profiles:
            1:
                name: Marco Zappacosta
                email: marco@acme.com
            2:
                name: Marco de Almeida
                email: mfa@acme.com

        Searching for "Marco Almeida" should return profile 2 as the top result.
        """
        response = self.client.call_action(
            'search_v2',
            query='marco almeida',
            category=search_pb2.PROFILES,
        )
        self.verify_top_results(
            'profile',
            {'email': 'mfa@acme.com'},
            response.result.results,
            top_results=1,
        )

    #def test_search_exact_email_match(self):
        #response = self.client.call_action('search_v2', query='marco@acme.com')
        #self.verify_top_results(
            #'profile',
            #{'email': 'marco@acme.com'},
            #response.result.results,
            #top_results=1,
        #)

    def test_search_raw_content_match_higher_than_title_match(self):
        response = self.client.call_action('search_v2', query='video conferencing')
        hit = response.result.results[0]
        self.assertIn('video conferencing', hit.highlight['content'])

    def test_search_team_name_highlighting_partial(self):
        response = self.client.call_action(
            'search_v2',
            query='Dev',
            category=search_pb2.TEAMS,
        )
        hit = response.result.results[0]
        self.assertTrue(hit.highlight['name'].startswith('DevOps'))

    def test_search_team_name_highlighting(self):
        response = self.client.call_action(
            'search_v2',
            query='Customer Support',
            category=search_pb2.TEAMS,
        )
        hit = response.result.results[0]
        self.assertEqual(hit.highlight['name'], 'Customer Support')

    def test_search_team_description_highlighting(self):
        response = self.client.call_action(
            'search_v2',
            query='site up',
            category=search_pb2.TEAMS,
        )
        hit = response.result.results[0]
        self.assertIn('site up', hit.highlight['description'])

    def test_search_profile_full_name_highlighting(self):
        response = self.client.call_action('search_v2', query='Meg')
        hit = response.result.results[0]
        self.assertTrue(hit.highlight['full_name'].startswith('Meghan'))
        response = self.client.call_action('search_v2', query='Meghan')
        hit = response.result.results[0]
        self.assertTrue(hit.highlight['full_name'].startswith('Meghan'))

        response = self.client.call_action('search_v2', query='Ward')
        hit = response.result.results[0]
        self.assertTrue(hit.highlight['full_name'].endswith('Ward'))

        response = self.client.call_action('search_v2', query='Meghan Ward')
        hit = response.result.results[0]
        self.assertEqual(hit.highlight['full_name'], 'Meghan Ward')

    def test_search_profile_display_title_highlighting(self):
        response = self.client.call_action(
            'search_v2',
            query='Sr. Account',
            category=search_pb2.PROFILES,
        )
        hit = response.result.results[0]
        self.assertTrue(
            hit.highlight['display_title'].startswith(
                'Sr. Account Manager',
            )
        )

        response = self.client.call_action(
            'search_v2',
            query='Manager',
            category=search_pb2.PROFILES,
        )
        hit = response.result.results[0]
        self.assertIn('Manager', hit.highlight['display_title'])

    def test_search_post_title_highlighting(self):
        response = self.client.call_action(
            'search_v2',
            query='Arbit',
            category=search_pb2.POSTS,
        )
        hit = response.result.results[0]
        self.assertIn('Arbiter', hit.highlight['title'])

    def test_search_post_title_highlighting_return_full_fragment(self):
        response = self.client.call_action(
            'search_v2',
            query='expense',
            category=search_pb2.POSTS,
        )
        hit = response.result.results[0]
        expected_title = (
            'How do I fill out an expense report with some really really long'
            ' title to make sure that we return the full field?'
        )
        self.assertIn(expected_title, hit.highlight['title'])

    def test_search_post_content_highlighting(self):
        response = self.client.call_action(
            'search_v2',
            query='Marco Zappacosta',
            category=search_pb2.POSTS,
        )
        hit = response.result.results[0]
        self.assertIn('Marco Zappacosta', hit.highlight['content'])
        self.assertEqual(len(hit.highlight['content']), 174)

    def test_search_result_has_tracking_details(self):
        response = self.client.call_action('search_v2', query='Meghan Ward')
        hit = response.result.results[0]
        profile = hit.profile
        tracking_details = hit.tracking_details
        self.assertEqual(tracking_details.document_id, profile.id)
        self.assertEqual(tracking_details.document_type, types.ProfileV1._doc_type.name)

    def test_search_post_does_not_have_content(self):
        response = self.client.call_action(
            'search_v2',
            query='Arbiter',
            category=search_pb2.POSTS,
        )
        self.assertFalse(any([result.post.content for result in response.result.results]))

    def test_search_does_not_index_html_content(self):
        response = self.client.call_action(
            'search_v2',
            query='div strong',
            category=search_pb2.POSTS,
        )
        self.assertFalse(response.result.results)
        response = self.client.call_action(
            'search_v2',
            query='some bold section',
            category=search_pb2.POSTS,
        )
        self.assertTrue(response.result.results)
        self.assertIn(
            'Some Bold Section',
            response.result.results[0].highlight['content'],
        )


wordList = []

key_word = {'char': 101, 'int': 102, 'double': 104, 'break': 105, 'return': 106,
            'void': 107, 'continue': 108, 'if': 109, 'main': 110, 'float': 111, 'else': 112, 'while': 113, 'for': 114,
            'printf': 115, 'scanf': 116}
operator = {'!': 205, '*': 206, '/': 207, '%': 208, '+': 209, '-': 210, '<': 211, '>': 212, '&': 213, '|': 214,
            '=': 215, '.': 216}
delima = {'{': 301, '}': 302, ';': 303, ',': 304, '(': 305, ')': 306}

def readFile(path):
    src = []
    with open(path, 'r', encoding='UTF-8') as f:
        src = f.read().splitlines()
        # for i in f.readlines():
        #     if i != '\n':
        #         src.append(i)
    return src

def removeNote(src):
    for i in src:
        for j in range(len(i)):
            if i[j] == '/':
                if i[j + 1] == '/' or i[j + 1] == '*':
                    src[src.index(i)] = i[:j]
                    break
            break
    for i in src:
        if not i:
            del src[src.index(i)]
    return src

def combineProg(src):
    strSrc = ' '.join(str(i) for i in src)
    return strSrc

def addWord(word, type):
    global wordList
    if type == 'operation':
        wordList.append(operator[word])
        wordList.append(word)
        # w = '(' + operator[word] + ',\"' + word + '\"' + ')\n'
        # wordList = wordList + w
    elif type == 'keyWord':
        wordList.append(key_word[word])
        wordList.append(word)
    elif type == 'identifier':
        wordList.append(700)
        wordList.append(word)
    elif type == 'integer':
        wordList.append(400)
        wordList.append(word)
    elif type == 'delima':
        wordList.append(delima[word])
        wordList.append(word)

def lexAnalyse(str):
    i = 0
    j = 0
    exitFlag = 0
    while exitFlag == 0:
        if str[i] == ' ':
            i += 1
            j = i

        if str[j].isalpha() or str[j] == '_':
            # 识别保留字、标识符
            for j in range(i, len(str)):
                if str[j].isalpha() or str[j] == '_':
                    if j >= len(str) - 1:
                        word = str[i:j + 1]
                        if word in key_word:
                            addWord(word, 'keyWord')
                        else:
                            addWord(word, 'identifier')
                        exitFlag = 1
                        i = j + 1
                        j = i
                        break
                    continue
                elif j >= len(str):
                    word = str[i:j + 1]
                    if word in key_word:
                        addWord(word, 'keyWord')
                    else:
                        addWord(word, 'identifier')
                    exitFlag = 1
                    i = j + 1
                    j = i
                    break
                else:
                    word = str[i:j]
                    if word in key_word:
                        addWord(word, 'keyWord')
                    else:
                        addWord(word, 'identifier')
                    i = j
                    break
                    # 完成一个单词的识别 跳出for循环
            if exitFlag == 1:
                i = j
                break

        elif str[i].isdigit():
            # 识别整数
            for j in range(i, len(str)):
                if str[j].isdigit():
                    # 只能判断整数
                    if j >= len(str) - 1:
                        word = str[i:j + 1]
                        addWord(word, 'integer')
                        exitFlag = 1
                        i = j + 1
                        j = i
                        break
                    continue
                else:
                    word = str[i:j]
                    addWord(word, 'integer')
                    i = j
                    break
                    # 完成一个数字的识别 跳出for循环
            if exitFlag == 1:
                i = j
                break

        # 识别界符delima
        elif str[i] in delima:
            addWord(str[i], 'delima')
            i += 1
            j = i
            if i >= len(str):
                exitFlag = 1
                break

        # 识别运算符
        elif str[i] in operator:
            addWord(str[i], 'operation')
            i += 1
            j = i
            if i >= len(str):
                exitFlag = 1
                break

        if exitFlag == 1:
            break

if __name__ == '__main__':
    srcS = combineProg(removeNote(readFile('testProgram.txt')))
    print(srcS)
    lexAnalyse(srcS)
    print(wordList)
    # todo: 程序中出现转义字符无法跳出循环


'''
Mob class.
Classes Turret and Mob inherits from class Entity
'''

# ------ Importations ------

import pygame
import math
from isometric import IsoSprite, isoutils
import constants as cst
from . import misc,entity

# ------ Mob Class ------

class Mob(entity.Entity):
    ''' Classe de base des monstres traversant le niveau '''

    def __init__(self, path_to_image, tile_pos=None):
        entity.Entity.__init__(self, path_to_image, tile_pos)
        self.spritesheet = self.image
        self.anim_key = 0  # 0, 1 or 2 (x on spritesheet)
        self.state = 0  # 0 front, 1 left, 2 right, 3 back (y on spritesheet)
        self.anim_speed = 5  # sprite anims every anim_speed frames
        self.anim_counter = 0  # increments every frame
        self.size = 32  # pixels

        # v force rect to be of size self.size, not spritesheet's size !
        new_iso_rect = pygame.Rect((0, 0), (self.size, self.size))
        new_iso_rect.center = self.iso_pos
        self.set_iso_rect(new_iso_rect)
        new_rect = pygame.Rect((0, 0), isoutils.iso_to_cart(self.size, self.size))
        new_rect.center = self.pos
        self.set_rect(new_rect)
        # ^
        self.image = None
        self.update_image()

        # game settings
        self.speed = 3  # chasing speed
        self.is_flying = False
        self.hp = 0

    ## ------ Graphical functions ------

    def update_image(self):
        mask_rect = pygame.Rect(self.anim_key*self.size, self.state*self.size, self.size, self.size)
        self.image = self.spritesheet.subsurface(mask_rect)

    def update(self):
        super().update()
        # update the animation
        self.anim_counter += 1
        if self.anim_counter == self.anim_speed:
            self.anim_counter = 0
            self.anim_key = (self.anim_key + 1) % 3
            self.update_image()

    def display(self, screen):
        '''
        display(self, screen) :
            displays the Sprite onto the screen.
        '''
        super().display(screen)
        if cst.DEBUG:
            pygame.draw.rect(screen, pygame.Color("blue"), self.rect, 2)
            pygame.draw.rect(screen, pygame.Color("red"), self.iso_rect, 2)

    ## ------ Behavior and AI functions ------

    def find_path(self, obstacles, target):
        '''
        find_path(self,obstacles) -> path list
            implementation of the A* algorithm. The heuristic used is the euclidean distance.
            return a list of tiles to walk on in order to get to the target avoiding obstacles. The path is the shortest possible path
            if no path is available, returns None.

            obstacles = dict where dict[(i,j)] is True if and only if there is an obstacle on case (i,j)
            target = the coordinate tupple of the case to reach
        '''

        # Data structures
        get_default_dict = lambda default_value: dict(((i, j), default_value) for i in range(cst.MAP_WIDTH) for j in range(cst.MAP_WIDTH))
        passage = get_default_dict(None)
        distance = get_default_dict(float('inf'))
        seen = get_default_dict(False)
        pq = PriorityQueue()

        # Initialisation
        seen[self.case] = True
        distance[self.case] = 0
        pq.put((0,self.case))

        # Processing
        try :
            while not seen[target] :
                prio, case = pq.get()
                if not seen[case] :
                    for vois in get_neightbors(case,obstacles):
                        new_distance = distance[case] + heuristic(target, vois)
                        if not seen[vois] and new_distance < distance[vois]:
                            pq.put((new_distance, vois))
                            distance[vois] = new_distance
                            passage[vois] = case
                seen[case] = True
        except Empty:
            return None
        else:
            # Post-Processing. Extracting path from datas
            shortest_path = []
            pos = target
            while pos != self.case :
                shortest_path.append(pos)
                pos = passage[pos]
            shortest_path.reverse()  # shortest_path was (goal -> init) and we want (init -> goal)
            return shortest_path


import datetime
from flask import Flask, Response, send_from_directory
import httpx
from os.path import exists

app = Flask(__name__)

now = datetime.datetime.now().strftime("%Y%m%d")

@app.route("/health")
def health():
  return "Ready"

@app.route("/")
def root():
  if not exists(f"/data/{now}.jpg"):
    print("Daily image missing. Fetching new image!")
    req = httpx.get("https://picsum.photos/300", follow_redirects=True)
    f = open(f"/data/{now}.jpg","wb")
    f.write(req.content)
  resp = f"""

<form method="post" action="/todos">
<input type="text" name="todo" maxlength="140">
<input type="submit" value="Create TODO">
</form>

"""
  req = httpx.get("http://backend-svc/todos")
  for todo in req.json():
    if todo["done"]:
      resp = resp + f"""
{todo["task"]}
"""
    else:
      resp = resp + f"""
<button onclick="done('/todos/{todo["id"]}')">Done</button> {todo["task"]}</form>
"""
  resp = resp + "
"
  return resp

@app.route("/pics/<string:pic>")
def picture(pic):
  return send_from_directory("/data", pic)


"""
Семинар занятие №3
Базовые задания
1) Реализовать функцию, принимающую два числа (позиционные аргументы) и выполняющую их деление.
Числа запрашивать у пользователя, предусмотреть обработку ситуации деления на ноль.
"""
def dividing(a, b):
# Функция деления числа
    try:
        result = a / b
    except ZeroDivisionError:
    # Обработка ситуации деления на ноль
        return
    return result

try:
    n1 = float(input("a = "))
    n2 = float(input("b = "))
    print(f"a / b = {dividing(n1, n2)}")
except ValueError:
# Обработка ситуации ввода текстовых данных
    print("Incorrect input value")

Basik task/lesson 3/Seminar 3 basik task 1.py


import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
fig = plt.figure()
ax = plt.axes(projection='3d')
z = np.linspace(0,1,100)
x = z*np.sin(z)
y = z*np.cos(z)
ax.plot3D(x,y,z,'g')
plt.show()


import sys
import time
from serial import Serial
from serial.tools import list_ports

from .config_handler import ConfigHandler

class UtilityHandler:

    arduino = None

    def write(message):
        UtilityHandler.arduino.write(message.encode())

    def init():
        print("""
        > Simulador ADS-B
        >> Autor: Caio Rondon Botelho de Carvalho
        >> Versao: 1.0v
        """)

        #
        # LISTA DIPOSITIVOS
        #

        # capturando dispositivos
        devices = list(list_ports.comports())
        # termina programa se nao encontra dispositivo para comunicacao
        if not devices:
            print("Nenhum dispositivo encontrado! Favor verificar.")
            sys.exit(0)

        print("Listando dispositivos conectados:\n[Numero] - 'Descricao'")
        for i, device in enumerate(devices):
            print ("["+ str(i) + "] - '" + str(device) + "'")

        #
        # ESCOLHER DISPOSITIVOS
        #
        opc = input("\nEscolha o numero que representa o Arduino. Qualquer letra para sair.\n> ")

        try:
            d = int(opc)
            # captura dispositivo escolhido
            arduino_info = devices[d]
            UtilityHandler.arduino = Serial(arduino_info.device, ConfigHandler.baudrate)
            time.sleep(2) # tempo para conexao ser estabelecida
            print("Conectado!")
        except ValueError:
            sys.exit(0)
        except Exception as e:
            print(str(e))
            print("Nao foi possivel se conectar ao dispositivo selecionado")
            sys.exit(1)

        return


import pygame
from .constants import BLACK, WHITE, BLUE, SQUARE_SIZE, ROWS, COLS, RED
from othello.board import Board
from .piece import Piece

LEFT = (0, -1)
TOP_LEFT = (-1, -1)
TOP = (-1, 0)
TOP_RIGHT = (-1, 1)
RIGHT = (0, 1)
BOTTOM_RIGHT = (1, 1)
BOTTOM = (1, 0)
BOTOTM_LEFT = (1, -1)

DIRECTIONS = (TOP_LEFT   , TOP   ,    TOP_RIGHT,
              LEFT       ,                RIGHT,
              BOTOTM_LEFT, BOTTOM, BOTTOM_RIGHT)

class Game:
    def __init__(self, win):
        self._init()
        self.win = win

    def update(self):
        self.board.draw(self.win)
        self.draw_valid_moves(self.valid_moves)
        # self.draw_opponent_neighbors(self.opponent_neighbors)
        pygame.display.update()

    def _init(self):
        self.selected = None
        self.board = Board()
        self.turn = BLACK
        self.black_count = 2
        self.white_count = 2
        self.valid_moves = set()
        self.opponent_neighbors = set()

    def reset(self):
        self._init()

    def step(self, row, col):
        initial_blacks = len(self.board.black_pieces_coordinates)
        initial_whites = len(self.board.white_pieces_coordinates)

        self._spawn_piece(row, col)

        next_state = self.board.board
        reward = self.white_count - initial_whites
        done = True

        return next_state, reward, done

    def _spawn_piece(self, row, col):

        if (row, col) in self.valid_moves:
            self.board.spawn_piece(row, col, self.turn)
            self.flip_pieces(row, col)
            # print('BLACK: ', self.black_count, ' | WHITE: ', self.white_count)
            print('BLACK: ', len(self.board.black_pieces_coordinates), ' | WHITE: ', len(self.board.white_pieces_coordinates))
            self.change_turn()
        else:
            print('Not a valid move!')

# PROBLEMA ME TO FLIP PIECES

    def flip_pieces(self, row, col):
        flipping_directions = set()
        piece = self.board.board[row][col]

        # this loop starts from the spawned piece position and extends to all directions while it finds oppponent pieces
        # if it a finds the current player's piece along this path, all oppponent piece in this path should be flip,
        # so the direction is stored

        for direction in DIRECTIONS:
            neighbor_position = tuple(x + y for x, y in zip((row, col), direction))
            if(neighbor_position[0] >= 0 and neighbor_position[1] >= 0 and
               neighbor_position[0] < ROWS and neighbor_position[1] < ROWS):
                next_piece = self.board.get_piece(neighbor_position[0], neighbor_position[1])

                while(next_piece == self.get_opponent()):
                    next_piece_coordinates = tuple(x + y for x, y in zip(next_piece.get_position(), direction))
                    if(next_piece_coordinates[0] < ROWS and next_piece_coordinates[1] < ROWS and
                       next_piece_coordinates[0] >= 0 and next_piece_coordinates[1] >= 0):
                           next_piece = self.board.get_piece(next_piece_coordinates[0], next_piece_coordinates[1])
                    else:
                        break

                    if next_piece == self.turn:
                       flipping_directions.add(direction)

        # we iterate once again from the spawned piece position, only to the flipping direction,
        # we flip all enemy piece along this path

        for direction in flipping_directions:
            neighbor_position = tuple(x + y for x, y in zip((row, col), direction))
            if(neighbor_position[0] >= 0 and neighbor_position[1] >= 0 and
               neighbor_position[0] < ROWS and neighbor_position[1] < ROWS):
                next_piece = self.board.get_piece(neighbor_position[0], neighbor_position[1])
                next_piece_coordinates = neighbor_position
                print(next_piece_coordinates)

                while( next_piece == self.get_opponent() ):
                    self.board.get_player_pieces(self.turn).add(next_piece.get_position())
                    # self.change_score()
                    self.board.get_opponent_pieces(self.turn).remove(next_piece.get_position())
                    self.board.board[next_piece.get_position()[0]][next_piece.get_position()[1]] = Piece(next_piece_coordinates[0], next_piece_coordinates[1], self.turn)

                    # added numbers board
                    pos  = next_piece.get_position()

                    if self.turn == WHITE:
                        self.board.board_QTable[pos[0]][pos[1]] = 1
                    elif self.turn == BLACK:
                        self.board.board_QTable[pos[0]][pos[1]] = -1

                    # end of initial numbes board addition

                    next_piece_coordinates = tuple(x + y for x, y in zip((next_piece_coordinates[0], next_piece_coordinates[1]), direction))
                    next_piece = self.board.get_piece(next_piece_coordinates[0], next_piece_coordinates[1])

    def change_turn(self):

        if self.turn == BLACK:
            self.turn = WHITE
        else:
            self.turn = BLACK

        self.valid_moves=self.get_valid_moves()

        if(len(self.valid_moves)) == 0:
            if( len(self.board.black_pieces_coordinates) +  len(self.board.white_pieces_coordinates) == 64):
              print('The game ended!')
              print('FINAL SCORE: ', 'BLACK: ', len(self.board.black_pieces_coordinates), ' | WHITE: ', len(self.board.white_pieces_coordinates))
              if(len(self.board.black_pieces_coordinates) > len(self.board.white_pieces_coordinates)):
                print('BLACK HAS WON')
              elif(len(self.board.white_pieces_coordinates) > len(self.board.black_pieces_coordinates)):
                print('WHITE HAS WON')
              elif(len(self.board.white_pieces_coordinates) == len(self.board.black_pieces_coordinates)):
                print('IT IS A TIE')
              else:
                print('Error calculating score')

            else:
                self.change_turn()
                print('----||||||----')
                print('~~~~~~~~~~~~~~')
                print('NO VALID MOVES')
                print('IT IS ', self.turn, '`s turn again!')
                print('~~~~~~~~~~~~~~')
                print('----||||||----')

    def get_valid_moves(self):
        opponent_adjuscent_cells = set()
        moves = set()

        for piece in self.board.get_opponent_pieces(self.turn):
            for direction in DIRECTIONS:
                neighbor=self.get_opponents_neighbors(piece, direction, opponent_adjuscent_cells)
                if(neighbor != None):
                    opponent_adjuscent_cells.add(neighbor)

        #mexri edw doylevei kala pernw ola ta adjuscent cells tou antipalou
        self.opponent_neighbors = opponent_adjuscent_cells

        for opponent_adjuscent_cell in opponent_adjuscent_cells:
            for direction in DIRECTIONS:
                possible_move = tuple(x + y for x, y in zip(opponent_adjuscent_cell, direction))
                if (possible_move[0] < ROWS and possible_move[1] < ROWS and
                    possible_move[0] >= 0 and possible_move[1] >= 0):

                    next_piece = self.board.get_piece(possible_move[0], possible_move[1])

                    while(next_piece == self.get_opponent()):
                         next_piece_coordinates = tuple(x + y for x, y in zip(next_piece.get_position(), direction))
                         if(next_piece_coordinates[0] < ROWS and next_piece_coordinates[1] < ROWS and
                            next_piece_coordinates[0] >= 0 and next_piece_coordinates[1] >= 0):
                                next_piece = self.board.get_piece(next_piece_coordinates[0], next_piece_coordinates[1])
                         else:
                             break

                         if next_piece == self.turn:
                            moves.add(opponent_adjuscent_cell)

        return moves

    def get_opponents_neighbors(self, piece, direction, moves):
        neighbor = tuple(x + y for x, y in zip(piece, direction))

        if neighbor not in moves:
            if(neighbor[0] >= 0 and neighbor[1] >= 0 and neighbor[0] < ROWS and neighbor[1] < ROWS):
                if(self.board.get_piece(neighbor[0], neighbor[1]) != None):
                    if self.board.get_piece(neighbor[0], neighbor[1]) == 0:
                        return neighbor

    def get_opponent(self):
        if self.turn == BLACK:
            return WHITE
        elif self.turn == WHITE :
            return BLACK

    def change_score(self):
        if self.turn == BLACK:
            self.black_count += 1
            self.white_count -= 1
        elif self.turn == WHITE:
            self.white_count += 1
            self.black_count -= 1

    def get_piece_count(self):
        if self.turn == BLACK:
            return self.black_count
        elif self.turn == WHITE:
            return self.white_count

    def next_piece_in_direction(self, current_tile, direction):
        next_piece = tuple(x + y for x, y in zip(current_tile, direction))

        if(next_piece[0] > ROWS - 1 or next_piece[1] > ROWS - 1 or
           next_piece[0] < 0 or next_piece[1] < 0):
            return False

        if(self.board.get_piece(next_piece[0], next_piece[1]) == self.get_opponent()):
            self.next_piece_in_direction(next_piece, direction)
        elif(self.board.get_piece(next_piece[0], next_piece[1]) == self.turn):
            return True
        else:
            return False

    def draw_valid_moves(self, moves):
        for move in moves:
            row, col = move
            pygame.draw.circle(self.win, BLUE, (col * SQUARE_SIZE + SQUARE_SIZE//2, row * SQUARE_SIZE + SQUARE_SIZE//2), 15)

    def draw_opponent_neighbors(self, opponent_neighbors):
        for move in opponent_neighbors:
            row, col = move
            pygame.draw.circle(self.win, RED, (col * SQUARE_SIZE + SQUARE_SIZE//2, row * SQUARE_SIZE + SQUARE_SIZE//2), 10)