import pygame
from robot import Robot
from manual_robot import ManualRobot
from automated_robot import AutomatedRobot
from automated_robots.robots_concursantes import *
from automated_robots.robots_zimatek import *
from robot_hub import RobotHub
from coin import Coin
import numpy as np
import os

class Combat:
    """
    A class to represent a robot combat environment.

    ...

    Attributes
    ----------
    dims : list
        with and height of the screen, dims = [width, height]
    robots : pygame.sprite.Group
        a sprite group containing the robot objects
    robot_list : list
        a list containing the robot objects
    left_robot : Robot
        the Robot that starts in the left-hand side
    right_robot : Robot
        the Robot that starts in the right-hand side
    robot_hubs : pygame.sprite.Group
        a sprite group containing the RobotHub objects
    coin_per_second : float
        estimated coin per second

    Methods
    -------
    fix_bugs:
        fixes bugs in the position of the robot sprites
    run:
        runs the robot combat

    """

    def __init__(self, left_robot: Robot, right_robot: Robot, coin_per_second: float):
        self.dims = (1050, 750)

        self.robots = pygame.sprite.Group()
        self.robots.add(left_robot)
        self.robots.add(right_robot)
        self.robot_list = [left_robot, right_robot]
        self.left_robot = left_robot
        self.right_robot = right_robot

        self.robot_hubs = pygame.sprite.Group()
        self.left_robot_hub = RobotHub(self.left_robot, RobotHub.DownLeft)
        self.right_robot_hub = RobotHub(self.right_robot, RobotHub.DownRight)

        self.robot_hubs.add(self.left_robot_hub)
        self.robot_hubs.add(self.right_robot_hub)

        self.coin_per_second = coin_per_second

        self.font = None
        self.font2 = None

    def fix_bugs(self):
        """
        fixes bugs in the position of the robot sprites

        :return:
        """
        if self.right_robot.living and self.left_robot.living:
            collide = self.left_robot.rect.colliderect(self.right_robot.rect)
            if collide:
                if self.left_robot.rect.x <= self.right_robot.rect.x:
                    self.left_robot.move(dx=-self.left_robot.rect.width, combat=self)
                    self.right_robot.move(dx=self.right_robot.rect.width, combat=self)
                else:
                    self.left_robot.move(dx=self.left_robot.rect.width, combat=self)
                    self.right_robot.move(dx=-self.right_robot.rect.width, combat=self)

    def run(self):
        """
        runs the robot combat

        :return:
        """
        pygame.init()
        pygame.font.init()
        self.font = pygame.font.Font("Resources/Pokemon_Classic.ttf", 16)
        self.font2 = pygame.font.Font("Resources/Pokemon_Classic.ttf", 28)

        background_image = pygame.image.load("Resources/background_mountains.jpg")
        background_image = pygame.transform.rotozoom(background_image, 0, 2.5)
        os.environ['SDL_VIDEO_CENTERED'] = '0'
        screen = pygame.display.set_mode(self.dims)
        pygame.display.set_caption("Robot Combat: {:s} vs {:s}".format(str(type(self.left_robot)).split(".")[-1][:-2],
                                                                       str(type(self.right_robot)).split(".")[-1][:-2]))

        for robot in self.robots:
            robot.set_up()

        for hub in self.robot_hubs:
            hub.set_up()

        # PRE LOOP
        sprites_all = pygame.sprite.Group()
        projectiles = pygame.sprite.Group()
        coins = pygame.sprite.Group()
        stop = False
        pause = False
        winner = None

        sprites_all.add(self.robots)
        sprites_all.add(projectiles)
        sprites_all.add(coins)
        clock = pygame.time.Clock()

        time = 1
        count_down = 60*3
        totalcoins = 0

        # -------- Principal Loop of the Program -----------
        while not stop:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    stop = True

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        pause = not pause
                        winner = None
                    if event.key == pygame.K_1:
                        pause = True
                        winner = 1
                    if event.key == pygame.K_0:
                        pause = True
                        winner = 0

                if isinstance(self.left_robot, ManualRobot) and self.left_robot.living:
                    projectile = self.left_robot.decide(event, self.left_robot_hub)
                    if projectile is not None:
                        sprites_all.add(projectile)
                        projectiles.add(projectile)

                elif isinstance(self.right_robot, ManualRobot) and self.right_robot.living:
                    projectile = self.right_robot.decide(event, self.right_robot_hub)
                    if projectile is not None:
                        sprites_all.add(projectile)
                        projectiles.add(projectile)

            # --- The Logic
            if not pause and (time > count_down):
                np.random.shuffle(self.robot_list)
                for robot in self.robot_list:
                    if robot == self.left_robot:
                        other = self.right_robot
                    else:
                        other = self.left_robot
                    if isinstance(robot, AutomatedRobot) and robot.living:
                        projectile = robot.decide(other_robot_properties=other.get_properties(),
                                                  coins=coins,
                                                  projectiles=projectiles)
                        if projectile is not None:
                            sprites_all.add(projectile)
                            projectiles.add(projectile)

                for robot in self.robot_list:
                    if robot.living:
                        robot_damaged = pygame.sprite.spritecollide(robot, projectiles, True)
                        coins_captured = pygame.sprite.spritecollide(robot, coins, True)

                        for projectile_hit in robot_damaged:
                            robot.suffer(projectile_hit.damage)
                        for coin in coins_captured:
                            robot.claim_coin(coin)
                        robot.update(combat=self)

                for projectile in projectiles:
                    projectile.draw(screen)
                    projectile.update(combat=self)

                coins.update()

                self.fix_bugs()

                if np.random.random() < self.coin_per_second / 60:
                    totalcoins += 2
                    pos1 = 50 + np.random.random(2) * (np.array(self.dims)-100) * np.array([0.5, 1])
                    pos2 = np.array(self.dims) * np.array([1, 0]) + pos1 * np.array([-1, 1])
                    coin_left = Coin(pos1)
                    coin_right = Coin(pos2)
                    coins.add(coin_left)
                    coins.add(coin_right)
                    sprites_all.add(coin_left)
                    sprites_all.add(coin_right)

            # --- The image
            screen.fill((255, 255, 255))
            screen.blit(background_image, (0, 0))
            sprites_all.draw(screen)

            for projectile in projectiles:
                projectile.draw(screen)

            for hub in self.robot_hubs:
                hub.draw(screen)

            time_text = self.font.render("{:02d}:{:02d}".format(int((time / 60) // 60), int((time / 60) % 60)), False,
                                         (0, 0, 0))
            screen.blit(time_text, (self.dims[0] - 5 - time_text.get_width(), 5))

            coin_text = self.font.render("# {:d}/{:d}".format(len(coins), int(totalcoins)), False,
                                         (0, 0, 0))
            screen.blit(coin_text, (self.dims[0] - 5 - coin_text.get_width(), 5 + coin_text.get_height()))

            # Only for zimabot
            if (isinstance(self.left_robot, Zimabot) or isinstance(self.right_robot, Zimabot)):
                if isinstance(self.left_robot, Zimabot):
                    zimabot = self.left_robot
                    other = self.right_robot
                else:
                    zimabot = self.right_robot
                    other = self.left_robot

                if time < count_down or (zimabot.living and not other.living):
                    belt_image = pygame.image.load("Resources/cinturon.png").convert_alpha()
                    belt_image = pygame.transform.scale(belt_image, (2*zimabot.width, 2*zimabot.height))
                    screen.blit(belt_image, zimabot.pos - np.array([zimabot.width//2, int(zimabot.height*1.5)]))
            # ----

            if self.left_robot.living and not self.right_robot.living:
                winner = 1
                pause = True
            if not self.left_robot.living and self.right_robot.living:
                winner = 0
                pause = True

            if pause:
                if winner == 1:
                    pause_text = self.font2.render("The winner is {:s}".format(str(type(self.left_robot)).split(".")[-1][:-2]), False, (0, 0, 0))
                    center = (self.dims[0] // 2, self.dims[1] // 2)
                    text_rect = pause_text.get_rect(center=center)
                    screen.blit(pause_text, text_rect)
                elif winner == 0:
                    pause_text = self.font2.render("The winner is {:s}".format(str(type(self.right_robot)).split(".")[-1][:-2]), False, (0, 0, 0))
                    center = (self.dims[0] // 2, self.dims[1] // 2)
                    text_rect = pause_text.get_rect(center=center)
                    screen.blit(pause_text, text_rect)
                else:
                    pause_text = self.font.render("Paused", False, (0, 0, 0))
                    center = (self.dims[0] // 2, self.dims[1] // 2)
                    text_rect = pause_text.get_rect(center=center)
                    screen.blit(pause_text, text_rect)
            else:
                time += 1

            pygame.display.flip()

            clock.tick(60)
        pygame.quit()

if __name__ == '__main__':
    attributes = {
        "health": 500,
        "armor": 90,
        "health_regen": 19,
        "damage": 65,
        "self_speed": 3,
        "projectile_initial_speed": 4,
        "projectile_per_second": 0.6,
        "g_health": 80,
        "g_armor": 8,
        "g_health_regen": 2,
        "g_damage": 12,
        "g_projectile_per_second": 0.05,
        "max_self_speed": 5,
        "max_projectile_initial_speed": 10,
        "experience_for_level_up": 7,
        "g_experience_for_level_up": 3
    }

    cps = 2

    bots = pygame.sprite.Group()
    bot1 = stalin_t_pose(x=150, y=325, **attributes)

    bot2 = Zimabot(x=1050-150-4*32, y=325, turn_left=True,
                   projectile_color=(38, 162, 149), image_path="Resources/simple_robot_green.png",
                   **attributes)

    mg = Combat(bot1, bot2, coin_per_second=cps)
    mg.run()


#!/usr/bin/python3

if __name__ == "__main__":

    import sys
    from calculator_1 import add, sub, mul, div

    args = sys.argv[1:]
    no_of_args = len(args)

    if no_of_args != 3:
        print("Usage: ./100-my_calculator.py <a> <operator> <b>")
        sys.exit(1)
    op = args[1]
    operators = {"+": add, "-": sub, "*": mul, "/": div}

    if op not in operators:
        print("Unknown operator. Available operators: +, -, * and /")
        sys.exit(1)

    a = int(args[0])
    b = int(args[2])
    res = operators[op](a, b)
    print(f"{a} {op} {b} = {res}")


import json
import glob
from flask import Flask , send_file
import os
from flask_cors import CORS

app = Flask (__name__)
cors = CORS(app)
@app.route('/')
def DownloadMergedJson() -> str:
    result = {}
    logs = {}
    node_ids =[]
    for f in glob.glob(os.path.join("..", "history_*.json")):
        print(str(f))
        node_ids.append(str(f).split('.')[2].split('_')[1])

    result["all_nodes"] = node_ids

    for f in glob.glob(os.path.join("..", "history_*.json")):
        node_id = str(f).split('.')[2].split('_')[1]
        with open(f, "rb") as infile:
            result[node_id] = json.load(infile)

    return result

app.run()


import requests
import collections
import csv

from bs4 import BeautifulSoup
from bs4.element import Tag

class ParseAnimals:
    def __init__(self) -> None:
        self.animals_names = {}

    def parse(self) -> None:
        """
            Make a while loop until calegory letter != Я
            Saves each animal data on the page in dict: key - letter, value - list of all animals on the page
        """
        url = 'https://ru.wikipedia.org/wiki/Категория:Животные_по_алфавиту'
        letter = ''

        while letter != 'Я':
            data = self._get_page(url)
            self._parse_animal_on_page(data=data)
            url = self._check_end_page(data=data)

            letter = collections.deque(self.animals_names, maxlen=1)[0][0]
            print(letter)

        self._get_csv()

    def _get_page(self, url: str) -> Tag:
        """
            Make a request on the page and gets all page data
        """
        request = requests.get(url)
        soup = BeautifulSoup(request.text, 'lxml')

        return soup.find('div', id='mw-pages')

    def _parse_animal_on_page(self, data: Tag) -> None:
        """
            Saves all animals on the page in a dict with key = category (letter)
        """
        for el in data.find_all('div', class_='mw-category-group'):
            category = el.h3.text
            animal_names = [[i.text, f"https://ru.wikipedia.org{i.a['href']}"] for i in el.find_all('li')]

            if not self.animals_names.get(category):
                self.animals_names[category] = []

            self.animals_names[category] = self.animals_names[category] + animal_names

    def _check_end_page(self, data: Tag) -> str:
        """
            Return an url to the next page
        """
        hrf = data.find_all('a')[-1]
        return f"https://ru.wikipedia.org{hrf['href']}"

    def _get_csv(self) -> None:
        """
            Saves data (dict) into csv file
        """
        with open('animals_names_count.csv', 'w') as f:
            writer = csv.writer(f)
            writer.writerows([[f'{k}, {len(v)}'] for k, v in self.animals_names.items()])

if __name__ == '__main__':
    parse = ParseAnimals()
    parse.parse()


import nltk
from newspaper import Article

# nltk.download('punkt') is a Python command that is used to download the "punkt" dataset or resource from the Natural Language Toolkit (NLTK) library.
# NLTK is a popular library in Python for working with human language data, including tasks like tokenization, parsing, and text classification.
# The "punkt" dataset in NLTK contains pre-trained models and data necessary for tokenization, which is the process of breaking down a text into individual words or tokens.
# These pre-trained models can be used to tokenize text in various languages, making it easier to work with natural language data in your Python projects.

nltk.download('punkt')
url='https://indianexpress.com/article/technology/tech-news-technology/apple-event-2-things-wowed-us-8938618/'
article = Article(url)
article.download()
article.parse()
article.nlp()

print(f'Title: {article.title}')
print(f'Authors: {article.authors}')
print(f'Publish Date: {article.publish_date}')
print(f'Summary: {article.summary}')


"""2020_02_18

Revision ID: 000001
Revises:
Create Date: 2020-02-18 03:57:38.958091

"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "000001"
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "users",
        sa.Column("added_on", sa.DateTime(), nullable=False),
        sa.Column("modified_on", sa.DateTime(), nullable=False),
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("enabled", sa.Boolean(), nullable=False),
        sa.Column("last_auth_time", sa.DateTime(), nullable=True),
        sa.Column("username", sa.String(length=32), nullable=False),
        sa.Column("password_hash", sa.String(length=128), nullable=True),
        sa.PrimaryKeyConstraint("id", name=op.f("pk_users")),
    )
    op.create_index(op.f("ix_users_username"), "users", ["username"], unique=True)
    op.create_table(
        "user_accesses",
        sa.Column("added_on", sa.DateTime(), nullable=False),
        sa.Column("modified_on", sa.DateTime(), nullable=False),
        sa.Column("id", sa.BigInteger(), autoincrement=True, nullable=False),
        sa.Column("enabled", sa.Boolean(), nullable=False),
        sa.Column("ip_address", sa.String(length=15), nullable=False),
        sa.Column("external_app_id", sa.String(length=15), nullable=False),
        sa.Column("users_id", sa.BigInteger(), nullable=False),
        sa.ForeignKeyConstraint(
            ["users_id"],
            ["users.id"],
            name=op.f("fk_user_accesses_users_id_users"),
            onupdate="CASCADE",
            ondelete="CASCADE",
        ),
        sa.PrimaryKeyConstraint("id", name=op.f("pk_user_accesses")),
        sa.UniqueConstraint(
            "users_id",
            "ip_address",
            "external_app_id",
            name=op.f("uq_user_accesses_users_id"),
        ),
    )
    op.create_index(
        op.f("ix_user_accesses_external_app_id"),
        "user_accesses",
        ["external_app_id"],
        unique=True,
    )
    op.create_index(
        op.f("ix_user_accesses_ip_address"),
        "user_accesses",
        ["ip_address"],
        unique=False,
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f("ix_user_accesses_ip_address"), table_name="user_accesses")
    op.drop_index(op.f("ix_user_accesses_external_app_id"), table_name="user_accesses")
    op.drop_table("user_accesses")
    op.drop_index(op.f("ix_users_username"), table_name="users")
    op.drop_table("users")
    # ### end Alembic commands ###


from pyglet.text import Label

from audio import explosion
from fonts.fonts import press_start_2p
from interfaces.interface import Interface
from system import system

import menus.menu
import menus.game_over_menu

class GameOverInterface(Interface):
    game_over_label: Label = None
    game_over_menu: menus.menu.Menu = None

    def __init__(self):
        self.game_over_label = Label('GAME OVER', font_name=press_start_2p, font_size=48)
        self.game_over_label.anchor_x = 'center'
        self.game_over_label.anchor_y = 'center'
        self.game_over_menu = menus.game_over_menu.GameOverMenu()
        self.resize()
        window = system.get_window()
        window.on_key_press = self.game_over_menu.on_key_press
        self.game_over_menu.focused = True
        explosion.play()

    def on_draw(self):
        self.game_over_label.draw()
        self.game_over_menu.draw()

    def resize(self):
        window = system.get_window()
        self.game_over_menu.move(window.width / 2, 100)
        self.game_over_label.x = window.width / 2
        self.game_over_label.y = window.height / 2


# This script should be executed inside a NetAddiction Odoo 9 shell.

import json

def remove_duplicate_attributes(product):
    seen_ids = set()
    duplicate_list = []
    for attr in product.attribute_value_ids:
        if attr.attribute_id.id not in seen_ids:
            seen_ids.add(attr.attribute_id.id)
        else:
            duplicate_list.append(attr)
    if duplicate_list:
        product.write({"attribute_value_ids": [(3, attr.id) for attr in duplicate_list]})
        return duplicate_list

duplicates = []
products = self.env["product.product"].search([])
for count, product in enumerate(products):
    duplicate = remove_duplicate_attributes(product)
    if duplicate:
        print(duplicate)
        duplicates.append(
            {
                "product_id": product.id,
                "duplicates": [{"name": a.name, "type": a.attribute_id.display_name} for a in duplicate],
            }
        )
    if not count % 100:
        self._cr.commit()
self._cr.commit()

if duplicates:
    with open("~/duplicates_found.json", "w") as fp:
        json.dump(duplicates, fp, sort_keys=True, indent=4, separators=(",", ": "))


import re
from requests import get
from sys import argv as cla
from readabilipy import simple_json_from_html_string
from ebooklib import epub

def valid_url(url):
	regex = re.compile(
        r'^(?:http)s?://' # http:// or https://
        r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' #domain...
        r'localhost|' #localhost...
        r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
        r'(?::\d+)?' # optional port
        r'(?:/?|[/?]\S+)$', re.IGNORECASE)
	return re.match(regex, str(url)) is not None

def slugify(s):
	s = s.lower().strip()
	s = ''.join(char for char in s if ord(char) < 128) #remove non-ascii characters
	s = re.sub(r'[^\w\s-]', '', s)
	s = re.sub(r'[\s_-]+', '-', s)
	s = re.sub(r'^-+|-+$', '', s)
	return s

def main():
	if not cla[1]:
		raise Exception("Invalid argument..")
	if len(cla) != 2:
		raise Exception("This script expects just one parameter.. Did you comma separate the URL's")

	links = str(cla[1]).split(',')

	for l in links:
		if not valid_url(l):
			raise Exception(str("This is not a valid url: "+l))

	book = epub.EpubBook()
	book.set_language('en')
	chapters = ['nav']
	epub_title = ""
	epub_author = ""
	toc = []

	if len(links) > 1:
		print("You're trying to download {0} links. Please provide title and author.".format(len(links)))
		epub_title = input("ePub title: ")
		epub_author = input("ePub author: ")
	for idx, link in enumerate(links):
		try:
			request = get(link)
			if bool(request.text) == False:
				if input('Do you want to skip this URL and continue? [y/n]') == 'y':
					continue
				else:
					print('Script stopped')
					sys.exit(0)
			else:
				print('Extracting content from page..')
				page_content = simple_json_from_html_string(request.text, use_readability=False)

				chapter_content = page_content['plain_content']

				if not epub_title:
					epub_title = page_content['title']

				if not epub_author:
					epub_author = page_content['byline'] if page_content['byline'] else "Various authors"

				print('Adding content to ePub..')
				chapter = epub.EpubHtml(title=page_content['title'], file_name=str('chapter{}.xhtml'.format(idx+1)), lang='en')
				chapter.content = u'{}'.format(chapter_content)
				book.add_item(chapter)
				chapters.append(chapter)
			pass
		except Exception as e:
			raise e

	print("Finishing epub..")

	slug = slugify(epub_title)

	book.set_identifier(slug)
	book.set_title(epub_title)
	book.add_item(epub.EpubNcx())
	book.add_item(epub.EpubNav())

	book.spine = chapters

	if epub_author:
		book.add_author(epub_author)
	else:
		book.add_author("Unknown Author")

	try:
		epub.write_epub('{}.epub'.format(slug), book, {})
		print("Done! Saved to {}.epub".format(slug))
	except Exception as e:
		raise e

if __name__ == "__main__":
	main()


# Import thư viện
from sklearn.linear_model import LinearRegression
import numpy as np
import csv
from vnstock import*
data=[]
cp=listing_companies()
check='ngân hàng thương mại cổ phần'
nh=[]
for n in range(len(cp)):
    if check in cp.loc[n][2].lower():
        nh.append(cp.loc[n][0])
print(len(nh))
for ticket in nh:
    linkfile='./nganhang/'+ticket+'.csv'
    with open(linkfile) as file:
        fp=csv.reader(file)
        header=next(fp)
        for row in fp:
            data.append(row)
    # Tạo dữ liệu giả định
    K=[]
    h=[]
    for i in range(len(data)):
        K.append([float(data[i][1]),float(data[i][2])])
        h.append(float(data[i][4]))
    # Tạo mô hình hồi quy tuyến tính
    model = LinearRegression()

    # Huấn luyện mô hình với dữ liệu
    model.fit(K, h)

    # In ra các hệ số của mô hình
    print('Coefficients:', model.coef_)

    # Dự đoán giá trị mới
    x_new = np.array([[48850.0,48222.0]])
    y_new = model.predict(x_new)
    print('Predicted value:', y_new)


def create_triangle(size):
    triangle = ""

    # first part
    for r in range(1, size + 1):
        for c in range(1, r + 1):
            triangle += f"{c} "
        triangle += "\n"
    # second part
    for r in range(size - 1, -1, -1):
        for c in range(1, r + 1):
            triangle += f"{c} "
        triangle += "\n"

    return triangle

def mathematical_operations(*args):
    first, operator, second = args

    operations = {
        "/": lambda x, y: x / y,
        "*": lambda x, y: x * y,
        "-": lambda x, y: x - y,
        "^": lambda x, y: x ** y,
    }

    return f"{operations[operator](float(first), float(second)):.2f}"

def fibonacci_sequence_module(*args):
    # fibonacci logic
    def fibonacci_sequence(n):
        sequence = [0, 1]
        for i in range(n - 2):
            sequence.append(sequence[-1] + sequence[-2])
        return sequence

    def locate_number(n, seq):
        try:
            return f"The number - {n} is at index {seq.index(n)}"
        except ValueError:
            return f"The number {n} is not in the sequence"

    action = args[0]
    if action == "Create":
        return fibonacci_sequence
    elif action == "Locate":
        return locate_number


import CryptoCurrency
import sqlite3 as sql
import requests
from datetime import datetime
import time

def get_crypto():
    """Récupères la liste des cryptomonnaies tradable sur le marché futures de Bybit
    (!! 120 requests per second for 5 consecutive seconds maximum)
    Returns:
        list:liste des cryptomonnaies
    """

    url = "https://api-testnet.bybit.com/v5/market/instruments-info?category=linear"

    payload = {}
    headers = {}

    response = requests.request(
        "GET", url, headers=headers, data=payload).json()
    baseCoins = []

    for crypto in response['result']['list']:
        if crypto['baseCoin'][:5] == '10000' and crypto['quoteCoin'] == 'USDT' and crypto['baseCoin'] not in baseCoins:
            # baseCoins += [crypto['baseCoin'][5:]]
            # non traité pour le moment
            pass
        elif crypto['baseCoin'][:4] == '1000' and crypto['quoteCoin'] == 'USDT' and crypto['baseCoin'] not in baseCoins:
            # baseCoins += [crypto['baseCoin'][4:]]
            # non traité pour le moment
            pass
        elif crypto['quoteCoin'] == 'USDT' and crypto['baseCoin'] not in baseCoins and crypto['baseCoin'] != 'LUNA2' and crypto['baseCoin'] != 'PEOPLE':
            # exception LUNA2 et PEOPLE à traiter
            baseCoins += [crypto['baseCoin']]

    return baseCoins

def get_price_history(interval, crypto):
    """renvoie un dicitonnaire qui permet de connaître le prix de la cryptomonnaie depuis l'apparition de son contrat futures sur l'échange de cryptomonnaie.

    Args:
        interval (string): interval de temps entre deux données (Kline interval. 1,3,5,15,30,60,120,240,360,720,D,M,W)
        crypto (CryptoCurrency): la crypto dont on veut le prix
    """
    listeDictionnaires = []
    listeDictionnaires.append(crypto.get_price(interval, 1500000000000,
                                               int(datetime.now().timestamp())*1000))
    lastTimestamps = list(listeDictionnaires[0].keys())
    lastTimestamps.sort()
    if len(lastTimestamps) < 200:
        return listeDictionnaires
    # intervalInTimestamp = int(lastTimestamps[2])-int(lastTimestamps[1])
    # jusqu'ici on a récupéré les 200 derniers timestamps
    compteur = 1
    while len(lastTimestamps) == 200:
        listeDictionnaires.append(crypto.get_price(
            interval, 1500000000000, int(lastTimestamps[0])))
        # il ne faut pas dépasser les 120 requetes par 5 secondes
        if compteur % 119 == 0:
            time.sleep(5)
        lastTimestamps = (list(listeDictionnaires[compteur].keys()))
        lastTimestamps.sort()
        compteur += 1
    print(listeDictionnaires)
    return listeDictionnaires

if __name__ == "__main__":
    # fonctionnement normal
    # print(get_crypto())
    cryptos = get_crypto()
    conn = sql.connect("cryptoDatabase.db")
    curs = conn.cursor()
    curs.execute("DROP TABLE IF EXISTS Crypto")
    curs.execute(
        "CREATE TABLE  Crypto (nom VARCHAR, symbol VARCHAR PRIMARY KEY, whitepaperlink VARCHAR)")
    curs.execute("DROP TABLE IF EXISTS Prix")
    curs.execute(
        "CREATE TABLE  Prix (symbol VARCHAR, date VARCHAR, open FLOAT, high FLOAT, low FLOAT, close FLOAT,PRIMARY KEY (symbol, date),FOREIGN KEY (symbol) REFERENCES Crypto(symbol))")
    cryptoCurrencies = []
    for crypto in cryptos:
        cryptoCurrencies += [CryptoCurrency.Cryptocurrency(crypto)]
    for crypto in cryptoCurrencies:
        infos = crypto.get_name_and_whitepaperlink()
        # l'interval choisi ici est hebdomadaire si on veut plus de précision, on peut prendre un plus petit interval
        price_history = get_price_history(
            "W", crypto)
        curs.execute("INSERT INTO Crypto(nom,symbol,whitepaperlink) VALUES (?,?,?)",
                     (infos["name"], crypto.symbol, infos["whitepaperLink"]))
        conn.commit()
        for prices in price_history:
            timestamps = list(prices.keys())
            for date in timestamps:
                curs.execute("INSERT INTO Prix(symbol,date,open,high,low,close) VALUES (?,?,?,?,?,?)",
                             (crypto.symbol, datetime.fromtimestamp(int(date)/1000), prices[date]["open"], prices[date]["high"], prices[date]["low"], prices[date]["close"]))
                conn.commit()
    conn.commit()
    conn.close()

    # test

    # nft = CryptoCurrency.Cryptocurrency('EOS')
    # print(get_price_history("D", nft))
    # bitcoin = CryptoCurrency.Cryptocurrency("BTC")
    # get_price_history("D", bitcoin)
    # infos = bitcoin.get_name_and_whitepaperlink()
    # conn = sql.connect("cryptoDatabase.db")
    # curs = conn.cursor()
    # curs.execute("DROP TABLE IF EXISTS Crypto")
    # curs.execute(
    #     "CREATE TABLE  Crypto (nom VARCHAR PRIMARY KEY, symbole VARCHAR, whitepaperlink VARCHAR)")
    # curs.execute(
    #     "INSERT INTO Crypto(nom,symbole,whitepaperlink) VALUES (?,?,?)", (infos["name"], bitcoin.symbol, infos["whitepaperLink"]))
    # conn.commit()
    # conn.close()


from dexy.common import OrderedDict
import dexy.database
import dexy.doc
import dexy.parser
import dexy.reporter
import inspect
import json
import logging
import logging.handlers
import os
import shutil

class Wrapper(object):
    """
    Class that assists in interacting with Dexy, including running Dexy.
    """
    DEFAULT_ARTIFACTS_DIR = 'artifacts'
    DEFAULT_CONFIG_FILE = 'dexy.conf' # Specification of dexy-wide config options.
    DEFAULT_DANGER = False
    DEFAULT_DB_ALIAS = 'sqlite3'
    DEFAULT_DB_FILE = 'dexy.sqlite3'
    DEFAULT_DISABLE_TESTS = False
    DEFAULT_DONT_USE_CACHE = False
    DEFAULT_DRYRUN = False
    DEFAULT_EXCLUDE = ''
    DEFAULT_GLOBALS = ''
    DEFAULT_HASHFUNCTION = 'md5'
    DEFAULT_IGNORE_NONZERO_EXIT = False
    DEFAULT_LOG_DIR = 'logs'
    DEFAULT_LOG_FILE = 'dexy.log'
    DEFAULT_LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    DEFAULT_LOG_LEVEL = 'DEBUG'
    DEFAULT_RECURSE = True
    DEFAULT_REPORTS = 'output'
    DEFAULT_SILENT = False

    LOG_LEVELS = {
            'DEBUG' : logging.DEBUG,
            'INFO' : logging.INFO,
            'WARN' : logging.WARN
            }

    RENAME_PARAMS = {
            'artifactsdir' : 'artifacts_dir',
            'conf' : 'config_file',
            'dbalias' : 'db_alias',
            'dbfile' : 'db_file',
            'disabletests' : 'disable_tests',
            'dryrun' : 'dry_run',
            'ignore' : 'ignore_nonzero_exit',
            'logfile' : 'log_file',
            'logformat' : 'log_format',
            'loglevel' : 'log_level',
            'logsdir' : 'log_dir',
            'nocache' : 'dont_use_cache'
            }

    SKIP_KEYS = ['h', 'help', 'version']

    def __init__(self, *args, **kwargs):
        self.initialize_attribute_defaults()
        self.check_config_file_location(kwargs)
        self.load_config_file()
        self.update_attributes_from_config(kwargs)

        self.args = args
        self.docs_to_run = []
        self.tasks = OrderedDict()
        self.pre_attrs = {}
        self.state = None

    def initialize_attribute_defaults(self):
        self.artifacts_dir = self.DEFAULT_ARTIFACTS_DIR
        self.config_file = self.DEFAULT_CONFIG_FILE
        self.danger = self.DEFAULT_DANGER
        self.db_alias = self.DEFAULT_DB_ALIAS
        self.db_file = self.DEFAULT_DB_FILE
        self.disable_tests = self.DEFAULT_DISABLE_TESTS
        self.dont_use_cache = self.DEFAULT_DONT_USE_CACHE
        self.dry_run = self.DEFAULT_DRYRUN
        self.exclude = self.DEFAULT_EXCLUDE
        self.globals = self.DEFAULT_GLOBALS
        self.hashfunction = self.DEFAULT_HASHFUNCTION
        self.ignore_nonzero_exit = self.DEFAULT_IGNORE_NONZERO_EXIT
        self.log_dir = self.DEFAULT_LOG_DIR
        self.log_file = self.DEFAULT_LOG_FILE
        self.log_format = self.DEFAULT_LOG_FORMAT
        self.log_level = self.DEFAULT_LOG_LEVEL
        self.recurse = self.DEFAULT_RECURSE
        self.reports = self.DEFAULT_REPORTS
        self.silent = self.DEFAULT_SILENT

    def check_config_file_location(self, kwargs):
        self.update_attributes_from_config(kwargs)

    def update_attributes_from_config(self, config):
        for key, value in config.iteritems():
            if not key in self.SKIP_KEYS:
                corrected_key = self.RENAME_PARAMS.get(key, key)
                if not hasattr(self, corrected_key):
                    raise Exception("no default for %s" % corrected_key)
                setattr(self, corrected_key, value)

    def load_config_file(self):
        """
        Look for a config file in current working dir and loads it.
        """
        if os.path.exists(self.config_file):
            with open(self.config_file) as f:
                try:
                    conf = json.load(f)
                except ValueError as e:
                    msg = inspect.cleandoc("""Was unable to parse the json in your config file '%s'.
                    Here is information from the json parser:""" % self.config_file)
                    msg += "\n"
                    msg += str(e)
                    raise dexy.exceptions.UserFeedback(msg)

            self.update_attributes_from_config(conf)

    @classmethod
    def default_config(klass):
        conf = klass().__dict__.copy()

        # Remove any attributes that aren't config options
        del conf['args']
        del conf['docs_to_run']
        del conf['tasks']

        for cl_key, internal_key in klass.RENAME_PARAMS.iteritems():
            conf[cl_key] = conf[internal_key]
            del conf[internal_key]

        return conf

    def db_path(self):
        return os.path.join(self.artifacts_dir, self.db_file)

    def log_path(self):
        return os.path.join(self.log_dir, self.log_file)

    def run(self):
        self.setup_run()

        self.log.debug("batch id is %s" % self.batch_id)
        self.state = 'populating'

        for doc in self.docs_to_run:
            for task in doc:
                task()

        self.state = 'settingup'

        for doc in self.docs_to_run:
            for task in doc:
                task()

        self.state = 'running'

        for doc in self.docs_to_run:
            for task in doc:
                task()

        self.state = 'complete'

        self.save_db()
        self.setup_graph()

    def setup_run(self):
        self.check_dexy_dirs()
        self.setup_log()
        self.setup_db()

        self.batch_id = self.db.next_batch_id()

        if not self.docs_to_run:
            self.setup_docs()

    def setup_read(self, batch_id=None):
        self.check_dexy_dirs()
        self.setup_log()
        self.setup_db()

        if batch_id:
            self.batch_id = batch_id
        else:
            self.batch_id = self.db.max_batch_id()

    def check_dexy_dirs(self):
        if not (os.path.exists(self.artifacts_dir) and os.path.exists(self.log_dir)):
            raise dexy.exceptions.UserFeedback("You need to run 'dexy setup' in this directory first.")

    def setup_dexy_dirs(self):
        if not os.path.exists(self.artifacts_dir):
            os.mkdir(self.artifacts_dir)
        if not os.path.exists(self.log_dir):
            os.mkdir(self.log_dir)

    def remove_dexy_dirs(self):
        shutil.rmtree(self.artifacts_dir)
        shutil.rmtree(self.log_dir)
        # TODO remove reports dirs

    def setup_log(self):
        try:
            loglevel = self.LOG_LEVELS[self.log_level.upper()]
        except KeyError:
            msg = "'%s' is not a valid log level, check python logging module docs."
            raise dexy.exceptions.UserFeedback(msg % self.log_level)

        self.log = logging.getLogger('dexy')
        self.log.setLevel(loglevel)

        handler = logging.handlers.RotatingFileHandler(
                self.log_path(),
                encoding="utf-8")

        formatter = logging.Formatter(self.log_format)
        handler.setFormatter(formatter)

        self.log.addHandler(handler)

    def setup_db(self):
        db_class = dexy.database.Database.aliases[self.db_alias]
        self.db = db_class(self)

    def setup_docs(self):
        for arg in self.args:
            self.log.debug("Processing arg %s" % arg)
            doc = self.create_doc_from_arg(arg)
            if not doc:
                raise Exception("no doc created for %s" % arg)
            doc.wrapper = self
            self.docs_to_run.append(doc)

    def create_doc_from_arg(self, arg, *children, **kwargs):
        if isinstance(arg, dexy.task.Task):
            return arg

        elif isinstance(arg, list):
            if not isinstance(arg[0], basestring):
                msg = "First arg in %s should be a string" % arg
                raise dexy.exceptions.UserFeedback(msg)

            if not isinstance(arg[1], dict):
                msg = "Second arg in %s should be a dict" % arg
                raise dexy.exceptions.UserFeedback(msg)

            if kwargs:
                raise Exception("Shouldn't have kwargs if arg is a list")

            if children:
                raise Exception("Shouldn't have children if arg is a list")

            alias, pattern = dexy.parser.AbstractSyntaxTree.qualify_key(arg[0])
            return dexy.task.Task.create(alias, pattern, **arg[1])

        elif isinstance(arg, basestring):
            alias, pattern = dexy.parser.AbstractSyntaxTree.qualify_key(arg[0])
            return dexy.task.Task.create(alias, pattern, *children, **kwargs)

        else:
            raise Exception("unknown arg type %s for arg %s" % (arg.__class__.__name__, arg))

    def save_db(self):
        self.db.save()

    ## DOCUMENTED above here..

    def run_docs(self, *docs):
        """
        Convenience method for testing to add docs and then run them.
        """
        self.setup_dexy_dirs()
        self.docs_to_run = docs
        self.run()

    def register(self, task):
        """
        Register a task with the wrapper
        """
        self.tasks[task.key_with_class()] = task

    def registered_docs(self):
        return [d for d in self.tasks.values() if isinstance(d, dexy.doc.Doc)]

    def registered_doc_names(self):
        return [d.name for d in self.registered_docs()]

    def reports_dirs(self):
        return [c.REPORTS_DIR for c in dexy.reporter.Reporter.plugins]

    def report(self, *reporters):
        """
        Runs reporters. Either runs reporters which have been passed in or, if
        none, then runs all available reporters which have ALLREPORTS set to
        true.
        """
        if not reporters:
            reporters = [c() for c in dexy.reporter.Reporter.plugins if c.ALLREPORTS]

        for reporter in reporters:
            self.log.debug("Running reporter %s" % reporter.ALIASES[0])
            reporter.run(self)

    def get_child_hashes_in_previous_batch(self, parent_hashstring):
        return self.db.get_child_hashes_in_previous_batch(self.batch_id, parent_hashstring)

    def load_doc_config(self):
        """
        Look for document config files in current working dir and load them.
        """
        parser_aliases = dexy.parser.Parser.aliases
        for k in parser_aliases.keys():
            if os.path.exists(k):
                self.log.debug("found doc config file '%s'" % k)

                parser = parser_aliases[k](self)

                with open(k, "r") as f:
                    self.doc_config = f.read()
                    parser.parse(self.doc_config)

                break

    def setup_config(self):
        self.setup_dexy_dirs()
        self.setup_log()
        self.load_doc_config()

    def cleanup_partial_run(self):
        if hasattr(self, 'db'):
            # TODO remove any entries which don't have
            self.db.save()

    def setup_graph(self):
        """
        Creates a dot representation of the tree.
        """
        graph = ["digraph G {"]

        for task in self.tasks.values():
            if hasattr(task, 'artifacts'):
                task_label = task.key_with_class().replace("|", "\|")
                label = """   "%s" [shape=record, label="%s\\n\\n""" % (task.key_with_class(), task_label)
                for child in task.artifacts:
                    label += "%s\l" % child.key_with_class().replace("|", "\|")

                label += "\"];"
                graph.append(label)

                for child in task.children:
                    if not child in task.artifacts:
                        graph.append("""   "%s" -> "%s";""" % (task.key_with_class(), child.key_with_class()))

            elif "Artifact" in task.__class__.__name__:
                pass
            else:
                graph.append("""   "%s" [shape=record];""" % task.key_with_class())
                for child in task.children:
                    graph.append("""   "%s" -> "%s";""" % (task.key_with_class(), child.key_with_class()))

        graph.append("}")

        self.graph = "\n".join(graph)


############## THESE SPLINES ARE USING CATMULL SPLINES ##############
# https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline
#
# FOLLOWING javidx9's SPLINE VIDEOS:
# https://www.youtube.com/watch?v=9_aJGUTePYo&t=898s&ab_channel=javidx9

from typing import List
import pygame, math
from code_modules.spline.spline_point_2D import Spline_Point2D

### THE FONT IS USED TO SHOW fOffset AND fMarker ###

###############

class Spline:
    def __init__(self):
        self.points = []
        self.activePoint = 0
        self.isLooped = False
        self.RIGHT = False
        self.LEFT = False
        self.UP = False
        self.DOWN = False
        self.totalLineLength = 0
        ############# DEBUG FONT #############
        ### THE FONT IS USED TO SHOW fOffset AND fMarker ###
        self.font = pygame.font.SysFont(None, 20)

    def update(self):
        if self.RIGHT:
            self.points[self.activePoint].x += 5
        if self.LEFT:
            self.points[self.activePoint].x -= 5
        if self.UP:
            self.points[self.activePoint].y -= 5
        if self.DOWN:
            self.points[self.activePoint].y += 5

        ### CALCULATE TOTAL LENGTH ###
        self.totalLineLength = self.__getTotalLength()

    def draw(self, canvas):
        ##### DRAW SPLINE POINTS #####
        ### LOOPED ###
        if self.isLooped:
            for t in range(0, len(self.points)*100, 1):
                pos = self.getSplinePoint(t / 100)
                pygame.draw.circle(canvas, (255,255,255), (pos.x, pos.y), 2)
        ### NOT LOOPED ###
        else:
            for t in range(0, (len(self.points)*100) - 300 , 1):
                pos = self.getSplinePoint(t / 100)
                pygame.draw.circle(canvas, (255,255,255), (pos.x, pos.y), 2)

        ##### DRAW CONTROL POINTS + TEXT #####
        for i in range(len(self.points)):
            ### DRAW DISTANCE ###
            tempImg = self.font.render(str(self.points[i].length), True, (200,200,200))
            canvas.blit(tempImg, (self.points[i].x + 20, self.points[i].y))
            ##########################

            ##### CONTROL POINTS #####
            if i == self.activePoint:
                pygame.draw.circle(canvas, (255,255,0), (self.points[i].x, self.points[i].y), 5)
            else:
                pygame.draw.circle(canvas, (255,0,0), (self.points[i].x, self.points[i].y), 5)
            tempImg = self.font.render(str(i), True, (255,255,255))
            canvas.blit(tempImg, (self.points[i].x, self.points[i].y))

    def getSplinePoint(self, t):
        if not self.isLooped:
            p1 = int(t) + 1
            p2 = p1 + 1
            p3 = p2 + 1
            p0 = p1 - 1
        else:
            p1 = int(t)
            p2 = (p1 + 1) % len(self.points)
            p3 = (p2 + 1) % len(self.points)
            if p1 >= 1:
                p0 = p1 - 1
            else:
                p0 = len(self.points) - 1

        t = t - int(t)
        tSquare = t * t
        tCube = tSquare * t

        q1 = -tCube + 2 * tSquare - t
        q2 = 3 * tCube - 5 * tSquare + 2
        q3 = -3 * tCube + 4 * tSquare + t
        q4 = tCube - tSquare

        tx = 0.5 * (self.points[p0].x * q1 +
                self.points[p1].x * q2 +
                self.points[p2].x * q3 +
                self.points[p3].x * q4)

        ty = 0.5 * (self.points[p0].y * q1 +
                self.points[p1].y * q2 +
                self.points[p2].y * q3 +
                self.points[p3].y * q4)

        return Spline_Point2D(tx, ty)

    def getSplineGradient(self, t):
        if not self.isLooped:
            p1 = int(t) + 1
            p2 = p1 + 1
            p3 = p2 + 1
            p0 = p1 - 1

        else:
            p1 = int(t)
            p2 = (p1 + 1) % len(self.points)
            p3 = (p2 + 1) % len(self.points)
            if p1 >= 1:
                p0 = p1 - 1
            else:
                p0 = len(self.points) - 1

        t = t - int(t)

        tSquare = t * t
        tCube = tSquare * t

        q1 = -3*tSquare + 4*t - 1
        q2 = 9*tSquare - 10*t
        q3 = -9*tSquare + 8*t + 1
        q4 = 3*tSquare - 2*t

        tx = 0.5 * (self.points[p0].x * q1 +
                self.points[p1].x * q2 +
                self.points[p2].x * q3 +
                self.points[p3].x * q4)

        ty = 0.5 * (self.points[p0].y * q1 +
                self.points[p1].y * q2 +
                self.points[p2].y * q3 +
                self.points[p3].y * q4)

        return Spline_Point2D(tx, ty)

    def __getTotalLength(self):
        ### CALCULATE TOTAL LENGTH ###
        total = 0
        if self.isLooped:
            for i in range(len(self.points)):
                self.points[i].length = self.__calculateSegmentLength(i)
                total += self.points[i].length
        else:
            for i in range(len(self.points)-3):
                self.points[i].length = self.__calculateSegmentLength(i)
                total += self.points[i].length
        return total

    def __calculateSegmentLength(self, node):
        fLength = 0
        fStepSize = 3
        old_point = self.getSplinePoint(node)
        for t in range(0, 100, fStepSize):
            new_point = self.getSplinePoint(node + t/100)
            fLength += math.sqrt((new_point.x - old_point.x) * (new_point.x - old_point.x)
                                + (new_point.y - old_point.y)*(new_point.y - old_point.y))
            old_point = new_point

        ### You need to recalculate the segment lengths if the spline changes.
        # which means its very innefficient to use splines dynamically. Preferrably
        # you use them Statically.

        return fLength

    def getNormalizedOffset(self, p):
        # Which node is the base?
        i = 0
        while p > self.points[i].length:
            p -= self.points[i].length
            i += 1

        # The fractional is the offset
        return i + (p / self.points[i].length)


'''
經典題型，由於羅馬字母原則上是由大至小排列，故若是發現某一數字大於先前的數字，則代表大 - 小 (e.g., XV = 4)
故作答上只需使用一個迴圈由左掃至右，判斷一下目前的羅罵字與上一個的大小關係，若發現小的字母在大的字母左側，則記得要減去2倍的先前字母值
(不是挺好解釋的，詳情見程式碼)
'''

class Solution:
    def eval_roman(self, symbol):
        answer = 0
        if('I' == symbol):
            answer = 1
        elif('V' == symbol):
            answer = 5
        elif('X' == symbol):
            answer = 10
        elif('L' == symbol):
            answer = 50
        elif ('C' == symbol):
            answer = 100
        elif ('D' == symbol):
            answer = 500
        elif ('M' == symbol):
            answer = 1000

        return answer

    def romanToInt(self, s):
       answer, previous_val, current_val = 0, 0, 0
       for i in s:
           current_val = self.eval_roman(i)
           answer = answer + current_val

           if(current_val > previous_val):
               answer = answer - 2 * previous_val

           previous_val = current_val

       return answer

# 本機端測試用
# sol = Solution()
# print(sol.romanToInt("MCMXCIV"))
# print(sol.romanToInt("XII"))
# print(sol.romanToInt("IV"))
# print(sol.romanToInt("IX"))


import pyautogui
import cv2 as cv
import numpy as np
import keyboard
import time
from math import sqrt
from PIL import ImageGrab
import win32api, win32con

# https://stackoverflow.com/questions/5906693/how-to-reduce-the-number-of-colors-in-an-image-with-opencv
def kmeans_color_quantization(image, clusters=8, rounds=1):
    h, w = image.shape[:2]
    samples = np.zeros([h*w,3], dtype=np.float32)
    count = 0

    for x in range(h):
        for y in range(w):
            samples[count] = image[x][y]
            count += 1

    compactness, labels, centers = cv.kmeans(samples,
            clusters,
            None,
            (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10000, 0.0001),
            rounds,
            cv.KMEANS_RANDOM_CENTERS)

    centers = np.uint8(centers)
    res = centers[labels.flatten()]
    return res.reshape((image.shape))

class GarticBot:

    def __init__(self, DEBUG=False):
        self.debug = DEBUG

    BOARD_ORIGIN = (692, 170)
    BOARD_RESOLUTION = (962, 530)
    PENCIL = (-150, 25)
    PENCIL_SLIDER = (-147, 772)
    PENCIL_SLIDER_MIN_RANGE = (790, 665)

    PALLETE = (-100, 570)

    # DRAWING_RESOLUTION = (120, 66)
    # DRAWING_RESOLUTION = (150, 82)
    DRAWING_RESOLUTION = (200, 110)
    COLOR_VARIANCE = 128
    WHITE_THRESHOLD = 55
    CLICK_DELAY = 1e-10
    CLICK_DELAY_INTERVAL = 5
    pyautogui.PAUSE = CLICK_DELAY

    def _getRelativePos(self, pos):
        return (pos[0] + self.BOARD_ORIGIN[0], pos[1] + self.BOARD_ORIGIN[1])

    def _downScale(self, image):
        f1 = self.DRAWING_RESOLUTION[0] / image.shape[1]
        f2 = self.DRAWING_RESOLUTION[1] / image.shape[0]
        dim = (int(image.shape[1] * min(f1, f2)), int(image.shape[0] * min(f1, f2)))
        resized = cv.resize(image, dim)

        downscaled = kmeans_color_quantization(resized, clusters=self.COLOR_VARIANCE, rounds=1)

        if self.debug:
            cv.imshow("IMAGE", cv.resize(image, (600, int(image.shape[0]*600/image.shape[1])), interpolation=cv.INTER_AREA))
            cv.waitKey(600)
            cv.imshow("IMAGE", cv.resize(resized, (600, int(resized.shape[0]*600/resized.shape[1])), interpolation=cv.INTER_AREA))
            cv.waitKey(600)
            cv.imshow("IMAGE", cv.resize(downscaled, (600, int(downscaled.shape[0]*600/downscaled.shape[1])), interpolation=cv.INTER_AREA))
            cv.waitKey(600)
            cv.destroyAllWindows()

        return downscaled

    def _getColorClusters(self, image):
        image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
        clusters = {}
        for j in range(len(image)):
            for i in range(len(image[0])):
                color = f"{image[j][i][0]},{image[j][i][1]},{image[j][i][2]}"
                if color in clusters:
                    clusters[color].append((i, j))
                else:
                    clusters.update({color: [(i, j)]})
        return clusters

    def _equipPencil(self):
        pyautogui.click(self._getRelativePos(self.PENCIL))

    def _setColor(self, color):
        pyautogui.click(self._getRelativePos(self.PALLETE))
        time.sleep(0.1)
        color = color.split(",")
        keyboard.send('tab')
        time.sleep(0.01)
        keyboard.send('tab')
        time.sleep(0.01)
        keyboard.send('tab')
        time.sleep(0.01)
        keyboard.write(color[0])
        time.sleep(0.01)
        keyboard.send('tab')
        time.sleep(0.01)
        keyboard.write(color[1])
        time.sleep(0.01)
        keyboard.send('tab')
        time.sleep(0.01)
        keyboard.write(color[2])
        time.sleep(0.01)
        keyboard.send('enter')
        time.sleep(0.1)

    def _getClickPosition(self, pos):
        upscale_factor_x = self.BOARD_RESOLUTION[0] / self.DRAWING_RESOLUTION[0]
        upscale_factor_y = self.BOARD_RESOLUTION[1] / self.DRAWING_RESOLUTION[1]
        pos = (int(pos[0]*upscale_factor_x), int(pos[1]*upscale_factor_y))
        return pos

    def _setPencilThickness(self, thickness):
        pyautogui.moveTo(self._getRelativePos(self.PENCIL_SLIDER))

    def draw(self, image):
        print("DOWNSCALING")
        downscaled = self._downScale(image)
        clusters = self._getColorClusters(downscaled)
        while True:
            if keyboard.is_pressed('alt+s'):
                print("STOPPING")
                return
            if keyboard.is_pressed('alt+q'):
                quit()
            if keyboard.is_pressed('alt+d'):
                break
        time.sleep(0.2)
        print("DRAWING")
        self._equipPencil()

        for color in clusters:
            channels = color.split(",")
            dist = sqrt(pow(int(channels[0])-255, 2) + pow(int(channels[1])-255, 2) + pow(int(channels[2])-255, 2))
            if dist < self.WHITE_THRESHOLD:
                continue
            print(f'Color: {color}')
            self._setColor(color)
            for i, pixel in enumerate(clusters[color]):
                pos = self._getClickPosition(pixel)
                pos = self._getRelativePos(pos)

                win32api.mouse_event(win32con.MOUSEEVENTF_MOVE | win32con.MOUSEEVENTF_ABSOLUTE, int(pos[0]/win32api.GetSystemMetrics(0)*65535), int(pos[1]/win32api.GetSystemMetrics(1)*65535) ,0 ,0)
                win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
                win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
                if i%self.CLICK_DELAY_INTERVAL==0: time.sleep(self.CLICK_DELAY)

                if keyboard.is_pressed('alt+s'):
                    print("STOPED")
                    return
        print("DONE")
    def run(self):
        while True:
            if keyboard.is_pressed('alt+q'):
                break
            if keyboard.is_pressed('alt+c'):
                image = np.array(ImageGrab.grabclipboard())[:,:,:3]
                image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
                self.draw(image)

bot = GarticBot(DEBUG=True)
bot.run()


#! /usr/bin/python

def solutionOneChecker(combinedLetters: str, testWord: str, dictWordScores: dict) -> bool:
    """
    Check if a word uses all letters of the box
    True = Valid Solution
    """

    fullScore = len(combinedLetters)
    #fullScore = 7

    if dictWordScores[testWord] > fullScore:
        return True
    return False

def topScoringWords(combinedLetters: str, dictWordScores: dict) -> bool:
    """
    Prints the top scoring words above or equal to 8 points
    """

    fullScore = len(combinedLetters)
    for iScore in range(fullScore, 7, -1):
        for iWord in dictWordScores:
            if dictWordScores[iWord] == iScore:
                print(iWord, iScore)

    return True

def run():
    return None

if __name__ == "__main__":
    run()


import tensorflow as tf

# Defince a "Computation Graph"
a = tf.constant(1)  # Defince a constant Tensor
b = tf.constant(1)
c = a + b  # Equal to c = tf.add(a, b)，c is a new Tensor created by Tensor a and Tesor b's add Operation

sess = tf.Session()     # Initailize a Session
c_ = sess.run(c)        # Session的run() will do actually computation to the nodes (Tensor) in the Computation Graph
print(c_)


from sqlalchemy import Column, Integer, String, ForeignKey
from app.routers.db import Base

class Task(Base):
    __tablename__ = 'tasks'

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String)
    body = Column(String)


from abc import ABC
from collections import OrderedDict, defaultdict

import torch
import torch.nn.functional as F
from torch import flatten
from torch.nn import Module, Conv2d, Dropout, Linear, BatchNorm2d, ReLU, Sequential, MaxPool2d
from torch.optim import Optimizer
from torch.optim.lr_scheduler import LRScheduler
from torch.utils.data import DataLoader
from tqdm.auto import tqdm

class AbstractModule(Module, ABC):  # TODO check that it's abstract
    def __init__(self):
        super().__init__()

        self._optim = None
        self._criterion = None
        self._scheduler = None
        self._pruner = None

    def optimizer(self, optim: callable(Optimizer), **kwargs):
        self._optim = optim(self.parameters(), **kwargs)
        return self

    def scheduler(self, scheduler: callable(LRScheduler), **kwargs):
        self._scheduler = scheduler(self._optim, **kwargs)
        return self

    def criterion(self, criterion: Module):
        self._criterion = criterion
        return self

    def fit(self,
            dataloader: DataLoader,
            epochs: int,
            callbacks=None
            ) -> None:
        device = 'cuda' if torch.cuda.is_available() else 'cpu'
        model = self.to(device).train()

        for epoch in range(1, epochs + 1):
            loader_bar = tqdm(dataloader, desc='train', leave=False)
            for inputs, targets in loader_bar:
                inputs = inputs.to(device)
                targets = targets.to(device)

                # Reset the gradients (from the last iteration)
                self._optim.zero_grad()

                outputs = model(inputs)
                loss = self._criterion(outputs, targets)

                loss.backward()
                self._optim.step()

                if callbacks is not None:
                    for callback in callbacks:
                        callback()

                loader_bar.set_description(f"Epoch [{epoch}/{epochs}]")

            if self._scheduler is not None:
                self._scheduler.step()

    @torch.inference_mode()
    def evaluate(self,
                 dataloader: DataLoader,
                 verbose=True,
                 ) -> float:
        device = 'cuda' if torch.cuda.is_available() else 'cpu'
        model = self.to(device).eval()

        num_samples = 0
        num_correct = 0

        for inputs, targets in tqdm(dataloader, desc="eval", leave=False, disable=not verbose):
            inputs = inputs.to(device)
            targets = targets.to(device)

            outputs = model(inputs)
            outputs = outputs.argmax(dim=1)

            # Update metrics
            num_samples += targets.size(0)
            num_correct += (outputs == targets).sum()

        return (num_correct / num_samples * 100).item()

class BaseLineNet(AbstractModule):
    def __init__(self):
        super().__init__()
        self.conv1 = Conv2d(1, 32, 3, 1)  # 1 x 32 x 3 x 3 = 288 parameters
        self.conv2 = Conv2d(32, 64, 3, 1)  # 32 x 64 x 3 x 3=18,432 parameters
        self.dropout1 = Dropout(0.25)
        self.dropout2 = Dropout(0.5)
        self.fc1 = Linear(9216, 128)  # 9216 x 128 = 1,179,648 parameters
        self.fc2 = Linear(128, 10)  # 128 x 10 = 1,280 parameters

    def forward(self, x):
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = F.max_pool2d(x, 2)
        x = self.dropout1(x)
        x = flatten(x, 1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.dropout2(x)
        x = self.fc2(x)
        output = F.log_softmax(x, dim=1)
        return output

class VGG(AbstractModule):
    ARCH = [64, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M']

    def __init__(self) -> None:
        super().__init__()

        layers = []
        counts = defaultdict(int)

        def add(name: str, layer: Module) -> None:
            layers.append((f"{name}{counts[name]}", layer))
            counts[name] += 1

        in_channels = 3
        for x in self.ARCH:
            if x != 'M':
                # conv-bn-relu
                add("conv", Conv2d(in_channels, x, 3, padding=1, bias=False))
                add("bn", BatchNorm2d(x))
                add("relu", ReLU(True))
                in_channels = x
            else:
                add("pool", MaxPool2d(2))

        self.backbone = Sequential(OrderedDict(layers))
        self.classifier = Linear(512, 10)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        # backbone: [N, 3, 32, 32] => [N, 512, 2, 2]
        x = self.backbone(x)

        # avgpool: [N, 512, 2, 2] => [N, 512]
        x = x.mean([2, 3])

        # classifier: [N, 512] => [N, 10]
        x = self.classifier(x)
        return x


""" JAX functions to Calculate moving average.
Author: Toshinori Kitamura
Affiliation: NAIST & OSX
"""
from __future__ import annotations

import jax
from chex import Array
from jax import lax

@jax.jit
def calc_ma(lr: float, idx1: Array, idx2: Array, tb: Array, tb_targ: Array) -> Array:
    """Calculate moving average.
    The semantics of calc_ma are given by:
        def calc_ma(lr, idx1, idx2, tb, tb_targ):
            for s, a, targ in zip(idx1, idx2, tb_targ):
                tb[s, a] = (1 - lr) * tb[s, a] + lr * targ
            return tb
    Args:
        lr (float): Learning rate
        idx1 (Array): (?, ) or (?, 1) array
        idx2 (Array): (?, ) or (?, 1) array
        tb (Array): (?, ?) initial array
        tb_targ (Array): (?, ) or (?, 1) target array

    Returns:
        tb (Array): (?, ) array
    """
    assert len(tb.shape) == 2  # dSxdA
    idx1 = idx1.squeeze(axis=1) if len(idx1) == 2 else idx1
    idx2 = idx2.squeeze(axis=1) if len(idx2) == 2 else idx2
    tb_targ = tb_targ.squeeze(axis=1) if len(tb_targ) == 2 else tb_targ

    def body_fn(i, tb):
        i1, i2, t = idx1[i], idx2[i], tb_targ[i]
        targ = (1 - lr) * tb[i1, i2] + lr * t
        return tb.at[i1, i2].set(targ)

    tb = lax.fori_loop(0, len(idx1), body_fn, tb)
    return tb


from bs4 import BeautifulSoup
import requests
import requests.packages.urllib3

requests.packages.urllib3.disable_warnings()

fx=open('WEB.txt','r',encoding="utf-8") ## FILENAME me file ka name dalna
line=fx.readline()
l=open('email_mailto.txt','a',encoding='utf-8')

def web_imrove(url):
    print(url)

    try:
        source = requests.get(url)
    except Exception :
        l.write('\n')
        return 0

    plain_text = source.text
    soup = BeautifulSoup(plain_text, 'html.parser')
    emails = [a["href"] for a in soup.select('a[href^=mailto:]')]
    popo = str(emails)
    toto = popo.replace('mailto:', '')
    hoho = toto.replace('[', '')
    gogo = hoho.replace(']', '')
    mm = gogo.replace("'", "")
    if len(mm) is not 0:
        l.write(mm)
        l.write('\n')
        print(mm)
        return 1
    else:
        l.write('\n')
        return 0
        #print(mm)

while line:
    if line is '\n':
        l.write('\n')
        line=fx.readline()
        continue
    p = line.strip()

    if(  web_imrove('http://'+p) ):
        print('first')
    elif(  web_imrove('http://' + p+'/contact-us') ):
        print('second')
    else:
        web_imrove('http://' + p+'/contactus')

    line = fx.readline()


from datetime import datetime

#convert date from YYYY-MM-DD-T to Date, Month, Year (in words)
#dfdsf
#dsfds
datetime
def date_convert(date):
    date=str(date)
    data=date.split('-') #year/month/day+time all separated by dash
    daydate=data[-1].split() #data[-1] is day+time, separated by a space
    day=daydate[0] #discard time, keep day
    day=day if day[0]!=0 else day[1] #otherwise single-digit days retain leading zero
    year=str(data[0]) #data is list containing the year and the month
    month=str(data[1])
    #map month numbers to their names
    months={'01':'January',
            '02':'February',
            '03':'March',
            '04':'April',
            '05':'May',
            '06':'June',
            '07':'July',
            '08':'August',
            '09':'September',
            '10':'October',
            '11':'November',
            '12':'December'}
    #adds appropriate suffix to day
    if day[-1]=='1' and int(day)%100!=11: #checks if date ends with 1 and isn't 11
        suffix='st'
    elif day[-1]=='2' and int(day)%100!=12: #checks if date ends with 1 and isn't 11
        suffix='nd'
    elif day[-1]=='3':
        suffix='rd'
    else:
        suffix='th' #including special cases 11 and 12 which were previously excluded
    return day+suffix+' '+months[month]+', '+year #returns string with date in appropriate format

#test case
#date=datetime.now()
#print date_convert(date)


from pytube import YouTube
from PySimpleGUI import PySimpleGUI as sg

sg.theme("reddit")
layout = [
    [sg.Text("URL"), sg.Input(key="url")],
    [sg.Button("Fazer o Download")]
],

janela = sg.Window("Video Downloader", layout)

while True:
    eventos, valores = janela.read()
    if eventos == sg.WINDOW_CLOSED:
            break
    if eventos == "Fazer o Download":
        link = valores["url"]
        yt = YouTube(link)
        stream = yt.streams.get_highest_resolution()
        stream.download()


from flask import Flask
from flask_restful import Resource, Api

import __init__

app=Flask(__name__)
api=Api(app)

class Quote(Resource):

    @app.route('/wifi/<int:id>')
    def get(id):
        x=main.main_(id)
        if x==-1:
            return 'Not found', 404
        else:
            return x, 200

    @app.route('/trace')
    def trace():
        x=main.output()
        return x, 200

if __name__ == '__main__':

    app.run(host="0.0.0.0", port="8080",debug=True)


"""
a pure python implementation of the heap sort algorithm
"""

def m_heap_sort(arr):
    """heap sort

    :type arr: array
    :rtype: array

    >>> m_heap_sort([3, 2, 1, 4, 5])
    [1, 2, 3, 4, 5]
    >>> m_heap_sort([])
    []
    >>> m_heap_sort([1])
    [1]
    """
    n = len(arr)
    for i in range(n//2 - 1, -1, -1):
        heapify(arr, n, i)
    for i in range(n-1, -1, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)
    return arr

def heapify(arr, n, i):
    """get max heap

    :type arr: array
    :type n: int, length
    :type i: index, subtree root
    :rtype: None

    """
    largest = i
    left = 2*i + 1
    right = 2*i + 2
    if left < n and arr[left] > arr[largest]:
        largest = left
    if right < n and arr[right] > arr[largest]:
        largest = right
    if largest != i:
        arr[largest], arr[i] = arr[i], arr[largest]
        heapify(arr, n, largest)


# Calculate how long it takes to save enough money make a down payment on a house

def app():
    # INPUTS
    annual_salary = float(input("Enter your annual salary: "))
    portion_saved = float(input("Enter the percent of your salary to save, as a decimal: "))
    total_cost = int(input("Enter the cost of your dream home: "))
    portion_down_payment = 0.25

    current_savings = 0

    r = 0.04
    # bonus = current_savings*r/12

    monthly_salary = (annual_salary/12)

    goal = (total_cost * portion_down_payment)

    months = 0
    while (current_savings <= goal):
        current_savings += current_savings*r/12
        current_savings += (monthly_salary * portion_saved)

        months += 1

    print(months)

if __name__ == "__main__":
    app()


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

#-----------
#@utool.indent_func('[harn]')
@profile
def test_configurations(ibs, acfgstr_name_list, test_cfg_name_list):
    r"""
    Test harness driver function

    CommandLine:
        python -m ibeis.expt.harness --exec-test_configurations --verbtd
        python -m ibeis.expt.harness --exec-test_configurations --verbtd --draw-rank-cdf --show

    Example:
        >>> # SLOW_DOCTEST
        >>> from ibeis.expt.harness import *  # NOQA
        >>> import ibeis
        >>> ibs = ibeis.opendb('PZ_MTEST')
        >>> acfgstr_name_list = ut.get_argval(('--aidcfg', '--acfg', '-a'), type_=list, default=['candidacy:qsize=20,dper_name=1,dsize=10', 'candidacy:qsize=20,dper_name=10,dsize=100'])
        >>> test_cfg_name_list = ut.get_argval('-t', type_=list, default=['custom', 'custom:fg_on=False'])
        >>> test_configurations(ibs, acfgstr_name_list, test_cfg_name_list)
        >>> ut.show_if_requested()
    """

    testres_list = run_test_configurations2(ibs, acfgstr_name_list, test_cfg_name_list)

    for testres in testres_list:
        if testres is None:
            return
        else:
            experiment_printres.print_results(ibs, testres)
            experiment_drawing.draw_results(ibs, testres)
    return testres_list

#def get_cmdline_testres():
#    ibs, qaids, daids = main_helpers.testdata_expanded_aids(verbose=False)
#    test_cfg_name_list = ut.get_argval('-t', type_=list, default=['custom', 'custom:fg_on=False'])
#    testres = run_test_configurations(ibs, qaids, daids, test_cfg_name_list)
#    return ibs, testres


from django.shortcuts import render, redirect
from django.views.generic import ListView, \
    CreateView, DetailView, UpdateView, DeleteView
from .models import Post, Review
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from accounts.models import UserFollows

from .forms import PostForm, ReviewForm
from django.template.defaulttags import register
from django.contrib import messages

@register.filter
# helps us loop over the review's rating and
# add stars for the range of the int variable; rating
def get_range(value):
    return range(value)

def flow(request):
    following = UserFollows.objects.filter(following=request.user)
    follower = UserFollows.objects.filter(follower=request.user)
    posts = []
    reviews = []
    for post in Post.objects.all().order_by('-date_posted'):
        posts.append(post)
    for review in Review.objects.all().order_by('-date_posted'):
        reviews.append(review)

    posts_reviews = []

    for post in posts:
        if post.author == request.user:
            posts_reviews.append(post)
            print(post)
        for contact in follower:
            if post.author == contact.following:
                posts_reviews.append(post)
    for review in reviews:
        if review.author == request.user:
            posts_reviews.append(review)
        for contact in follower:
            if review.author == contact.following:
                posts_reviews.append(review)
        if review.ticket.author == request.user:
            posts_reviews.append(review)

    posts_reviews = list(set(posts_reviews))
    posts_reviews.sort(key=lambda x: x.date_posted, reverse=True)
    for p in posts_reviews:
        print(p.type)

    context = {
        'follower': follower,
        'following': following,
        'post_review': posts_reviews
    }

    return render(request, 'flow.html', context)

class ReviewCreateView(LoginRequiredMixin, CreateView):
    model = Review
    fields = ['ticket', 'headline', 'rating', 'content', ]

    def form_valid(self, form):
        form.instance.author = self.request.user
        try:
            return super().form_valid(form)
        except ValueError:
            messages.add_message(self.request, messages.INFO, 'Hello world.')

class ReviewDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    model = Review
    success_url = '/'

    def test_func(self):
        post = self.get_object()
        if self.request.user == post.author:
            return True
        else:
            return False

class PostCreateView(LoginRequiredMixin, CreateView):
    model = Post
    fields = ['title', 'content', 'header_image']

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)

class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Post
    fields = ['title', 'content', 'header_image']

    def form_valid(self, form):
        form.instance.author = self.request.user
        self.object = form.save()
        return super().form_valid(form)

    def test_func(self):
        post = self.get_object()
        if self.request.user == post.author:
            return True
        else:
            return False

class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    model = Post
    success_url = '/'

    def test_func(self):
        post = self.get_object()
        if self.request.user == post.author:
            return True
        else:
            return False

class PostListView(ListView):
    model = Post
    context_object_name = 'posts'
    ordering = ['-date_posted']

class ReviewListView(ListView):
    model = Review
    context_object_name = 'reviews'
    ordering = ['-date_posted']

class PostDetailView(DetailView):
    model = Post

class ReviewDetailView(DetailView):
    model = Review

class ReviewUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Review
    fields = ['headline', 'body', 'rating']

    def form_valid(self, form):
        form.instance.author = self.request.user
        self.object = form.save()
        return super().form_valid(form)

    def test_func(self):
        post = self.get_object()
        if self.request.user == post.author:
            return True
        else:
            return False

def review_create_view(request):
    form2 = PostForm(request.POST, request.FILES or None)
    form = ReviewForm(request.POST or None)

    context = {

        "form2": form2,
        "form": form,
    }
    if all([form2.is_valid(), form.is_valid()]):
        current_user = request.user
        parent = form2.save(commit=False)
        parent.author_id = current_user.id
        parent.reviewed = 'true'
        parent.save()
        child = form.save(commit=False)
        child.author_id = current_user.id
        child.ticket = parent
        child.save()
        print("form", form.cleaned_data)
        print("form2", form2.cleaned_data)
        context['message'] = 'data saved'

        return redirect('flow')
        # return render(request, 'reviews/review_create.html', context)
    else:
        return render(request, 'reviews/review_create.html', context)

def review_of_ticket(request, pk):

    instance = Post.objects.get(id=pk)
    form = ReviewForm(request.POST or None)
    review_form_ticket = instance
    context = {
        "form": form,
        "ticket": review_form_ticket,
    }
    if form.is_valid():
        current_user = request.user
        child = form.save(commit=False)
        child.author_id = current_user.id
        child.ticket = instance
        instance.reviewed = 'true'
        child.save()
        instance.save()
        form.save()
        return redirect('flow')
    else:

        return render(request, "website/review_form.html", context,)

def view_tickets_reviews(request):
    object1 = Post.objects.filter(author=request.user).order_by('-date_posted')
    object2 = Review.objects.filter(
        author=request.user).order_by('-date_posted')

    context = {
        'object1': object1,
        'object2': object2,
    }

    return render(request, "website/review_post_detail.html", context)


import argparse
from math import sqrt
import Image
import ImageDraw

def color_map(v):
    assert 0 <= v <= 255
    if v == 0: return (0, 0, 0)
    if v == 255: return (255, 255, 255)
    if v < 4 * 8:
        # 0 .. 31
        return (0, 255 - (31 * 4) + v * 4, 0)
    if v < 16 * 8:
        # 32 .. 127
        # 0 .. 95
        return (128 + (v - 32) * 127 / 95, 0, 0)

    return (0, v, v)

def convert():
    if args.test:
        data = map(chr, range(256))
    else:
        data = file(args.in_file).read()

    size = len(data)
    w = 1
    while size / w > w * 8:
        w *= 2

    h = size / w
    if size % w != 0: h += 1

    image = Image.new('RGB', (w, h))
    d = ImageDraw.Draw(image)
    for i, c in enumerate(data):
        d.point((i % w, i / w), color_map(ord(c)))
    image.save(args.out_file, 'PNG')

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Show binary in color pattern')
    parser.add_argument('--test', action='store_true')
    parser.add_argument('in_file', action='store')
    parser.add_argument('--out_file', action='store', default='out.png')
    args = parser.parse_args()
    convert()


import filecmp, os, sys
sys.path.append('c:\\dev\\pytWinc\\superpy')
sys.path.append('c:\\dev\\pytWinc\\superpy\\utils_superpy')
from utils.utils import calculate_inventory, get_path_to_directory_of_file

directory_of_testcase = "fn_calculate_inventory"
path_to_directory_of_testcase = get_path_to_directory_of_file(directory_of_testcase)

# input test files:
path_to_input_file_sold_test_01 = os.path.join(path_to_directory_of_testcase, "test_input", 'input_file_sold_for_testcase_01.csv')
path_to_input_file_cost_test_01 = os.path.join(path_to_directory_of_testcase, "test_input", 'input_file_cost_for_testcase_01.csv')

path_to_input_file_sold_test_02 = os.path.join(path_to_directory_of_testcase, "test_input", 'input_file_sold_for_testcase_02.csv')
path_to_input_file_cost_test_02 = os.path.join(path_to_directory_of_testcase, "test_input", 'input_file_cost_for_testcase_02.csv')

'''
about the data structure of expected testresult:
list of lists is a common and convenient (but not the only) way to create tables in Python.
This also applies to Rich.

So expected test results take the shape of a list with lists. This has worked
while testing fn calculate_expired_products_on_day.
'''

def test_01_calculate_inventory_happy_flow():
    filecmp.clear_cache()
    date_on_which_to_calculate_inventory = '2024-05-21'
    expected_test_result = [['b_3', 'candle', '3.1', '2024-01-11', 'does not expire'], ['b_6', 'book', '0.5', '2024-01-15', 'does not expire'], ['b_39', 'skeelers', '1.1', '2024-04-20', 'does not expire'], ['b_45', 'shoes', '1.4', '2024-04-30', 'does not expire'], ['b_48', 'fish', '2.5', '2024-05-08', '2024-05-23'], ['b_51', 'kiwi', '0.5', '2024-05-15', '2024-05-30'], ['b_54', 'onion', '1.1', '2024-05-21', '2024-06-05']]
    actual_result = calculate_inventory(date_on_which_to_calculate_inventory, path_to_input_file_sold_test_01,
    path_to_input_file_cost_test_01)
    assert actual_result == expected_test_result

def test_02_calculate_inventory_happy_flow():
    filecmp.clear_cache()
    date_on_which_to_calculate_inventory = '2023-11-15'
    expected_test_result = [['b_6', 'garbage_bag', '5.2', '2023-10-17', 'does not expire'], ['b_26', 'tomato', '2.5', '2023-10-31', '2023-11-15'], ['b_28', 'lettuce', '0.5', '2023-11-01', '2023-11-16'], ['b_30', 'lettuce', '4.0', '2023-11-02', '2023-11-17'], ['b_32', 'tomato', '5.2', '2023-11-03', '2023-11-18'], ['b_34', 'lightbulb', '4.0', '2023-11-06', 'does not expire'], ['b_36', 'tomato', '4.0', '2023-11-07', '2023-11-22'], ['b_38', 'rice', '0.5', '2023-11-08', '2023-11-23'], ['b_40', 'cheese', '1.4', '2023-11-09', '2023-11-24'], ['b_42', 'book', '5.2', '2023-11-11', 'does not expire'],
    ['b_44', 'oats', '0.5', '2023-11-14', '2023-11-29']]
    actual_result = calculate_inventory(date_on_which_to_calculate_inventory, path_to_input_file_sold_test_02,
    path_to_input_file_cost_test_02)
    assert actual_result == expected_test_result


class odds_compare:

    def __init__(self, api_array):
        self.api_array = api_array

    # calculate odds comparisons for all available matches
    def calculate_comparisons(self):
        result = []

        for i in self.api_array:
            result_dict = {
                "home": "",
                "away": "",
                "home_odds": [],
                "away_odds": []
            }

            result_dict['home'] = i['home_team']
            result_dict['away'] = [x for x in i['teams'] if x != i['home_team']][0]

            home_odds = []
            away_odds = []
            # return all odds
            for book in i['sites']:
                if result_dict['home'] == i['teams'][0]:
                    home_odds.append((book['site_nice'], book['odds']['h2h'][0]))
                    away_odds.append((book['site_nice'], book['odds']['h2h'][1]))
                else:
                    home_odds.append((book['site_nice'], book['odds']['h2h'][1]))
                    away_odds.append((book['site_nice'], book['odds']['h2h'][0]))

            result_dict['home_odds'] = sorted(home_odds, key=lambda tup: tup[1], reverse=True)
            result_dict['away_odds'] = sorted(away_odds, key=lambda tup: tup[1], reverse=True)

            result.append(result_dict)

        return result

    # calculate odds comparisons for a specific team
    def calculate_comparisons_team(self, team):
        # print(self.api_array)
        result = {
            "home": "",
            "away": "",
            "home_odds": [],
            "away_odds": []
        }

        # look for particular match
        for i in self.api_array:
            if team in i['teams']:
                home_odds = []
                away_odds = []
                # return all odds
                for book in i['sites']:
                    # print(book['site_nice']+ " - " +str(book['odds']['h2h']))
                    home_odds.append((book['site_nice'], book['odds']['h2h'][0]))
                    away_odds.append((book['site_nice'], book['odds']['h2h'][1]))

                result['home_odds'] = sorted(home_odds, key=lambda tup: tup[1], reverse=True)
                result['away_odds'] = sorted(away_odds, key=lambda tup: tup[1], reverse=True)

                result['home'] = i['home_team']
                result['away'] = [x for x in i['teams'] if x != i['home_team']][0]

                break   # only want first game with selected team from API

        return result


# VIIRS packge

from __future__ import division, print_function

import datetime
import numpy as np
from osgeo import gdal
from scipy import ndimage

import core
import env

bumper = env.environment()

class viirs(core.raster):

    def __init__(self):
        core.raster.__init__(self,'viirs')

        return

    def read(self,infile):

        out = self._copy()

        tree = '//HDFEOS/GRIDS/VNP_Grid_{}_2D/Data_Fields/'
        field = 'SurfReflect_{0}{1}_1'
        base = 'HDF5:"{0}":{1}{2}'

        m = [i for i in range(12) if i not in [0,6,9]]
        i = [i for i in range(1,4)]
        bands = [m,i]

        res = ['1km','500m']
        mode = ['M','I']

        band = gdal.Open(base.format(infile,tree.format('1km'),field.format('QF',1)))
        out.metadata = band.GetMetadata()
        cloudQA = self._extractBits(band.ReadAsArray(),2,3)
        hiresCloudQA = ndimage.zoom(cloudQA,2,order=0)
        band = None

        band = gdal.Open(base.format(infile,tree.format('1km'),field.format('QF',2)))
        shadowQA = self._extractBits(band.ReadAsArray(),3,3)
        hiresShadowQA = ndimage.zoom(shadowQA,2,order=0)

        # qa = (cloudQA>0)&(shadowQA<1)
        mask = ~(hiresCloudQA>0)&(hiresShadowQA<1)

        east,west = float(out.metadata['EastBoundingCoord']), float(out.metadata['WestBoundingCoord'])
        north,south = float(out.metadata['NorthBoundingCoord']), float(out.metadata['SouthBoundingCoord'])

        out.extent = [west,south,east,north]

        databands = {'mask':mask}

        bandNames = ['mask']

        for i in range(2):
            for j in range(len(bands[i])):

                subdataset = base.format(infile,tree.format(res[i]),field.format(mode[i],bands[i][j]))

                band = gdal.Open(subdataset)
                if i == 0:
                    data = ndimage.zoom(band.ReadAsArray(),2,order=0)
                else:
                    data = band.ReadAsArray()

                data = np.ma.masked_where(data<0,data)
                data = np.ma.masked_where(data>10000,data)

                bName = '{0}{1}'.format(mode[i],bands[i][j])
                databands[bName] = data.astype(np.int16)
                bandNames.append(bName)

                band = None
                data = None

        out.bands = databands
        out.bandNames = bandNames

        out.updateMask()

        coords = {}

        out.nativeCRS = {'init':'epsg:6974'}
        out.proj = '+proj=sinu +R=6371007.181 +nadgrids=@null +wktext'

        coords['lon'],coords['lat'] = self._geoGrid(out.extent,out.bands['I1'].shape,out.proj,wgsBounds=False)

        out.coords = coords

        out.gt = None

        date = '{0}{1}{2}'.format(out.metadata['RangeBeginningDate'],out.metadata['RangeBeginningTime'],' UTC')

        out.coords['date'] = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S.%f %Z')

        return out


import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

class TinyImageNet:
    def __init__(self, root, train=True, transform=None, target_transform=None, test_transform=None, target_test_transform=None):
        self.transform = transform
        self.target_transform = target_transform
        self.target_test_transform = target_test_transform
        self.test_transform = test_transform
        self.TrainData = []
        self.TrainLabels = []
        self.TestData = []
        self.TestLabels = []
        if train:
            path = root + '/TinyImageNet/train/'
        else:
            path = root + '/TinyImageNet/val/'
        self.data = np.load(path + 'data.npy')
        self.targets = np.load(path + 'targets.npy')

    def concatenate(self, datas, labels):
        con_data = datas[0]
        con_label = labels[0]
        for i in range(1, len(datas)):
            con_data = np.concatenate((con_data, datas[i]), axis=0)
            con_label = np.concatenate((con_label, labels[i]), axis=0)
        con_label = np.array(con_label, dtype=np.int64)
        return con_data, con_label

    def getTestData(self, classes):
        datas, labels = [], []
        for label in range(classes[0], classes[1]):
            data = self.data[np.array(self.targets) == label]
            datas.append(data)
            labels.append(np.full((data.shape[0]), label))
        datas, labels = self.concatenate(datas, labels)
        self.TestData = datas if self.TestData == [] else np.concatenate((self.TestData, datas), axis=0)
        self.TestLabels = labels if self.TestLabels == [] else np.concatenate((self.TestLabels, labels), axis=0)
        print("the size of test set is %s" % (str(self.TestData.shape)))
        print("the size of test label is %s" % str(self.TestLabels.shape))

    def getTestData_up2now(self, classes):
        datas, labels = [], []
        for label in range(classes[0], classes[1]):
            data = self.data[np.array(self.targets) == label]
            datas.append(data)
            labels.append(np.full((data.shape[0]), label))
        datas, labels = self.concatenate(datas, labels)
        self.TestData = datas
        self.TestLabels = labels
        print("the size of test set is %s" % (str(datas.shape)))
        print("the size of test label is %s" % str(labels.shape))

    def getTrainData(self, classes):
        datas, labels = [], []
        for label in range(classes[0], classes[1]):
            data = self.data[np.array(self.targets) == label]
            datas.append(data)
            labels.append(np.full((data.shape[0]), label))
        self.TrainData, self.TrainLabels = self.concatenate(datas, labels)
        print("the size of train set is %s" % (str(self.TrainData.shape)))
        print("the size of train label is %s" % str(self.TrainLabels.shape))

    def getTrainItem(self, index):
        img, target = Image.fromarray(self.TrainData[index]), self.TrainLabels[index]
        if self.transform:
            img = self.transform(img)
        if self.target_transform:
            target = self.target_transform(target)
        return index, img, target

    def getTestItem(self, index):
        img, target = Image.fromarray(self.TestData[index]), self.TestLabels[index]
        if self.test_transform:
            img = self.test_transform(img)
        if self.target_test_transform:
            target = self.target_test_transform(target)
        return index, img, target

    def __getitem__(self, index):
        if self.TrainData != []:
            return self.getTrainItem(index)
        elif self.TestData != []:
            return self.getTestItem(index)

    def __len__(self):
        if self.TrainData != []:
            return len(self.TrainData)
        elif self.TestData != []:
            return len(self.TestData)

    def get_image_class(self, label):
        return self.data[np.array(self.targets) == label]


# 1-Escribe un programa que pida al usuario una palabra y luego imprima cada
# letra de la palabra en una línea separada

def programa():

    usuario = list(input('Ingresa una palabra: '))

    contador = 0
    while len(usuario) > contador:
        print(usuario[contador])
        contador += 1

programa()

Week-3/Ejercicios Estructuras de Datos Loops/ejercicio1.py


from datetime import datetime, timedelta
import logging
import os
import json

import pandas as pd
import requests

try:
    from .exceptions import ApexApiException
except:
    from exceptions import ApexApiException

class Apex_API:
    def __init__(self, api_key: str):
        self.api_key = api_key

        logging.basicConfig(
            level=logging.INFO,
            format="[%(levelname)s] %(asctime)s %(message)s",
            datefmt="%Y-%m-%d %I:%M:%S %p",  # this defines the date format for the (asctime) part above
            handlers=[logging.StreamHandler()],
            # this means store logs to a example.log file as well as print them to the terminal
        )
        logging.getLogger("requests").setLevel(
            logging.WARNING
        )  # get rid of https debug gahbage

    def ___iter__(self):
        logging.info("what")

    def __str__(self):
        return "Apex API Client Object"

    def __repr__(self):
        return "Apex API"

    def get_apex_player_stats(self, player: str) -> pd.DataFrame:
        try:
            data = requests.get(
                f"https://api.mozambiquehe.re/bridge?version=5&platform=PC&player={player}&auth={self.api_key}"
            )
            logging.info(
                f"Grabbing data for Player {player}, Status Code was {data.status_code}"
            )
            df = data.json()
            return df
        except BaseException as e:
            logging.error(e)
            raise ApexApiException

    def get_apex_map_rotation(self) -> pd.DataFrame:
        try:
            data = requests.get(
                f"https://api.mozambiquehe.re/maprotation?version=2&auth={self.api_key}"
            )
            logging.info(
                f"Grabbing data for current Map Rotation, Status Code was {data.status_code}"
            )
            df = data.json()

            df_current = pd.DataFrame([df["battle_royale"]["current"]])
            df_current["type"] = "current"

            df_next = pd.DataFrame([df["battle_royale"]["next"]])
            df_next["remainingSecs"] = 0
            df_next["remainingMins"] = 0
            df_next["remainingTimer"] = "00:00:00"
            df_next["type"] = "next"

            df_combo = pd.concat([df_current, df_next])
            logging.info(f"Grabbing {len(df_combo)} Records for Apex Map Rotation")

            return df_combo
        except BaseException as e:
            logging.error(e)
            raise ApexApiException


################### PRACTICAL_ EMAIL SLICING ##########################

name = input('please enter your name: ')
email = input('please enter your email: ')
name = name.strip().capitalize()

username = email[:email.index('@')]
username = username.strip().capitalize()
website = email[email.index('@') + 1:]
print(f'Hello {name} we are happy to meet you, ')
print(f'your username is {username} and your website is {website}')


"""
Get Distances of Shortest Path (Dijkstra)

edges: dict<from:int, dict<to:int, cost:number>>
"""

from heapq import heappush, heappop

def one_to_one(
        start, goal, num_vertexes, edges,
        INF=9223372036854775807, UNREACHABLE=-1):
    distances = [INF] * num_vertexes
    distances[start] = 0
    queue = [(0, start)]
    while queue:
        d, frm = heappop(queue)
        if distances[frm] < d:
            # already know shorter path
            continue
        if frm == goal:
            return d
        for to in edges[frm]:
            new_cost = distances[frm] + edges[frm][to]
            if distances[to] > new_cost:
                # found shorter path
                distances[to] = new_cost
                heappush(queue, (distances[to], to))

    return UNREACHABLE

def one_to_all(
        start, num_vertexes, edges,
        INF=9223372036854775807):

    distances = [INF] * num_vertexes
    distances[start] = 0
    queue = [(0, start)]
    while queue:
        d, frm = heappop(queue)
        if distances[frm] < d:
            # already know shorter path
            continue
        for to in edges[frm]:
            new_cost = distances[frm] + edges[frm][to]

            if distances[to] > new_cost:
                # found shorter path
                distances[to] = new_cost
                heappush(queue, (distances[to], to))
    return distances

def one_to_all_bfs(start, num_vertexes, edges, INF=9223372036854775807):
    """
    when all cost is 1, BFS is faster (ABC170E)
    """
    distances = [INF] * num_vertexes
    distances[start] = 0
    to_visit = [start]
    while to_visit:
        next_visit = []
        for frm in to_visit:
            for to in edges[frm]:
                new_cost = distances[frm] + 1
                if new_cost < distances[to]:
                    distances[to] = new_cost
                    next_visit.append(to)
        to_visit = next_visit
    return distances

# --- end of library ---

def debug(*x, msg=""):
    import sys
    print(msg, *x, file=sys.stderr)

def solve(N, M, edges):
    INF = 9223372036854775807
    ret = INF

    for start in range(N):
        distances = one_to_all(start, N, edges)
        debug(distances, msg=":distances")
        ret = min(ret, max(distances))
    return ret

def main():
    # verified https://atcoder.jp/contests/abc012/tasks/abc012_4
    N, M = map(int, input().split())
    from collections import defaultdict
    edges = defaultdict(dict)
    for _i in range(M):
        A, B, T = map(int, input().split())
        edges[A - 1][B - 1] = T
        edges[B - 1][A - 1] = T
    print(solve(N, M, edges))

# tests
T1 = """
3 2
1 2 10
2 3 10
"""
TEST_T1 = """
>>> as_input(T1)
>>> main()
10
"""

T2 = """
5 5
1 2 12
2 3 14
3 4 7
4 5 9
5 1 18
"""
TEST_T2 = """
>>> as_input(T2)
>>> main()
26
"""

T3 = """
4 6
1 2 1
2 3 1
3 4 1
4 1 1
1 3 1
4 2 1
"""
TEST_T3 = """
>>> as_input(T3)
>>> main()
1
"""

def _test():
    import doctest
    doctest.testmod()
    g = globals()
    for k in sorted(g):
        if k.startswith("TEST_"):
            print(k)
            doctest.run_docstring_examples(g[k], g, name=k)

def as_input(s):
    "use in test, use given string as input file"
    import io
    f = io.StringIO(s.strip())
    g = globals()
    g["input"] = lambda: bytes(f.readline(), "ascii")
    g["read"] = lambda: bytes(f.read(), "ascii")

if __name__ == "__main__":
    import sys
    input = sys.stdin.buffer.readline
    read = sys.stdin.buffer.read
    sys.setrecursionlimit(10 ** 6)
    if sys.argv[-1] == "-t":
        print("testing")
        _test()
        sys.exit()
    main()

# end of snippets/main.py


import ALU, I_MEM, CLK, PC, REG_BANK, D_MEM, threading
#OpCode = 0000 0000
#       Im[-1]  instr
class CONTROL_UNIT(threading.Thread):
    def __init__(self, LongRegFtoD, OpCode):

        self.OpCode = OpCode
        self.MyLongRegFtoD = LongRegFtoD

        self.ALUControl = OpCode[4:8]
        #indica si usa la Dir_B o si usa Reg[Dir_B]

        #if(type(OpCode) == str):
        self.Imm = int(OpCode[3:4],2)
        #para mux de WB
        self.MemOrRegW = int(OpCode[2:3],2)
        #MemW/WE habilita a  D_Mem para escritura
        self.MemW = int(OpCode[1:2],2)
        #RegW/WE habilita a REG_BANK para escritura
        self.RegW = int(OpCode[0:1],2)

        threading.Thread.__init__(self, target = self.setSignals, args = ())

    #cuidado con el clock
    def setSignals(self):
        while True:
            self.Imm = int(self.MyLongRegFtoD.OpCode[2:3],2)
            self.MemW = int(self.MyLongRegFtoD.OpCode[1:2],2)
            self.MemOrRegW = int(self.MyLongRegFtoD.OpCode[2:3],2)
            self.RegW = int(self.MyLongRegFtoD.OpCode[2:3],2)
            self.ALUControl = self.MyLongRegFtoD.OpCode[4:8]


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sun Nov 17 11:47:02 2019

@author: hwan - Took out relevant code from dolfin's plotting.py _plot_matplotlib code
              - To enter dolfin's own plotting code, use dl.plot(some_dolfin_object) wheresome_dolfin_object is a 3D object and an error will be thrown up
"""
import matplotlib.pyplot as plt
import dolfin.cpp as cpp

import pdb #Equivalent of keyboard in MATLAB, just add "pdb.set_trace()"

def plot_3D(obj, title, angle_1, angle_2):
    # Importing this toolkit has side effects enabling 3d support
    from mpl_toolkits.mplot3d import Axes3D  # noqa
    # Enabling the 3d toolbox requires some additional arguments
    plt.title(title)
    ax = plt.gca(projection='3d')
    ax.set_aspect('auto')
    ax.view_init(angle_1, angle_2)

    # For dolfin.function.Function, extract cpp_object
    if hasattr(obj, "cpp_object"):
        obj = obj.cpp_object()

    if isinstance(obj, cpp.function.Function):
        return my_mplot_function(ax, obj,)
    elif isinstance(obj, cpp.mesh.Mesh):
        return my_mplot_mesh(ax, obj)

def my_mplot_mesh(ax, mesh):
    tdim = mesh.topology().dim()
    gdim = mesh.geometry().dim()
    if gdim == 3 and tdim == 3:
        bmesh = cpp.mesh.BoundaryMesh(mesh, "exterior", order=False)
        my_mplot_mesh(ax, bmesh)
    elif gdim == 3 and tdim == 2:
        xy = mesh.coordinates()
        return ax.plot_trisurf(*[xy[:, i] for i in range(gdim)],
                               triangles=mesh.cells())

def my_mplot_function(ax, f):
    mesh = f.function_space().mesh()
    gdim = mesh.geometry().dim()
    C = f.compute_vertex_values(mesh)
    X = [mesh.coordinates()[:, i] for i in range(gdim)]
    return ax.scatter(*X, c=C)