import pygame
from pygame.locals import *
from audio_mixer import *
from background import *
from grid import *
from base import *
from tower import *
from projectile import *
from impact import *
from magic_effects import *
from ennemy import *
from dead_body import *
from game_mouse import *
from menu import *
from selected_object import *
from gold import *
from error_message import *
from spawning_mode import *
from utilitaries import *

#############################
## Main functions
#############################

class Game():
      def __init__(self):

            self.timestep = 0.0
            self.timer = 0.0
            self.best_score = 0.0
            self.previous_best_score = self.best_score

            self.is_running = True

            self.all_mixers = All_mixers()

            self.background = Background()

            loading_progress.value += 10

            self.grid = Grid(self)

            self.show_grid = False

            self.menu = Menu(self)

            self.selected_object = Selected_object()

            loading_progress.value += 10

            self.gold = Gold()

            self.mouse = Game_mouse()

            self.spawning_mode = Spawning_mode(self)

            self.base = Base(self)

            loading_progress.value += 10

            self.all_towers = All_towers()

            loading_progress.value += 10

            self.all_projectiles = All_projectiles()

            loading_progress.value += 10

            self.all_impacts = All_impacts()

            self.all_magic_effects = All_magic_effects(self)

            loading_progress.value += 10

            self.all_ennemies = All_ennemies()

            loading_progress.value += 10

            self.all_dead_bodies = All_dead_bodies()

            loading_progress.value += 10

            self.all_gold_anim = All_gold_anim()

            loading_progress.value += 10

            self.all_error_messages = All_error_message_anim()

            self.object_to_render = []

      def deal_with_mouse(self):
            self.mouse.doing_stuff(self)

      def spawning_ennemies(self):
            self.spawning_mode.spawning_ennemies(self)

      def fight(self):
            for tower in self.all_towers:
                  tower.check_ennemies(self)
                  tower.attack_and_reload(self)
            for ennemy in self.all_ennemies:
                  ennemy.attack(self)
                  ennemy.use_power(self)

      def move_objects(self):
            for ennemy in self.all_ennemies:
                  ennemy.move(self)

            for projectile in self.all_projectiles:
                  projectile.move(self)
                  projectile.check_impact(self)

            for impact in self.all_impacts:
                  impact.explode(self)
                  impact.check_impact(self)

            for effect in self.all_magic_effects:
                  effect.advance(self)
                  effect.check_impact(self)

            for gold_gain in self.all_gold_anim.list:
                  gold_gain.move(self)

            for error_message in self.all_error_messages.list:
                  error_message.move(self)

            self.check_game_over()

      def check_game_over(self):
            for ennemy in self.all_ennemies:
                  if (ennemy.posX>WINDOW_WIDTH):
                        global_status.status = "Game Over"
                        break

      def die(self):
            for ennemy in self.all_ennemies:
                  ennemy.die(self)
            for dead_body in self.all_dead_bodies:
                  dead_body.fall(self)
            for tower in self.all_towers:
                  tower.die()
            for gate in self.base.all_gates:
                  gate.open()

      def render(self,update=True):
            self.object_to_render.append(self.background)
            self.object_to_render.append(self.menu)
            self.object_to_render.append(self.spawning_mode)

            for button in self.menu.all_buttons:
                  self.object_to_render.append(button)

            for button in self.menu.all_options_buttons:
                  self.object_to_render.append(button)

            for asset_background in self.background.all_assets:
                  self.object_to_render.append(asset_background)

            for gate in self.base.all_gates:
                  self.object_to_render.append(gate)

            for tower in self.all_towers:
                  self.object_to_render.append(tower)

            for projectile in self.all_projectiles:
                  self.object_to_render.append(projectile)

            for ennemy in self.all_ennemies:
                  self.object_to_render.append(ennemy)

            for dead_body in self.all_dead_bodies:
                  self.object_to_render.append(dead_body)

            for impact in self.all_impacts:
                  self.object_to_render.append(impact)

            for effect in self.all_magic_effects:
                  self.object_to_render.append(effect)

            for gold_gain in self.all_gold_anim.list:
                  self.object_to_render.append(gold_gain)

            for error_message in self.all_error_messages.list:
                  self.object_to_render.append(error_message)

            self.object_to_render.append(self.gold)

            self.object_to_render.append(self.selected_object)

            if (self.show_grid):
                  for box in self.grid.all_boxes:
                        self.object_to_render.append(box)

            if (global_status.status == "In game"):
                  self.object_to_render.append(self.mouse)

            self.object_to_render.sort(key =lambda object : object.rendering_layer)

            for object in self.object_to_render:
                  object.render()

            if update:
                  pygame.display.update()

            self.object_to_render.clear()

      def advance_time(self):
            self.timer += self.timestep

            self.gold.gold_earn(self)

            #print(CLOCK.get_fps())

      def reset(self):

            self.spawning_mode.reset()

            self.gold.reset()

            self.menu.reset()

            self.base.reset()

            self.all_towers.empty()

            self.all_towers.all_siege_engines.empty()

            self.all_projectiles.empty()

            self.all_impacts.empty()

            self.all_magic_effects.empty()

            self.all_ennemies.empty()

            self.all_dead_bodies.empty()

            self.all_gold_anim.list.clear()

            self.all_error_messages.list.clear()

            for box in self.grid.all_boxes:
                  box.occupied = False

            self.timer = 0.0

            self.previous_best_score = self.best_score

      def get_event(self):
            CLOCK.tick(FPS)
            self.timestep = CLOCK.get_time()

            self.all_events = pygame.event.get()
            for event in self.all_events:
                  if event.type == QUIT:
                        global_status.status = "Quitting"
                  if event.type == KEYDOWN:
                        if ((event.key == K_ESCAPE) or (event.key == K_p)):
                              if (global_status.status == "In game"):
                                    global_status.status = "In pause"
                              elif (global_status.status == "In pause"):
                                    global_status.status = "In game"
                        if ((event.key == K_DELETE) or (event.key == K_x)):
                              if self.selected_object.destroyable:
                                    self.selected_object.obj.destroy(self)
                        if DEV_MODE:
                              if (event.key == K_g):
                                    global_status.status = "Game Over"
                              if (event.key == K_n):
                                    self.gold.amount *= 2
                              if (event.key == K_k):
                                    self.all_ennemies.empty()
                              if (event.key == K_h):
                                    for emy in self.all_ennemies:
                                          emy.hp = 0.0

                              if (event.key == K_1):
                                    self.spawning_mode.spawn(self,GOBLIN_TAG,1)
                              if (event.key == K_2):
                                    self.spawning_mode.spawn(self,OGRE_TAG,1)
                              if (event.key == K_3):
                                    self.spawning_mode.spawn(self,BLUE_NEC_TAG,1)
                              if (event.key == K_4):
                                    self.spawning_mode.spawn(self,RED_NEC_TAG,1)
                              if (event.key == K_5):
                                    self.spawning_mode.spawn(self,GREEN_NEC_TAG,1)
                              if (event.key == K_6):
                                    self.spawning_mode.spawn(self,BLUE_SKEL_TAG,1)
                              if (event.key == K_7):
                                    self.spawning_mode.spawn(self,RED_SKEL_TAG,1)
                              if (event.key == K_8):
                                    self.spawning_mode.spawn(self,GREEN_SKEL_TAG,1)
                              if (event.key == K_9):
                                    self.spawning_mode.spawn(self,KAMIKAZE_TAG,1)
                              if (event.key == K_0):
                                    self.spawning_mode.spawn(self,DRAGON_TAG,1)


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

print('Program uruchomiony...')
print("""Włam się do systemu, zgadująć dwucyfrowy PIN.
Numer PIN składa się z cyfr 0, 1, 2.""")
pin = input('Wprowadź numer PIN: ')

if pin == '21':
    print('BRAWO! Złamałes system')
elif pin == '20':
    print('Trochę za mało')
elif pin == '22':
    print('Trochę za dużo')
else:
    print('Nie trafiłes')
# %%

    print('Program uruchomiony...')
    print("""Włam się do systemu, zgadująć dwucyfrowy PIN.
    Numer PIN składa się z cyfr 0, 1, 2.""")
    pin = int(input('Wprowadź numer PIN: '))

    if pin == 21:
        print('BRAWO! Złamałes system')
    elif pin == 20:
        print('Trochę za mało')
    elif pin == 22:
        print('Trochę za dużo')
    else:
        print('Nie trafiłes')
# %%
string = ''
if string:
    print('Niepusty')
else:
    print('Pusty')
# %%
number = 1
if number:
    print('liczba niezerowa')
else:
    print('Zero')
# %%
default_flag = False

if default_flag:
    print('Doszło do defaultu')
else:
    print('Nie doszło')
# %%
default_flag = False

if not default_flag:
    print('Nie doszło')
else:
    print('Doszło do defaultu')
# %%
saldo = 10000
klient_zwer = True

if saldo > 0 and klient_zwer:
    print('możesz wyplacic')
else:
    print('nie możesz')
# %%
saldo = 10000
klient_zwer = True
amount = int(input('ile chcesz? '))
if saldo > 0 and klient_zwer and saldo >= amount:
    print('możesz wyplacic')
else:
    print('nie możesz. '
          'Brakuje ci {}'.format(abs(saldo - amount)))
# %%
name = 'Python'
if 'Po' in name:
    print('znaleziono')
else:
    print('nie znaleziono')
# %%
tech = 'Python'
'dobry wybor' if tech == 'Python' else 'Poszukaj czegos innego'


# 이진 탐색 소스코드 구현 (반복문)
def binary_search(array, target, start, end):
    while start <= end:
        mid = (start + end) // 2
        # 찾은 경우 중간점 인덱스 반환
        if array[mid] == target:
            return mid
        # 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인
        elif array[mid] > target:
            end = mid - 1
        # 중간점의 값보다 찾고자 하는 값이 작은 경우 오른쪽 확인
        else:
            start = mid + 1
    return None

# N(가게의 부품 개수) 입력
n = int(input())
# 가게에 있는 전체 부품 번호를 공백을 기준으로 구분하여 입력
array = list(map(int, input().split()))
array.sort() # 이진 탐색을 수행하기 위해 사전에 정렬 수행
# M(손님이 확인 요청한 부품 개수) 입력
m = int(input())
# 손님이 확인 요청한 전체 부품 번호를 공백을 기준으로 구분하여 입력
x = list(map(int, input().split()))

# 손님이 확인 요청한 부품 번호를 하나씩 확인
for i in x:
    # 해당 부품이 존재하는지 확인
    result = binary_search(array, i, 0, n - 1)
    if result != None:
        print('yes', end=' ')
    else:
        print('no', end=' ')


class ChainingHashTable:
    def __init__(self, size=100):
        self.size = size
        self.table = [[] for _ in range(size)]

    def hash_function(self, value):
        return value % 2

    def insert(self, value):
        index = self.hash_function(value)
        print(index)
        if value not in self.table[index]:
            self.table[index].append(value)
            return True
        else:
            return False

def is_distinct(lst):
    hash_table = ChainingHashTable()
    for elem in lst:
        if not hash_table.insert(elem):
            return False
    return True

# Example usage
lst = [1, 11, 21, 31]
print(is_distinct(lst))  # Output: True


import os, random
print(f"Welcome to Tic-Tac-Toe. You play with X, while the both plays with O. Here are the possible positions. After each move of the bot, please choose which position you want to place the X, and press Enter\n     │1│2│3│\n     │4│5│6│\n     │7│8│9│\n\nclick on the terminal and press Enter to continue...")
input()
first_pos = "bot"
score=[0,0]

def clear():
    #clearing the console
    #THIS SCRIPT DOESN'T WORK IN PYCHARM IF YOU HAVEN'T SELECTED "EMULATE TERMINAL IN OUTPUT CONSOLE"
    #TO GET THERE, RIGHT CLICK ON THE CODE AND PRESS "MODIFY RUN CONFIGURATION"
    if os.name == 'nt':
        _ = os.system('cls')
    else:
        _ = os.system('clear')

def check_row(which_row, check_player):
    #check if a row is filled with the same
    global field
    check_one = field[which_row * 3] == check_player
    check_two = field[which_row * 3 + 1] == check_player
    check_tre = field[which_row * 3 + 2] == check_player
    return check_one and check_two and check_tre

def check_col(which_col, check_player):
    #check if a column is filled with the same
    global field
    check_one = field[which_col] == check_player
    check_two = field[which_col + 3] == check_player
    check_tre = field[which_col + 6] == check_player
    return check_one and check_two and check_tre

def check_diag(check_player):
    #check the diagonals
    global field
    check_one = field[0] == check_player and field[4] == check_player and field[8] == check_player
    check_two = field[2] == check_player and field[4] == check_player and field[6] == check_player
    return check_one or check_two

def draw_field():
    #draw the game field
    #the symbol   means empty space
    print("\n   Tic-Tac-Toe\n")
    for symbol, bs in enumerate(field):
        if field[symbol] == 0:
            field_display[symbol] = " "
        elif field[symbol] == 1:
            field_display[symbol] = "X"
        elif field[symbol] == 2:
            field_display[symbol] = "O"
    print(f"     │{field_display[0]}│{field_display[1]}│{field_display[2]}│\n     │{field_display[3]}│{field_display[4]}│{field_display[5]}│     player points: {score[0]}\n     │{field_display[6]}│{field_display[7]}│{field_display[8]}│     bot points: {score[1]}")

def check_winner(keep_score):
    global first_pos
    #check if someone wins and return True or False
    #keep_score shows whether you should keep score, because this function is also called "hypothetically" when the bot checks if it might win or lose next round
    #in which case don't affect the score yet
    player_won = -1
    for j in range(1, 3):
        for i in range(3):
            if check_row(i, j):
                player_won = j
                break
            if check_col(i, j):
                player_won = j
                break
        if check_diag(j):
            player_won = j
            break
    if player_won == 1:
        print("\nThe player wins! Press Enter to try again. Next time the bot is first.")
        first_pos = "bot"
        if keep_score:
            score[0] += 1
        return True
    elif player_won == 2:
        print("\nThe bot wins! Press Enter to try again. Next time the player is first.")
        first_pos = "player"
        if keep_score:
            score[1] += 1
        return True
    else:
#if it's a draw, the next first round is randomly given
        if not 0 in field:
            if random.random()>=0.5:
                first_pos = "player"
            else:
                first_pos = "bot"
            print(f"\nDraw! Press Enter to try again. Next time the {first_pos} is first.")
            return True
        else:
            if keep_score:
                print("\n" + message + ": ", end="")
            return False

# bot's "AI"
def bot_move():
    valid_move = False
    winning_move = False
    #attack mode
    #here it checks if there's a move which can win him the game (like 2 out of 3 Os placed in a row/col/diag)
    for i in range(9):
        if field[i] != 0:
            continue
        else:
            field[i] = 2
            if check_winner(False) and random.random() >= 0.1: #if there's such a move, there's a 10% chance he won't notice
                winning_move = True
                break
            else:
                field[i] = 0
    #defense mode
    #if it hasn't found such a move, here it checks if there's a move which IF it does NOT make, YOU might win the game
    if winning_move != True:
        for i in range(9):
            if field[i] != 0:
                continue
            else:
                field[i] = 1
                if check_winner(False) and random.random() >= 0.1: #if there's such a move, there's a 10% chance he won't notice
                    field[i] = 2
                    winning_move = True
                    break
                else:
                    field[i] = 0

    #if it hasn't figured out anything, make a random move
    if winning_move != True:
        while not valid_move:
            move_position = random.randint(1, 9)
            if field[move_position-1] == 0:
                field[move_position - 1] = 2
                valid_move = True

#main loop
while True: # this loop represents one round
    #clearing the field from last round
    field = [0, 0, 0, 0, 0, 0, 0, 0, 0]
    field_display = ["", "", "", "", "", "", "", "", ""]
    message = "Choose a position"
    if first_pos == "bot":
        bot_move()
    while True: # this loop represents one move
        clear() #clear the terminal
        draw_field() #draw the field
        if not check_winner(True): #if no one has won, wait for player move
            action=input()
            #here I make sure you can't enter BS and break the code
            if action!="1" and action!="2" and action!="3" and action!="4" and action!="5" and action!="6" and action!="7" and action!="8" and action!="9":
                message = "Such a position doesn't exist. Try again"
            elif field[int(action)-1] != 0:
                message = "That position is occupied! Try again"
            else:
            #if it passes the checks and the move is possible, do it
                message = "Choose a position"
                field[int(action) - 1] = 1
                #if this move hasn't won the player the game, do bot's move
                if not check_winner(False):
                    bot_move()
        else: #if someone has won, wait for input and do the next iteration of the "game round" loop
            input()
            break


def find_node_without_dependencies():
    for node, count in dependencies_by_node.items():
        if count == 0:
            return "Yes"

    return "No"

def find_dependencies():
    result = {}

    for node, children in graph.items():
        if node not in result:
            result[node] = 0
        for child in children:
            if child not in result:
                result[child] = 1
            else:
                result[child] += 1

    return result

graph = {}

while True:
    data = input().split('-')

    if len(data) == 1:
        break

    graph[data[0]] = data[1]

dependencies_by_node = find_dependencies()
print(f"Acyclic: {find_node_without_dependencies()}")


import os
import argparse
import subprocess
import shutil
from pathlib import Path

# additional CSS from system locations, we use it if available
EXTRA_CSS = [['/usr/share/javascript/highlight.js/styles/routeros.css', 'highlight.css']]

def daps_build(src_dir, project_name, daps_exe):
    print('Creating HTML with DAPS...')
    sys.stdout.flush()

    build_dir = os.path.join(src_dir, '_docbuild')
    cmd = [daps_exe, 'html', '--clean']
    if project_name:
        cmd.extend(['--name', project_name])

    if os.path.exists(build_dir):
        shutil.rmtree(build_dir)
    os.makedirs(build_dir, exist_ok=True)

    ret = subprocess.call(cmd, cwd=src_dir)
    if ret != 0:
        print('Documentation HTML build failed!')
        sys.exit(6)

    html_out_dir = os.path.join(build_dir, project_name, 'html', project_name)

    # copy the (usually missing) plain SVG project icon
    shutil.copy(
        os.path.join(src_dir, 'images', 'src', 'svg', 'appstream-logo.svg'),
        os.path.join(html_out_dir, 'images'),
    )

    # copy extra CSS if it is available
    for css_fname in EXTRA_CSS:
        if os.path.exists(css_fname[0]):
            shutil.copy(css_fname[0], os.path.join(html_out_dir, 'static', 'css', css_fname[1]))

    return build_dir

def copy_result(build_dir, project_name, dest_dir):
    print('Copying HTML documentation...')
    if os.path.exists(dest_dir):
        shutil.rmtree(dest_dir)

    shutil.copytree(
        os.path.join(build_dir, project_name, 'html', project_name), dest_dir, symlinks=True
    )

def cleanup_build_dir(build_dir):
    print('Cleaning up.')
    if os.path.exists(build_dir):
        shutil.rmtree(build_dir)

def daps_validate(src_dir, daps_exe):
    print('Validating documentation with DAPS...')

    build_dir = os.path.join(src_dir, '_docbuild')
    if os.path.exists(build_dir):
        shutil.rmtree(build_dir)
    os.makedirs(build_dir, exist_ok=True)

    ret = subprocess.call([daps_exe, 'validate'], cwd=src_dir)
    if ret != 0:
        print('Validation failed!')
    cleanup_build_dir(build_dir)
    return ret == 0

def main(args):
    parser = argparse.ArgumentParser()
    parser.add_argument('--build', action='store_true')
    parser.add_argument('--validate', action='store_true')

    parser.add_argument('--src', action='store')
    parser.add_argument('--builddir', action='store')
    parser.add_argument('--daps', action='store', default='daps')
    parser.add_argument('project', action='store', default='AppStream', nargs='?')

    options = parser.parse_args(args)

    if not options.validate and not options.build:
        print('No action was specified.')
        return 1

    if not options.src:
        print('Source root directory is not defined!')
        return 1

    os.chdir(options.src)

    if options.build:
        # build the HTML files
        build_dir = daps_build(options.src, options.project, options.daps)

        # copy to output HTML folder, overriding all previous contents
        copy_result(build_dir, options.project, os.path.join(options.src, 'html'))

        # remove temporary directory
        cleanup_build_dir(build_dir)

        # make a dummy file so Meson can rebuild documentation on demand
        if options.builddir:
            Path(os.path.join(options.builddir, 'docs_built.stamp')).touch()

        print('Documentation built.')

    elif options.validate:
        # validate the XML
        ret = daps_validate(options.src, options.daps)
        if not ret:
            sys.exit(6)

    return 0

if __name__ == '__main__':
    import sys

    sys.exit(main(sys.argv[1:]))


from __future__ import absolute_import
import os.path
import pytest
from pytest import fixture, yield_fixture
from core.archive import Archive
from core.permission import get_or_add_everybody_rule
from core.database.postgres.permission import AccessRulesetToRule
from core import httpstatus
from web.frontend.filehandlers import fetch_archived, send_image, send_from_webroot
from utils.testing import make_node_public

def test_fetch_archived(req, session, fake_archive, content_node):
    node = content_node
    node.system_attrs[u"archive_path"] = u"testpath"
    node.system_attrs[u"archive_type"] = u"test"
    session.flush()
    req.path = u"/archive/{}".format(node.id)
    assert fake_archive.get_state(node) == Archive.NOT_PRESENT
    fetch_archived(req)
    assert fake_archive.get_state(node) == Archive.PRESENT

@yield_fixture
def req_for_png_image(session, image_png, req):
    req.request_headers["Accept"] = "image/png"
    session.flush()
    req.path = "/image/" + unicode(image_png.id)
    yield req

@yield_fixture
def req_for_svg_image(session, image_svg, req):
    req.request_headers["Accept"] = "image/svg+xml"
    session.flush()
    req.path = "/image/" + unicode(image_svg.id)
    yield req

@fixture
def public_image_png(image_png):
    image = image_png
    make_node_public(image)
    image._generate_image_formats()
    return image

@pytest.mark.slow
@fixture
def public_image_svg(image_svg):
    image = image_svg
    make_node_public(image)
    image._generate_image_formats()
    return image

def assert_image_file_sent(image, mimetype, request, error=None):
    assert error is None
    image_file = image.files.filter_by(filetype=u"image", mimetype=mimetype).scalar()
    assert image_file, u"error in fixture, image file not present: " + mimetype
    assert (image_file.abspath, mimetype) in request.sent_files_with_mimetype

def test_send_image_accept_anything(public_image_png, req_for_png_image):
    image = public_image_png
    req = req_for_png_image
    req.request_headers["Accept"] = "*/*"
    error = send_image(req)
    assert_image_file_sent(image, u"image/png", req, error)

def test_send_image_png(public_image_png, req_for_png_image):
    image = public_image_png
    req = req_for_png_image
    error = send_image(req)
    assert_image_file_sent(image, u"image/png", req, error)

def test_send_image_png_nothing_preferred_by_client(public_image_png, req_for_png_image):
    image = public_image_png
    req = req_for_png_image
    del req.request_headers["Accept"]
    error = send_image(req)
    assert_image_file_sent(image, u"image/png", req, error)

def test_send_image_extension_png(public_image_png, req_for_png_image):
    image = public_image_png
    req = req_for_png_image
    req.path = "/image/" + unicode(image.id) + ".png"
    error = send_image(req)
    assert_image_file_sent(image, u"image/png", req, error)

@pytest.mark.slow
def test_send_image_svg(public_image_svg, req_for_svg_image):
    image = public_image_svg
    req = req_for_svg_image
    error = send_image(req)
    assert_image_file_sent(image, u"image/svg+xml", req, error)

@pytest.mark.slow
def test_send_image_svg_client_anything(public_image_svg, req_for_svg_image):
    image = public_image_svg
    req = req_for_svg_image
    # client accepts everything, Chrome does this, for example
    req.request_headers["Accept"] = "*/*"
    error = send_image(req)
    assert_image_file_sent(image, u"image/png", req, error)

@pytest.mark.slow
def test_send_image_svg_client_anything_server_prefers_png(public_image_svg, req_for_svg_image):
    image = public_image_svg
    req = req_for_svg_image
    req.request_headers["Accept"] = "*/*"
    image.system_attrs["preferred_mimetype"] = u"image/png"
    error = send_image(req)
    assert_image_file_sent(image, u"image/png", req, error)

@pytest.mark.slow
def test_send_image_svg_server_prefers_png(public_image_svg, req_for_svg_image):
    image = public_image_svg
    req = req_for_svg_image
    image.system_attrs["preferred_mimetype"] = u"image/png"
    error = send_image(req)
    # client wants svg, client gets svg, regardless of server's preferred_mimetype setting
    assert_image_file_sent(image, u"image/svg+xml", req, error)

### failure cases

def test_send_image_no_data_access(req_for_png_image):
    req = req_for_png_image
    error = send_image(req)
    assert error == 404

def test_send_image_no_file(image_png, req_for_png_image):
    req = req_for_png_image
    node = image_png
    error = send_image(req)
    make_node_public(node)
    assert error == 404

def test_send_image_accept_wrong(public_image_png, req_for_png_image):
    req = req_for_png_image
    req.request_headers["Accept"] = "animal/lizard"
    error = send_image(req)
    assert error == httpstatus.HTTP_NOT_ACCEPTABLE

def test_send_image_path_wrong(req_for_png_image):
    req = req_for_png_image
    req.path = "/lizard/"
    error = send_image(req)
    assert error == httpstatus.HTTP_BAD_REQUEST

def test_send_image_extension_wrong(public_image_png, req_for_png_image):
    node = public_image_png
    req = req_for_png_image
    req.path = "/image/" + unicode(node.id) + ".cow"
    error = send_image(req)
    assert error == httpstatus.HTTP_NOT_ACCEPTABLE

def test_send_from_webroot(req):
    req.path = "/favicon.ico"
    send_from_webroot(req)
    from core import config
    assert (os.path.join(config.basedir, "web/root", "favicon.ico"), "other") in req.sent_files_with_mimetype


soma = 0
contagem = 0
for i in range(10):
    num = int(input("Digite um número inteiro positivo: "))
    if num > 0:
        soma += num
        contagem += 1

media = soma / contagem
print("A média dos números positivos digitados é:", media)


from collections import Mapping
import posixpath

from api_schema_graph import APISchemaGraph
from branch_utility import BranchUtility
from extensions_paths import API, JSON_TEMPLATES
from third_party.json_schema_compiler.model import UnixName

_EXTENSION_API = 'extension_api.json'

# The version where api_features.json is first available.
_API_FEATURES_MIN_VERSION = 28
# The version where permission_ and manifest_features.json are available and
# presented in the current format.
_ORIGINAL_FEATURES_MIN_VERSION = 20
# API schemas are aggregated in extension_api.json up to this version.
_EXTENSION_API_MAX_VERSION = 17
# The earliest version for which we have SVN data.
_SVN_MIN_VERSION = 5

def _GetChannelFromFeatures(api_name, json_fs, filename):
  '''Finds API channel information from the features |filename| within the the
  given |json_fs|. Returns None if channel information for the API cannot be
  located.
  '''
  feature = json_fs.GetFromFile(API + filename).Get().get(api_name)
  if feature is None:
    return None
  if isinstance(feature, Mapping):
    # The channel information exists as a solitary dict.
    return feature.get('channel')
  # The channel information dict is nested within a list for whitelisting
  # purposes. Take the newest channel out of all of the entries.
  return BranchUtility.NewestChannel(entry.get('channel') for entry in feature)

def _GetChannelFromApiFeatures(api_name, json_fs):
  return _GetChannelFromFeatures(api_name, json_fs, '_api_features.json')

def _GetChannelFromManifestFeatures(api_name, json_fs):
  # _manifest_features.json uses unix_style API names.
  api_name = UnixName(api_name)
  return _GetChannelFromFeatures(api_name, json_fs, '_manifest_features.json')

def _GetChannelFromPermissionFeatures(api_name, json_fs):
  return _GetChannelFromFeatures(api_name, json_fs, '_permission_features.json')

class AvailabilityFinder(object):
  '''Generates availability information for APIs by looking at API schemas and
  _features files over multiple release versions of Chrome.
  '''

  def __init__(self,
               branch_utility,
               compiled_fs_factory,
               file_system_iterator,
               host_file_system,
               object_store_creator):
    self._branch_utility = branch_utility
    self._compiled_fs_factory = compiled_fs_factory
    self._file_system_iterator = file_system_iterator
    self._host_file_system = host_file_system
    self._object_store_creator = object_store_creator
    def create_object_store(category):
      return object_store_creator.Create(AvailabilityFinder, category=category)
    self._top_level_object_store = create_object_store('top_level')
    self._node_level_object_store = create_object_store('node_level')
    self._json_fs = compiled_fs_factory.ForJson(self._host_file_system)

  def _GetPredeterminedAvailability(self, api_name):
    '''Checks a configuration file for hardcoded (i.e. predetermined)
    availability information for an API.
    '''
    api_info = self._json_fs.GetFromFile(
        JSON_TEMPLATES + 'api_availabilities.json').Get().get(api_name)
    if api_info is None:
      return None
    if api_info['channel'] == 'stable':
      return self._branch_utility.GetStableChannelInfo(api_info['version'])
    else:
      return self._branch_utility.GetChannelInfo(api_info['channel'])

  def _GetApiSchemaFilename(self, api_name, file_system, version):
    '''Gets the name of the file which may contain the schema for |api_name| in
    |file_system|, or None if the API is not found. Note that this may be the
    single _EXTENSION_API file which all APIs share in older versions of Chrome,
    in which case it is unknown whether the API actually exists there.
    '''
    def under_api_path(path):
      return API + path

    if version == 'trunk' or version > _ORIGINAL_FEATURES_MIN_VERSION:
      # API schema filenames switch format to unix_hacker_style.
      api_name = UnixName(api_name)

    # |file_system| will cache the results from the ReadSingle() call.
    filenames = file_system.ReadSingle(API).Get()

    for ext in ('json', 'idl'):
      filename = '%s.%s' % (api_name, ext)
      if filename in filenames:
        return under_api_path(filename)
    if _EXTENSION_API in filenames:
      return under_api_path(_EXTENSION_API)
    # API schema data could not be found in any .json or .idl file.
    return None

  def _GetApiSchema(self, api_name, file_system, version):
    '''Searches |file_system| for |api_name|'s API schema data, and processes
    and returns it if found.
    '''
    api_filename = self._GetApiSchemaFilename(api_name, file_system, version)
    if api_filename is None:
      # No file for the API could be found in the given |file_system|.
      return None

    schema_fs = self._compiled_fs_factory.ForApiSchema(file_system)
    api_schemas = schema_fs.GetFromFile(api_filename).Get()
    matching_schemas = [api for api in api_schemas
                        if api['namespace'] == api_name]
    # There should only be a single matching schema per file, or zero in the
    # case of no API data being found in _EXTENSION_API.
    assert len(matching_schemas) <= 1
    return matching_schemas or None

  def _HasApiSchema(self, api_name, file_system, version):
    '''Whether or not an API schema for |api_name|exists in the given
    |file_system|.
    '''
    filename = self._GetApiSchemaFilename(api_name, file_system, version)
    if filename is None:
      return False
    if filename.endswith(_EXTENSION_API):
      return self._GetApiSchema(api_name, file_system, version) is not None
    return True

  def _CheckStableAvailability(self, api_name, file_system, version):
    '''Checks for availability of an API, |api_name|, on the stable channel.
    Considers several _features.json files, file system existence, and
    extension_api.json depending on the given |version|.
    '''
    if version < _SVN_MIN_VERSION:
      # SVN data isn't available below this version.
      return False
    available_channel = None
    json_fs = self._compiled_fs_factory.ForJson(file_system)
    if version >= _API_FEATURES_MIN_VERSION:
      # The _api_features.json file first appears in version 28 and should be
      # the most reliable for finding API availability.
      available_channel = _GetChannelFromApiFeatures(api_name, json_fs)
    if version >= _ORIGINAL_FEATURES_MIN_VERSION:
      # The _permission_features.json and _manifest_features.json files are
      # present in Chrome 20 and onwards. Use these if no information could be
      # found using _api_features.json.
      available_channel = available_channel or (
          _GetChannelFromPermissionFeatures(api_name, json_fs)
          or _GetChannelFromManifestFeatures(api_name, json_fs))
      if available_channel is not None:
        return available_channel == 'stable'
    if version >= _SVN_MIN_VERSION:
      # Fall back to a check for file system existence if the API is not
      # stable in any of the _features.json files, or if the _features files
      # do not exist (version 19 and earlier).
      return self._HasApiSchema(api_name, file_system, version)

  def _CheckChannelAvailability(self, api_name, file_system, channel_info):
    '''Searches through the _features files in a given |file_system|, falling
    back to checking the file system for API schema existence, to determine
    whether or not an API is available on the given channel, |channel_info|.
    '''
    json_fs = self._compiled_fs_factory.ForJson(file_system)
    available_channel = (_GetChannelFromApiFeatures(api_name, json_fs)
        or _GetChannelFromPermissionFeatures(api_name, json_fs)
        or _GetChannelFromManifestFeatures(api_name, json_fs))
    if (available_channel is None and
        self._HasApiSchema(api_name, file_system, channel_info.version)):
      # If an API is not represented in any of the _features files, but exists
      # in the filesystem, then assume it is available in this version.
      # The chrome.windows API is an example of this.
      available_channel = channel_info.channel
    # If the channel we're checking is the same as or newer than the
    # |available_channel| then the API is available at this channel.
    newest = BranchUtility.NewestChannel((available_channel,
                                          channel_info.channel))
    return available_channel is not None and newest == channel_info.channel

  def _CheckApiAvailability(self, api_name, file_system, channel_info):
    '''Determines the availability for an API at a certain version of Chrome.
    Two branches of logic are used depending on whether or not the API is
    determined to be 'stable' at the given version.
    '''
    if channel_info.channel == 'stable':
      return self._CheckStableAvailability(api_name,
                                           file_system,
                                           channel_info.version)
    return self._CheckChannelAvailability(api_name,
                                          file_system,
                                          channel_info)

  def GetApiAvailability(self, api_name):
    '''Performs a search for an API's top-level availability by using a
    HostFileSystemIterator instance to traverse multiple version of the
    SVN filesystem.
    '''
    availability = self._top_level_object_store.Get(api_name).Get()
    if availability is not None:
      return availability

    # Check for predetermined availability and cache this information if found.
    availability = self._GetPredeterminedAvailability(api_name)
    if availability is not None:
      self._top_level_object_store.Set(api_name, availability)
      return availability

    def check_api_availability(file_system, channel_info):
      return self._CheckApiAvailability(api_name, file_system, channel_info)

    availability = self._file_system_iterator.Descending(
        self._branch_utility.GetChannelInfo('dev'),
        check_api_availability)
    if availability is None:
      # The API wasn't available on 'dev', so it must be a 'trunk'-only API.
      availability = self._branch_utility.GetChannelInfo('trunk')
    self._top_level_object_store.Set(api_name, availability)
    return availability

  def GetApiNodeAvailability(self, api_name):
    '''Returns an APISchemaGraph annotated with each node's availability (the
    ChannelInfo at the oldest channel it's available in).
    '''
    availability_graph = self._node_level_object_store.Get(api_name).Get()
    if availability_graph is not None:
      return availability_graph

    def assert_not_none(value):
      assert value is not None
      return value

    availability_graph = APISchemaGraph()

    host_fs = self._host_file_system
    trunk_stat = assert_not_none(host_fs.Stat(self._GetApiSchemaFilename(
        api_name, host_fs, 'trunk')))

    # Weird object thing here because nonlocal is Python 3.
    previous = type('previous', (object,), {'stat': None, 'graph': None})

    def update_availability_graph(file_system, channel_info):
      version_filename = assert_not_none(self._GetApiSchemaFilename(
          api_name, file_system, channel_info.version))
      version_stat = assert_not_none(file_system.Stat(version_filename))

      # Important optimisation: only re-parse the graph if the file changed in
      # the last revision. Parsing the same schema and forming a graph on every
      # iteration is really expensive.
      if version_stat == previous.stat:
        version_graph = previous.graph
      else:
        # Keep track of any new schema elements from this version by adding
        # them to |availability_graph|.
        #
        # Calling |availability_graph|.Lookup() on the nodes being updated
        # will return the |annotation| object -- the current |channel_info|.
        version_graph = APISchemaGraph(self._GetApiSchema(
            api_name, file_system, channel_info.version))
        availability_graph.Update(version_graph.Subtract(availability_graph),
                                  annotation=channel_info)

      previous.stat = version_stat
      previous.graph = version_graph

      # Continue looping until there are no longer differences between this
      # version and trunk.
      return version_stat != trunk_stat

    self._file_system_iterator.Ascending(self.GetApiAvailability(api_name),
                                         update_availability_graph)

    self._node_level_object_store.Set(api_name, availability_graph)
    return availability_graph


'''
字符串编码一直是令人非常头疼的问题，尤其是我们在处理一些不规范的第三方网页的时候。虽然Python提供了Unicode表示的str和bytes两种数据类型，并且可以通过encode()和decode()方法转换，但是，在不知道编码的情况下，对bytes做decode()不好做。

对于未知编码的bytes，要把它转换成str，需要先“猜测”编码。猜测的方式是先收集各种编码的特征字符，根据特征字符判断，就能有很大概率“猜对”。

当然，我们肯定不能从头自己写这个检测编码的功能，这样做费时费力。chardet这个第三方库正好就派上了用场。用它来检测编码，简单易用。
'''
# 使用chardet
import chardet
# 当我们拿到一个bytes时，就可以对其检测编码。用chardet检测编码，只需要一行代码：
a = chardet.detect(b'Hello, world!')

'''检测出的编码是ascii，注意到还有个confidence字段，表示检测的概率是1.0（即100%）。

我们来试试检测GBK编码的中文：'''
data = '离离原上草，一岁一枯荣'.encode('gbk')
chardet.detect(data)
# 检测的编码是GB2312，注意到GBK是GB2312的超集，两者是同一种编码，检测正确的概率是74%，language字段指出的语言是'Chinese'。
# 对UTF-8编码进行检测:
data = '离离原上草，一岁一枯荣'.encode('utf-8')
chardet.detect(data)
# 日语
data = '最新の主要ニュース'.encode('euc-jp')
chardet.detect(data)


import uuid

from computedfields.models import ComputedFieldsModel, computed
from django.core import validators
from django.db import models

from categories import models as categories_models

class Product(ComputedFieldsModel):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    name = models.CharField(max_length=100)
    description = models.TextField()
    color = models.CharField(max_length=100)
    price = models.DecimalField(
        max_digits=9, decimal_places=2, validators=[validators.MinValueValidator(0)]
    )
    category = models.ForeignKey(categories_models.Category, on_delete=models.CASCADE)

    @computed(
        models.DecimalField(
            help_text="Promotion price based on the product category discount",
            validators=[validators.MinValueValidator(0)],
            max_digits=9,
            decimal_places=2,
            default=0,
            null=False,
        ),
        depends=[("self", ["price"]), ("category", ["discount"])],
    )
    def promotion_price(self) -> float:
        return round(float(self.price) * float(1 - self.category.discount_for_calc), 2)

    class Meta:
        indexes = [
            models.Index(
                fields=["name", "description"],
                name="name_description_filter_index",
            ),
        ]


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Jan 18 15:53:22 2019

@author: romain
"""

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report
from sklearn.metrics import roc_auc_score
from sklearn import metrics
from sklearn.metrics import roc_curve, auc
from sklearn.metrics import average_precision_score
from sklearn.metrics import precision_recall_curve

#---------------------------------------------------------------------------#
                    # LECTURE DU FICHIER #
#---------------------------------------------------------------------------#

# On lit notre fichier
df = pd.read_csv('inquiry.csv' , delimiter=',')
print(df.shape)
# On gère le format date
df['datetime_created_at'] = pd.to_datetime(df['inquiry_created_at'])
df.drop(['inquiry_created_at'], axis=1, inplace=True)
# On trie les dates created_at
data_sort = df.sort_values(by=['datetime_created_at'])
# On renome la colonne pour quelle garde le nom initial
inquiry_data = data_sort.rename(columns={"datetime_created_at": "inquiry_created_at"})
# On enlève la dernière ligne
inquiry = inquiry_data.drop([6584])

#inquiry data [20452 rows x 19 columns]

#---------------------------------------------------------------------------#
                    # DATA PRE PROCESSING #
#---------------------------------------------------------------------------#

# On normalise nos currency en euro
X_norm = inquiry[inquiry['currency'] == 'USD'].total_price * 0.87
X_norm=X_norm.append(inquiry[inquiry['currency'] == 'GBP'].total_price * 1.10)
X_norm=X_norm.append(inquiry[inquiry['currency'] == 'HKD'].total_price * 0.11)
X_norm=X_norm.append(inquiry[inquiry['currency'] == 'SGD'].total_price * 0.63)
X_norm=X_norm.append(inquiry[inquiry['currency'] == 'CAD'].total_price * 0.64)
X_norm=X_norm.append(inquiry[inquiry['currency'] == 'AUD'].total_price * 0.62)
X_norm=X_norm.append(inquiry[inquiry['currency'] == 'CZK'].total_price * 0.038)
X_norm=X_norm.append(inquiry[inquiry['currency'] == 'EUR'].total_price)

# On rajoute une colonne avec tous les prix en euro
inquiry['total_price_norm'] = X_norm
# On enleve la colonne currency
del inquiry['currency']

# On rassemble les colonnes messages
inquiry['main_message'] = inquiry['main_nbr_admin_message'] + inquiry['main_nbr_renter_message']
inquiry['private_message'] = inquiry['private_lo_nbr_admin_message'] + inquiry['private_lo_nbr_lo_message'] + inquiry['private_renter_nbr_admin_message'] + inquiry['private_renter_nbr_renter_message']

# On calcule le budget day
total_price = inquiry['total_price_norm']
duration_event_days = inquiry['duration_event_days']
duration_event_days_copy = duration_event_days.copy()
duration = duration_event_days_copy.replace(0.0, 1.0)
inquiry['budget_day'] = total_price / duration

#---------------------------------------------------------------------------#
                    # DATASET SUCCESS #
#---------------------------------------------------------------------------#

# On selectionne les success
X_success = inquiry[inquiry['status_deal'] == 'success']
#On gère le format date
X_success['datetime_booked_at'] = pd.to_datetime(X_success['paid_at'])
X_success.drop(['paid_at'], axis=1, inplace=True)
X_success['datetime_created_at'] = pd.to_datetime(X_success['inquiry_created_at'])
X_success.drop(['inquiry_created_at'], axis=1, inplace=True)

# On crée une colonne pour le temps que l'on met pour gagner en mois
time_to_win_deals = X_success['datetime_booked_at'].dt.month - X_success['datetime_created_at'].dt.month
X_success['time_to_win_month'] = time_to_win_deals

# On explore notre dataset
df_same_month = X_success[X_success['time_to_win_month'] == 0]
# 756
df_different_month = X_success[X_success['time_to_win_month'] == 2]
# 330 (292 : 1 et 34 : 2 et 3 : 3 et 4 : 1)

# On remplace les valeurs 2,3,4 par un pour avoir un pb de classification binaire
X_success['time_to_win_month'].replace(to_replace=[2,3,4],value=1,inplace=True)

#---------------------------------------------------------------------------#
                    # MODELISATION #
#---------------------------------------------------------------------------#

inquiry_features1 = ['event_type','duration_event_days', 'nbr_days_before_event',
   'total_price_norm', 'main_message', 'private_message', 'budget_day']
X1 = X_success[inquiry_features1]

# On encode nos données
X2 = pd.get_dummies(X1)
y = X_success['time_to_win_month']

# On split notre dataset
X_train, X_test, y_train, y_test = train_test_split(X2, y, test_size=0.2)
# On modélise
model = DecisionTreeClassifier(max_depth=6)
model.fit(X_train, y_train)
pred_train = model.predict(X_train)
pred_test = model.predict(X_test)
pred = model.predict(X2)

#---------------------------------------------------------------------------#
                    # PERFORMANCE SUR LE TRAIN #
#---------------------------------------------------------------------------#

# On affiche notre performance sur le test
print('-------- PERFORMANCE SUR LE TRAIN --------- \n')
print('classification_report train  \n',classification_report(pred_train, y_train))
print('ROC = ', roc_auc_score(pred_train, y_train), '\n')

fpr_train, tpr_train, thresholds = metrics.roc_curve(pred_train, y_train, pos_label=0)
#---------------------------------------------------------------------------#
                    # PERFORMANCE SUR LE TEST #
#---------------------------------------------------------------------------#

# On affiche notre performance sur le test
print('-------- PERFORMANCE SUR LE TEST --------- \n')
print('classification_report test  \n',classification_report(pred_test, y_test))
print('ROC = ', roc_auc_score(pred_test, y_test), '\n')

fpr_train, tpr_train, thresholds = metrics.roc_curve(pred_test, y_test, pos_label=0)

#---------------------------------------------------------------------------#
                    # PERFORMANCE SUR LE DATASET #
#---------------------------------------------------------------------------#

# On affiche notre performance sur le test
print('-------- PERFORMANCE SUR LE DATASET --------- \n')
print('classification_report dataset  \n',classification_report(pred, y))
print('ROC = ', roc_auc_score(y, pred), '\n')

fpr_train, tpr_train, thresholds = metrics.roc_curve(y, pred, pos_label=0)

#---------------------------------------------------------------------------#
                    # Courbe ROC #
#---------------------------------------------------------------------------#

plt.figure('Courbe roc')
plt.plot(tpr_train,fpr_train, color = 'b', label = ('Courbe ROC :', round(roc_auc_score(pred_test, y_test),2)))
plt.plot([0,1],[0,1],color='r',ls="--")
plt.title('Courbe ROC')
plt.legend()
plt.show()

#---------------------------------------------------------------------------#
                    # Features importances #
#---------------------------------------------------------------------------#

features = ['duration_event_days', 'nbr_days_before_event', 'total_price_norm',
       'main_message', 'private_message', 'budget_day',
       'event_type_Art Opening', 'event_type_Corporate Event',
       'event_type_Fashion Show', 'event_type_Fashion Showroom',
       'event_type_Food Event', 'event_type_Late Night Event (after 10pm)',
       'event_type_Photoshoot & Filming', 'event_type_Pop-Up Store',
       'event_type_Private Sale', 'event_type_Product Launch',
       'event_type_Shopping Mall']
importances = model.feature_importances_
indices = np.argsort(importances)

plt.figure('features importances')
plt.title('Feature Importances')
plt.barh(range(len(indices)), importances[indices], color='b', align='center')
plt.yticks(range(len(indices)), [features[i] for i in indices])
plt.xlabel('Relative Importance')
plt.show()

#---------------------------------------------------------------------------#
                    # VISUALISATION #
#---------------------------------------------------------------------------#

#from sklearn.externals.six import StringIO
#from IPython.display import Image  , display
#from sklearn.tree import export_graphviz
#import pydotplus
#dot_data = StringIO()
#export_graphviz(model, out_file=dot_data,  feature_names = features,
#                filled=True, rounded=True,
#                special_characters=True)
#graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
#display(Image(graph.create_png()))

#---------------------------------------------------------------------------#
                    # max_depth #
#---------------------------------------------------------------------------#

max_depths = [1, 2, 3,4,5,6,7,8,9,10]
train_results1 = []
test_results1 = []
train_results2 = []
test_results2 = []
train_results3 = []
test_results3 = []

for max_depth in max_depths:
   rf = DecisionTreeClassifier(max_depth=max_depth)
   rf.fit(X_train, y_train)

   train_pred = rf.predict(X_train)
   false_positive_rate, true_positive_rate, thresholds = roc_curve(y_train, train_pred)
   roc_auc = auc(false_positive_rate, true_positive_rate)
   average_precision1 = average_precision_score(y_train, train_pred)
   precision1, recall1, thresholds = precision_recall_curve(y_train, train_pred)
   #train_results1.append(average_precision1)
   train_results2.append(precision1[1])
   train_results3.append(recall1[1])

   y_pred = rf.predict(X_test)
   false_positive_rate, true_positive_rate, thresholds = roc_curve(y_test, y_pred)
   roc_auc = auc(false_positive_rate, true_positive_rate)
   average_precision2 = average_precision_score(y_test, y_pred)
   precision2, recall2, thresholds = precision_recall_curve(y_test, y_pred)
   #test_results1.append(average_precision2)
   test_results2.append(precision2[1])
   test_results3.append(recall2[1])

plt.figure("max depths")

#line1, = plt.plot(max_depths, train_results1, "b", label="Train average")
#line2,= plt.plot(max_depths, test_results1, "b--", label="Test average")

line3, = plt.plot(max_depths, train_results2, "r", label="Train précision")
line4,= plt.plot(max_depths, test_results2, "r--", label="Test précision")

line5, = plt.plot(max_depths, train_results3, "g", label="Train recall")
line6,= plt.plot(max_depths, test_results3, "g--", label="Test recall")

plt.ylabel("Score")
plt.xlabel("max_depth")
plt.legend()
plt.show()


from azure.cli.testsdk.reverse_dependency import get_dummy_cli
from azext_iot.dps.providers.discovery import DPSDiscovery
from azext_iot.tests.settings import Setting

def test_dps_discovery(provisioned_iot_dps_no_hub_module):
    dps_name = provisioned_iot_dps_no_hub_module["name"]
    dps_rg = provisioned_iot_dps_no_hub_module["resourceGroup"]
    cmd_shell = Setting()
    setattr(cmd_shell, "cli_ctx", get_dummy_cli())
    desired_policy_name = "provisioningserviceowner"
    discovery = DPSDiscovery(cmd_shell)

    resource = discovery.find_resource(resource_name=dps_name)
    assert resource.name == dps_name

    auto_policy = discovery.find_policy(resource_name=dps_name, rg=dps_rg).as_dict()
    assert auto_policy

    # Assumption - Test DPS includes the vanilla provisioningserviceowner policy
    desired_policy = discovery.find_policy(
        resource_name=dps_name, rg=dps_rg, policy_name=desired_policy_name
    ).as_dict()
    assert desired_policy["key_name"] == desired_policy_name

    policies = discovery.get_policies(resource_name=dps_name, rg=dps_rg)
    assert len(policies)

    # Example for leveraging discovery to build cstring for every policy on target DPS
    cstrings = [discovery._build_target(resource=resource, policy=p)["cs"] for p in policies]
    assert len(cstrings)

    sub_dps = discovery.get_resources()
    assert sub_dps

    filtered_sub_dps = [
        dps for dps in sub_dps if dps.as_dict()["name"] == dps_name
    ]
    assert filtered_sub_dps

    rg_dpss = discovery.get_resources(rg=dps_rg)
    assert rg_dpss

    filtered_rg_dpss = [dps for dps in rg_dpss if dps.as_dict()["name"] == dps_name]
    assert filtered_rg_dpss

    assert len(rg_dpss) <= len(sub_dps)

def test_dps_targets(provisioned_iot_dps_no_hub_module):
    dps_name = provisioned_iot_dps_no_hub_module["name"]
    dps_rg = provisioned_iot_dps_no_hub_module["resourceGroup"]
    dps_host_name = provisioned_iot_dps_no_hub_module['dps']['properties']['serviceOperationsHostName']
    cmd_shell = Setting()
    setattr(cmd_shell, "cli_ctx", get_dummy_cli())
    discovery = DPSDiscovery(cmd_shell)

    auto_target = discovery.get_target(resource_name=dps_name)
    assert_target(auto_target, rg=dps_rg)
    connection_string = auto_target["cs"]

    cs_target1 = discovery.get_target_by_cstring(connection_string)
    assert_target(cs_target1, True)

    cs_target2 = discovery.get_target(resource_name=None, login=connection_string)
    assert_target(cs_target2, True)

    cs_target2 = discovery.get_target(resource_name=dps_host_name)
    assert_target(cs_target2, True)

    auto_target = discovery.get_target(resource_name=dps_name, resource_group_name=dps_rg)
    assert_target(auto_target, rg=dps_rg)

    sub_targets = discovery.get_targets()
    [assert_target(tar) for tar in sub_targets]

    rg_targets = discovery.get_targets(resource_group_name=dps_rg)
    [assert_target(tar, rg=dps_rg) for tar in rg_targets]

    assert len(rg_targets) <= len(sub_targets)

def assert_target(target: dict, by_cstring=False, **kwargs):
    assert target["cs"]
    assert target["policy"]
    assert target["primarykey"]
    assert target["entity"]

    if not by_cstring:
        assert target["secondarykey"]
        assert target["subscription"] and target["subscription"] != "unknown"


import argparse
import calendar
import datetime
import math
from typing import List, Optional

import svgwrite

from .exceptions import PosterError
from .poster import Poster
from .track import Track
from .tracks_drawer import TracksDrawer
from .utils import compute_grid
from .value_range import ValueRange
from .xy import XY

class CircularDrawer(TracksDrawer):
    """Draw a circular Poster for each of the Poster's tracks.

    Attributes:
        _rings: True if distance rings should be drawn, else False.
        _ring_color: Color of distance rings.

    Methods:
        create_args: Set up an argparser for circular poster options.
        fetch_args: Get args from argparser.
        draw: Draw each year on the Poster.
    """

    def __init__(self, the_poster: Poster):
        """Init the CircularDrawer with default values for _rings and _ring_color

        Note that these can be overridden via arguments when calling."""
        super().__init__(the_poster)
        self._rings = False
        self._ring_color = "darkgrey"

    def create_args(self, args_parser: argparse.ArgumentParser):
        """Add arguments to the parser"""
        group = args_parser.add_argument_group("Circular Type Options")
        group.add_argument(
            "--circular-rings",
            dest="circular_rings",
            action="store_true",
            help="Draw distance rings.",
        )
        group.add_argument(
            "--circular-ring-color",
            dest="circular_ring_color",
            metavar="COLOR",
            type=str,
            default="darkgrey",
            help="Color of distance rings.",
        )

    def fetch_args(self, args):
        """Get arguments from the parser"""
        self._rings = args.circular_rings
        self._ring_color = args.circular_ring_color

    def draw(self, dr: svgwrite.Drawing, size: XY, offset: XY):
        """Draw the circular Poster using distances broken down by time"""
        if self.poster.tracks is None:
            raise PosterError("No tracks to draw.")
        if self.poster.length_range_by_date is None:
            return

        years = self.poster.years.count()
        _, counts = compute_grid(years, size)
        if counts is None:
            raise PosterError("Unable to compute grid.")
        count_x, count_y = counts[0], counts[1]
        x, y = 0, 0
        cell_size = size * XY(1 / count_x, 1 / count_y)
        margin = XY(4, 4)
        if count_x <= 1:
            margin.x = 0
        if count_y <= 1:
            margin.y = 0
        sub_size = cell_size - 2 * margin
        for year in range(self.poster.years.from_year, self.poster.years.to_year + 1):
            self._draw_year(dr, sub_size, offset + margin + cell_size * XY(x, y), year)
            x += 1
            if x >= count_x:
                x = 0
                y += 1

    def _draw_year(self, dr: svgwrite.Drawing, size: XY, offset: XY, year: int):
        min_size = min(size.x, size.y)
        outer_radius = 0.5 * min_size - 6
        radius_range = ValueRange.from_pair(outer_radius / 4, outer_radius)
        center = offset + 0.5 * size

        if self._rings:
            self._draw_rings(dr, center, radius_range)

        year_style = f"dominant-baseline: central; font-size:{min_size * 4.0 / 80.0}px; font-family:Arial;"
        month_style = f"font-size:{min_size * 3.0 / 80.0}px; font-family:Arial;"

        dr.add(
            dr.text(
                f"{year}",
                insert=center.tuple(),
                fill=self.poster.colors["text"],
                text_anchor="middle",
                alignment_baseline="middle",
                style=year_style,
            )
        )
        df = 360.0 / (366 if calendar.isleap(year) else 365)
        day = 0
        date = datetime.date(year, 1, 1)
        while date.year == year:
            text_date = date.strftime("%Y-%m-%d")
            a1 = math.radians(day * df)
            a2 = math.radians((day + 1) * df)
            if date.day == 1:
                (_, last_day) = calendar.monthrange(date.year, date.month)
                a3 = math.radians((day + last_day - 1) * df)
                sin_a1, cos_a1 = math.sin(a1), math.cos(a1)
                sin_a3, cos_a3 = math.sin(a3), math.cos(a3)
                r1 = outer_radius + 1
                r2 = outer_radius + 6
                r3 = outer_radius + 2
                dr.add(
                    dr.line(
                        start=(center + r1 * XY(sin_a1, -cos_a1)).tuple(),
                        end=(center + r2 * XY(sin_a1, -cos_a1)).tuple(),
                        stroke=self.poster.colors["text"],
                        stroke_width=0.3,
                    )
                )
                path = dr.path(
                    d=("M", center.x + r3 * sin_a1, center.y - r3 * cos_a1),
                    fill="none",
                    stroke="none",
                )
                path.push(
                    f"a{r3},{r3} 0 0,1 {r3 * (sin_a3 - sin_a1)},{r3 * (cos_a1 - cos_a3)}"
                )
                dr.add(path)
                tpath = svgwrite.text.TextPath(
                    path, date.strftime("%B"), startOffset=(0.5 * r3 * (a3 - a1))
                )
                text = dr.text(
                    "",
                    fill=self.poster.colors["text"],
                    text_anchor="middle",
                    style=month_style,
                )
                text.add(tpath)
                dr.add(text)
            if text_date in self.poster.tracks_by_date:
                self._draw_circle_segment(
                    dr,
                    self.poster.tracks_by_date[text_date],
                    a1,
                    a2,
                    radius_range,
                    center,
                )

            day += 1
            date += datetime.timedelta(1)

    def _determine_ring_distance(self) -> Optional[float]:
        length_range = self.poster.length_range_by_date
        ring_distance = None
        for distance in [1.0, 5.0, 10.0, 50.0]:
            if self.poster.units != "metric":
                # convert from miles to meters
                distance *= 1609.344
            else:
                # convert from km to meters
                distance *= 1000.0
            if length_range.upper() < distance:
                continue
            ring_distance = distance
            if (length_range.upper() / distance) <= 5:
                break
        return ring_distance

    def _draw_rings(self, dr: svgwrite.Drawing, center: XY, radius_range: ValueRange):
        length_range = self.poster.length_range_by_date
        ring_distance = self._determine_ring_distance()
        if ring_distance is None:
            return
        distance = ring_distance
        while distance < length_range.upper():
            radius = (
                radius_range.lower()
                + radius_range.diameter() * distance / length_range.upper()
            )
            dr.add(
                dr.circle(
                    center=center.tuple(),
                    r=radius,
                    stroke=self._ring_color,
                    stroke_opacity="0.2",
                    fill="none",
                    stroke_width=0.3,
                )
            )
            distance += ring_distance

    def _draw_circle_segment(
        self,
        dr: svgwrite.Drawing,
        tracks: List[Track],
        a1: float,
        a2: float,
        rr: ValueRange,
        center: XY,
    ):
        length = sum([t.length for t in tracks])
        has_special = len([t for t in tracks if t.special]) > 0
        color = self.color(self.poster.length_range_by_date, length, has_special)
        r1 = rr.lower()
        r2 = (
            rr.lower()
            + rr.diameter() * length / self.poster.length_range_by_date.upper()
        )
        sin_a1, cos_a1 = math.sin(a1), math.cos(a1)
        sin_a2, cos_a2 = math.sin(a2), math.cos(a2)
        path = dr.path(
            d=("M", center.x + r1 * sin_a1, center.y - r1 * cos_a1),
            fill=color,
            stroke="none",
        )
        path.push("l", (r2 - r1) * sin_a1, (r1 - r2) * cos_a1)
        path.push(f"a{r2},{r2} 0 0,0 {r2 * (sin_a2 - sin_a1)},{r2 * (cos_a1 - cos_a2)}")
        path.push("l", (r1 - r2) * sin_a2, (r2 - r1) * cos_a2)
        dr.add(path)


"""Damda Weather's sensor entity."""
from homeassistant.core import callback

from .const import (
    SENSOR_DOMAIN,
    DEVICE_CLASS,
    DEVICE_ICON,
    DEVICE_UNIQUE,
    DEVICE_UNIT,
    NAME,
)
from homeassistant.components.sensor import SensorEntity
from .dweather_device import DWeatherDevice
from .api_dweather import get_api
import logging

_LOGGER = logging.getLogger(__name__)

def log(flag, val):
    """0:debug, 1:info, 2:warning, 3:error."""
    if flag == 0:
        _LOGGER.debug(f"[{NAME}] Sensor > {val}")
    elif flag == 1:
        _LOGGER.info(f"[{NAME}] Sensor > {val}")
    elif flag == 2:
        _LOGGER.warning(f"[{NAME}] Sensor > {val}")
    elif flag == 3:
        _LOGGER.error(f"[{NAME}] Sensor > {val}")

def isfloat(value):
    """Determine string is float."""
    try:
        float(value)
        return True
    except ValueError:
        return False

def isnumber(value):
    """Determine string is number."""
    return (
        value is not None
        and isinstance(value, (str, int, float))
        and (
            isinstance(value, str)
            and (value.isnumeric() or value.isdigit())
            or isfloat(value)
        )
    )

async def async_setup_entry(hass, config_entry, async_add_entities):
    """Set up sensor for Damda Waether component."""

    @callback
    def async_add_entity(devices=[]):
        """Add sensor from api_dweather."""
        entities = []
        api = get_api(hass, config_entry)
        if api:
            try:
                if len(devices) == 0:
                    devices = api.sensors()
            except Exception:
                devices = []
            for device in devices:
                if DEVICE_UNIQUE not in device:
                    continue
                if not api.search_entity(SENSOR_DOMAIN, device[DEVICE_UNIQUE]):
                    entities.append(DWeatherSensor(device, api))

        if entities:
            async_add_entities(entities)

    api = get_api(hass, config_entry)
    if api:
        api.load(SENSOR_DOMAIN, async_add_entity)

    async_add_entity()

class DWeatherSensor(DWeatherDevice, SensorEntity):
    """Representation of a DamdaWeather sensor."""

    TYPE = SENSOR_DOMAIN

    @property
    def state(self):
        """Return the state of the sensor."""
        state = self.api.get_state(self.unique_id)
        return state

    @property
    def icon(self):
        """Return the icon of the sensor."""
        value = self.api.get_state(self.unique_id, DEVICE_ICON)
        return value

    @property
    def device_class(self):
        """Return the class of the sensor."""
        value = self.api.get_state(self.unique_id, DEVICE_CLASS)
        return value

    @property
    def unit_of_measurement(self):
        """Return the unit of measurement of this sensor."""
        value = self.api.get_state(self.unique_id, DEVICE_UNIT)
        return value

    @property
    def state_class(self):
        """Type of this sensor state."""
        return "measurement" if isnumber(self.state) else None


from collections import namedtuple
import youtube_dl

SearchResult = namedtuple('SearchResult', [
    "location",
    "name",
    "artist",
    "album",
])

class Searcher:
    @staticmethod
    def search(query, autogenerated=True):
        ydl_url = Searcher.construct_ydl_url(query, autogenerated)
        opts = {"quiet": True}
        with youtube_dl.YoutubeDL(opts) as ydl:
            ydl_result = ydl.extract_info(ydl_url, download=False)
            return Searcher.extract_result(ydl_result)

    @staticmethod
    def construct_ydl_url(query, autogenerated):
        if(autogenerated):
            query = '{} "Auto-generated by YouTube"'.format(query)
        return 'ytsearch1:{}'.format(query)

    @staticmethod
    def extract_result(ydl_result):
        # get the first search result if there is one
        entry = next(iter(ydl_result["entries"]), None)
        if entry is None:
            return None

        url = entry["webpage_url"]
        title = entry["title"]
        description = entry["description"].split("\n\n")

        name = title
        artist = None
        album = None

        # if we know how to read the description extract the info from it
        if Searcher.is_description_autogenerated(description, title):
            name, artist = description[1].split(" \u00B7 ", 1)
            album = description[2]

        return SearchResult(location=url, name=name, artist=artist, album=album)

    @staticmethod
    def is_description_autogenerated(description, title):
        """
        Auto-generated YouTube uploads have a very particular structure that is checked here.
        """
        return (len(description) > 3 and
                description[0].startswith("Provided to YouTube by ") and
                description[1].startswith(title + " \u00B7 ") and
                description[-1].strip() == "Auto-generated by YouTube."
        )


import abc
import asyncio
import collections
import contextlib
import inspect
import logging.handlers
import signal
import sys
from typing import Awaitable, Callable, Dict, Generic, GenericMeta, Optional, Type, TypeVar, Union
import weakref

from .config import Config

LOG = logging.getLogger(__name__)

Self = TypeVar('Self')

class Runnable(collections.Awaitable):
    """
    Runnable is a convenience wrapper around asyncio.Task with distinct flow:
      - `initialize` is called only once, and is the best place to allocate task-related resources or abort execution
        entirely due to some precondition
      - `main` is where all the work happens
      - `cleanup` is called only once after main returns or raises

    Each runnable has an associated `name` (ivar) and `LOG` (cvar):
      - `name` defaults to classname and can be customized via `__init__`
      - `LOG` defaults to __module__.__qualname__ (e.g. my.app.Service) and can be customized as any other cvar

    As asyncio's Task, Runnable can either complete by return, due to exception or by being cancelled.
    Completion due to exception (including cancellation) is considered an abnormal abort.

    A concept of abortion is just a convenience to distinguish non-clean exits and otherwise identical to stop.

    >>> class Service(Runnable):
    >>>     async def initialize(self):
    >>>         # It's safe to allocate resources that require event loop here
    >>>         if not await allocate_resources():
    >>>             self.abort()
    >>>             return
    >>>
    >>>         super().initialize()
    >>>
    >>>     async def main(self):
    >>>         await do_some_work()
    >>>
    >>>     async def cleanup(self, exc_type=None, exc_val=None, exc_tb=None):
    >>>         await dealloc_resources()
    >>>
    >>> s = Service(name='MyService')
    >>> await s.start()

    @cvar LOG: For each subclass new LOG variable is automatically created unless explicitly set.
    """
    LOG: logging.Logger = LOG.getChild('Runnable')

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)

        if 'LOG' not in cls.__dict__:
            cls.LOG = logging.getLogger('{}.{}'.format(cls.__module__, cls.__qualname__))

    def __init__(self, *, name: str = None) -> None:
        self._name = name or type(self).__name__

        self._run_f = None

        self._initialize_f = None
        self._main_f = None
        self._cleanup_f = None

        self._should_stop = False
        self._is_initialized = False
        self._is_aborted = False

    @property
    def name(self) -> str:
        """
        Name of the runnable.
        """
        return self._name

    @property
    def should_stop(self) -> bool:
        """
        Whether runnable should stop.
        """
        return self._should_stop

    @property
    def is_initialized(self) -> bool:
        """
        Whether runnable is initialized.

        Can be used to detect errors during initialization.
        """
        return self._is_initialized

    @property
    def is_aborted(self) -> bool:
        """
        Whether runnable is aborted, e.g. due to exception.
        """
        return self._is_aborted

    @property
    def is_started(self) -> bool:
        """
        Whether task is started.
        """
        return self._run_f is not None

    @property
    def is_alive(self) -> bool:
        """
        Whether task was started and still running.
        """
        return self._run_f and not self._run_f.done()

    @property
    def is_done(self) -> bool:
        """
        Whether task was started and completed its execution.
        """
        return self._run_f and self._run_f.done()

    async def initialize(self) -> None:
        """
        Convenience method that's called only once before `main`.

        Subclasses must call super(), usually at the end of the custom implementation.

        If abort or stop is called, neither main nor cleanup will be called and underlying task will finish
        as soon as possible.

        @see: abort
        """
        self.LOG.debug("\"%s\" initialized.", self.name)
        self._is_initialized = True

    @abc.abstractmethod
    async def main(self):
        """
        Subclasses must implement this method.

        @see: initialize
        @see: cleanup
        """
        pass

    async def cleanup(self, exc_type=None, exc_val=None, exc_tb=None) -> None:
        """
        Convenience method that's called only once after `main` exits.
        """
        pass

    def start(self: Self, *, loop: asyncio.AbstractEventLoop = None) -> Self:
        """
        Schedule runnable execution.

        Create and configure underlying asyncio.Task.

        @raise RuntimeError: If started more than once.
        """
        if self._run_f:
            raise RuntimeError(f"\"{self.name}\" can only be started once")

        self.LOG.debug("\"%s\" started.", self.name)
        self._run_f = asyncio.ensure_future(self.run(), loop=loop)
        self._run_f.add_done_callback(self.on_run_done)

        if self.should_stop:
            self._run_f.cancel()

        return self

    async def run(self):
        self._initialize_f = asyncio.ensure_future(self.initialize())
        self._initialize_f.add_done_callback(self.on_initialize_done)
        await self._initialize_f

        if not self.is_initialized and not self.should_stop:
            raise NotImplementedError("either super or abort()/stop() must be called in overridden initialize()")
        elif self.should_stop:
            return

        try:
            self._main_f = asyncio.ensure_future(self.main())
            self._main_f.add_done_callback(self.on_main_done)
            result = await self._main_f
        except:
            self._cleanup_f = asyncio.ensure_future(self.cleanup(*sys.exc_info()))
            self._cleanup_f.add_done_callback(self.on_cleanup_done)
            await self._cleanup_f
            raise
        else:
            self._cleanup_f = asyncio.ensure_future(self.cleanup())
            self._cleanup_f.add_done_callback(self.on_cleanup_done)
            await self._cleanup_f

        return result

    def stop(self) -> None:
        """
        Stop runnable by cancelling wrapped task.
        """
        self.LOG.debug("\"%s\" stopped.", self.name)

        if not self._should_stop:
            self._should_stop = True

            if self._run_f:
                self._run_f.cancel()

    def abort(self) -> None:
        """
        Same as stop, but sets the abort flag.

        @see: stop
        """
        self.LOG.debug("\"%s\" aborted.", self.name)
        self._is_aborted = True
        self.stop()

    def on_run_done(self, f: asyncio.Task) -> None:
        """
        Called when the run task is done.
        """
        assert f == self._run_f

        if self._run_f.cancelled():
            if not self._should_stop:
                self.LOG.info("\"%s\" task was manually cancelled.", self.name)
        elif self._run_f.exception() is not None:
            self.LOG.exception("\"%s\" task failed with exception:", self.name, exc_info=self._run_f.exception())
            self._is_aborted = True
        else:
            self.LOG.debug("\"%s\" task finished.", self.name)

        self._should_stop = True

    def on_initialize_done(self, f: asyncio.Task) -> None:
        """
        Called when the initialize task is done.
        """
        assert f == self._initialize_f

    def on_main_done(self, f: asyncio.Task) -> None:
        """
        Called when the main task is done.
        """
        assert f == self._main_f

    def on_cleanup_done(self, f: asyncio.Task) -> None:
        """
        Called when the cleanup task is done.
        """
        assert f == self._cleanup_f

    async def __aenter__(self):
        return self.start()

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        self.stop()

        with contextlib.suppress(asyncio.CancelledError):
            await self

    def __await__(self):
        if self._run_f:
            return self._run_f.__await__()
        else:
            raise RuntimeError(f"\"{self.name}\" is not running")

    def __repr__(self):
        return '<{}(name={})>'.format(type(self).__name__, self.name)

    def __del__(self):
        if getattr(self, '_run_f', None) and not self._run_f.done():
            self.LOG.error("\"%s\" is destroyed with pending task.", self.name)

AppType = TypeVar('AppType', bound='App')
ConfigType = TypeVar('ConfigType', bound=Config)
ServiceType = TypeVar('ServiceType', bound='Service')

class App(Runnable, Generic[ConfigType]):
    """
    App is the root runnable for the application.

    It's semantics is alike Thread: user can either subclass it and override main
    or provide a callable that returns a coroutine.

    App handles the SIGINT and SIGTERM signals by stopping itself.

    >>> class MyApp(App):
    >>>     async def main(self):
    >>>         a_service = ...
    >>>         b_service = ...
    >>>         await asyncio.gather(a_service, b_service)
    >>>
    >>> MyApp().exec()

    Alternatively:

    >>> async with App():
    >>>     a_service = ...
    >>>     b_service = ...
    >>>     await asyncio.gather(a_service, b_service)
    """
    _current_apps: Dict[weakref.ReferenceType, 'App'] = weakref.WeakValueDictionary()

    @classmethod
    def current_app(cls: Type[AppType], loop: asyncio.AbstractEventLoop = None) -> Optional[AppType]:
        """
        Return App for the current event loop.
        """
        try:
            loop = loop or asyncio.get_event_loop()
            loop_ref = weakref.ref(loop)
        except RuntimeError:
            cls.LOG.warning("There is no current asyncio event loop.")
            return None

        app = cls._current_apps.get(loop_ref)

        if app is None:
            cls.LOG.debug("There is no active App in event loop %s.", loop)

        return app

    def __init_subclass__(cls, **kwargs):
        super(GenericMeta, cls).__setattr__('_gorg', cls)
        super().__init_subclass__(**kwargs)

    def __init__(self, target: Union[Callable[[], Awaitable], Runnable] = None, *, config: ConfigType = None, name: str = None) -> None:
        """
        @param target: Either coroutine or Runnable that will be awaited. If None, main must be overridden.
        """
        super().__init__(name=name)
        self._target = target
        self._config = config
        self._is_context = False
        self._loop_ref = None

    @property
    def config(self) -> Optional[ConfigType]:
        return self._config

    def exec(self, *, loop: asyncio.AbstractEventLoop = None):
        """
        Convenience method to start and await completion of the application.

        CancelledError is ignored as an expected way to complete execution.
        """
        loop = loop or asyncio.get_event_loop()

        try:
            t = self.start(loop=loop)
            return loop.run_until_complete(t)
        except asyncio.CancelledError:
            self.LOG.info("\"%s\" is cancelled.", self.name)

    #{ Runnable

    def start(self, *, loop=None):
        loop = loop or asyncio.get_event_loop()
        self._loop_ref = weakref.ref(loop, lambda ref: self.__class__._current_apps.pop(ref, None))

        if self._loop_ref in self.__class__._current_apps:
            raise RuntimeError("only one app can be active in an event loop")
        else:
            self.__class__._current_apps[self._loop_ref] = self

        return super().start(loop=loop)

    def on_run_done(self, f):
        super().on_run_done(f)

        if not self._is_context:
            del self.__class__._current_apps[self._loop_ref]

    async def initialize(self):
        await super().initialize()

        loop = asyncio.get_event_loop()

        try:
            loop.add_signal_handler(signal.SIGINT, self.stop)
            loop.add_signal_handler(signal.SIGTERM, self.stop)
        except NotImplementedError:
            self.LOG.debug("%s does not implement add_signal_handler", loop)

    async def main(self):
        if self._target:
            if isinstance(self._target, Runnable) and not self._target.is_started:
                return await self._target.start()
            elif inspect.isawaitable(self._target):
                return await self._target
            else:
                return await asyncio.ensure_future(self._target())

    async def __aenter__(self):
        r = await super().__aenter__()
        self._is_context = True
        return r

    async def __aexit__(self, *args, **kwargs):
        try:
            return await super().__aexit__(*args, **kwargs)
        finally:
            del self.__class__._current_apps[self._loop_ref]
            self._is_context = False
    #}

class Service(Runnable, Generic[AppType, ConfigType]):
    """
    Service is an asynchronous task for the app.
    """
    def __init_subclass__(cls, **kwargs):
        super(GenericMeta, cls).__setattr__('_gorg', cls)
        super().__init_subclass__(**kwargs)

    def __init__(self, *, app: AppType = None, config: ConfigType = None, name: str = None) -> None:
        """
        @param app: App that owns the service. If None, will be resolved at the beginning of the service's execution.
        @param config: Custom config.
        """
        super().__init__(name=name)
        self._app = app
        self._config = config

    @property
    def app(self) -> Optional[AppType]:
        return self._app

    @property
    def config(self) -> Optional[ConfigType]:
        return self._config or self.app.config

    #{ Runnable

    async def run(self, *args, **kwargs):
        current_app = App.current_app()

        if current_app is None:
            raise RuntimeError(f"{self.name} must run inside an app")
        elif self._app is None:
            self._app = current_app
        elif self._app != current_app:
            raise RuntimeError(f"{self.name} should run in {self._app.name} but runs in {current_app.name} instead")

        return await super().run(*args, **kwargs)

    #}


from CameraAndDetector import *
import cv2
import apis
import time

def distance_duck(s):
    return 2421.692084 / s - 8.566887384

def theta_duck(u):
    return -0.00172753493 * u + 0.5294127344

def blob_to_optitrack(blob, x_t, angle):
    u = blob[0]
    s = blob[2]

    dist_to_camera = 0.16 # meters

    dist_to_duck = distance_duck(s) / 100.0 # cm to m
    angle_to_duck = theta_duck(u)

    #print("Duck dist", dist_to_duck)
    #print("Duck angle", angle_to_duck)

    p_duck = np.array([dist_to_duck * np.cos(angle_to_duck) + dist_to_camera, dist_to_duck * np.sin(angle_to_duck)])

    #print("Pos duck in robot frame", pos_duck_in_robot_frame)

    #print(x_t)

    theta = angle

    T = np.array([[np.cos(theta), -np.sin(theta), x_t[0]],
                  [np.sin(theta), np.cos(theta), x_t[1]],
                  [0., 0., 1.]])

    vec = np.array([p_duck[0], p_duck[1], 1.])

    res = np.dot(T, vec)

    return np.array([res[0], res[1]])

class CirclePath:

    def __init__(self, position, factor, radius):
        self.start = time.time()
        self.init, _ = position.get()
        self.factor = factor
        self.radius = radius

    def get_next(self):
        t = time.time() - self.start
        if t / self.factor >= 2. * np.pi:
            return self.init
        return self.radius * np.array([np.sin(t/self.factor) + self.init[0], np.cos(t/self.factor) - 1.0 + self.init[1]])

if __name__ == "__main__":

    camera = Camera(raspberrypi = True)
    robot = apis.LocalRobot()
    position = apis.Position("192.168.0.207", "192.168.0.4", 207)

    try:

        path = CirclePath(position, 3.0, 1.0)

        while True:
            blobs = camera.get_blobs()

            x_t, angle = position.get()

            if blobs is not None:
                for blob in blobs[0, :]:
                    p_d = blob_to_optitrack(blob, x_t, angle)
                    print(p_d[0], p_d[1] ,sep=",")

            x_d = path.get_next()

            K1 = 1000
            K2 = 2000

            dist, desired_angle = apis.dist_and_angle(x_d, x_t)

            v = K1 * dist
            omega = K2 * apis.angle_diff(desired_angle, angle)

            u = np.array([v - omega, v + omega])

            robot.set_motor(u[0], u[0], u[1], u[1])

            time.sleep(0.1)

    except KeyboardInterrupt:
        pass

    robot.shutdown()
    camera.close()
    cv2.destroyAllWindows()


import turtle
import random
import math

# Set up the Turtle screen
wn = turtle.Screen()
wn.bgcolor("white")
wn.title("Approximating Pi")

# Create a Turtle object
pi_approximation_turtle = turtle.Turtle()
pi_approximation_turtle.penup()
pi_approximation_turtle.hideturtle()

# Initialize global counters
inside_circle = 0
total_points = 0

# Function to draw the approximation
def draw_approximation():
    global inside_circle, total_points
    x, y = random.uniform(-1, 1), random.uniform(-1, 1)
    total_points += 1
    distance = math.sqrt(x**2 + y**2)

    if distance <= 1:
        inside_circle += 1
        pi_approximation_turtle.color("blue")
    else:
        pi_approximation_turtle.color("red")

    pi_approximation_turtle.goto(x * 200, y * 200)
    pi_approximation_turtle.dot()

    # Calculate pi approximation
    pi_approximation = 4 * inside_circle / total_points

    # Update the title
    wn.title(f"Approximating Pi: {pi_approximation:.8f}")

# Function to update the approximation
def update_approximation():
    draw_approximation()
    wn.ontimer(update_approximation, 10)  # 10 millisecond delay for a faster frame rate

# Start the animation
update_approximation()

# Close the Turtle graphics window by clicking it
wn.exitonclick()


import numpy as np
from sklearn.svm import SVC
import pandas as pd
from sklearn.grid_search import GridSearchCV
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import MultinomialNB
from sklearn.externals import joblib
import json
from collections import Counter

def getWords(topWordsFile):
    topwords = json.load(topWordsFile)
    wordCounter = Counter()
    for key in topwords.keys():
        for word in topwords[key]:
            wordCounter.update([word[0]])
    return list(wordCounter.keys())

def create_train():
  df = pd.read_csv('data/pre_train.csv')
  X = df.iloc[:, :-1]
  y = df.iloc[:, -1]
  X = X.values
  X = [element[0] for element in X]

  sentiment_encoder = LabelEncoder()
  y = sentiment_encoder.fit_transform(y)
  print(sentiment_encoder.classes_)
  with open('./newTopWords.json') as topWordsFile:
    vocabulary = getWords(topWordsFile)
  tfidf = TfidfVectorizer()

  X = tfidf.fit_transform(X)

  X_train, X_test, y_train, y_test = train_test_split(
            X, y, test_size=0.3, random_state=1)

  svm_model = SVC(probability=True, kernel='linear', C=1, class_weight='balanced')

  search_parameters = {
      'degree': [2, 3, 4], 'gamma': (np.arange(0.1, 1.1, 0.1)), 'C': (np.arange(0.1, 1.1, 0.1)), 'kernel': ['linear']
  }
  # model_svm = GridSearchCV(
  #     svm_model, search_parameters, cv=5, scoring='accuracy', n_jobs=8)
  svm_model.fit(X_train, y_train)
  # print(model_svm.best_score_)
  # print(model_svm.best_params_)
  y_pred = svm_model.predict(X_test)
  print(metrics.accuracy_score(y_pred, y_test))
  print("model trained")

  # gnb = MultinomialNB()
  # gnb.fit(X_train, y_train)
  # y_pred = gnb.predict(X_test)
  # print(metrics.accuracy_score(y_pred, y_test))
  joblib.dump(svm_model, 'model_linear_svm_tfidf_w.pkl')

def main():
  create_train()

if __name__ == '__main__':
  main()


import numpy as np
import torch.nn as nn
from mmcv.cnn import normal_init

from mmpose.core.evaluation.top_down_eval import keypoints_from_heatmaps
from mmpose.core.evaluation import pose_pck_accuracy
from mmpose.core.post_processing import flip_back
from mmpose.models.builder import HEADS, build_loss

from .utils.tokenbase import TokenPose_TB_base

BN_MOMENTUM = 0.1

@HEADS.register_module()
class TokenPoseHead(nn.Module):
    """
    "TokenPose: Learning Keypoint Tokens for Human Pose Estimation".

    Args:
        in_channels (int): Number of input channels
        num_joints (int): Number of joints
        loss_keypoint (dict): Config for keypoint loss. Default: None.
        tokenpose_cfg (dict): Config for tokenpose.
    """

    def __init__(self,
                 in_channels,
                 num_joints,
                 loss_keypoint=None,
                 tokenpose_cfg=None,
                 train_cfg=None,
                 test_cfg=None):
        super().__init__()

        self.in_channels = in_channels
        self.num_joints = num_joints

        self.loss = build_loss(loss_keypoint)

        self.train_cfg = {} if train_cfg is None else train_cfg
        self.test_cfg = {} if test_cfg is None else test_cfg
        self.target_type = self.test_cfg.get('target_type', 'GaussianHeatmap')

        self.tokenpose_cfg = {} if tokenpose_cfg is None else tokenpose_cfg

        self.tokenpose = TokenPose_TB_base(feature_size=tokenpose_cfg.feature_size,
                                           patch_size=tokenpose_cfg.patch_size,
                                           num_keypoints=self.num_joints,
                                           dim=tokenpose_cfg.dim,
                                           depth=tokenpose_cfg.depth,
                                           heads=tokenpose_cfg.heads,
                                           mlp_ratio=tokenpose_cfg.mlp_ratio,
                                           heatmap_size=tokenpose_cfg.heatmap_size,
                                           channels=in_channels,
                                           pos_embedding_type=tokenpose_cfg.pos_embedding_type,
                                           apply_init=tokenpose_cfg.apply_init)

    def forward(self, x):
        """Forward function."""
        if isinstance(x, list):
            x = x[0]
        x = self.tokenpose(x)
        return x

    def get_loss(self, output, target, target_weight):
        """Calculate top-down keypoint loss.

        Note:
            - batch_size: N
            - num_keypoints: K
            - heatmaps height: H
            - heatmaps weight: W

        Args:
            output (torch.Tensor[N,K,H,W]): Output heatmaps.
            target (torch.Tensor[N,K,H,W]): Target heatmaps.
            target_weight (torch.Tensor[N,K,1]):
                Weights across different joint types.
        """
        losses = dict()

        assert not isinstance(self.loss, nn.Sequential)
        assert target.dim() == 4 and target_weight.dim() == 3

        losses['heatmap_loss'] = self.loss(output.pred, target, target_weight)

        return losses

    def get_accuracy(self, output, target, target_weight):
        """Calculate accuracy for top-down keypoint loss.

        Note:
            - batch_size: N
            - num_keypoints: K
            - heatmaps height: H
            - heatmaps weight: W

        Args:
            output (torch.Tensor[N,K,H,W]): Output heatmaps.
            target (torch.Tensor[N,K,H,W]): Target heatmaps.
            target_weight (torch.Tensor[N,K,1]):
                Weights across different joint types.
        """

        accuracy = dict()

        if self.target_type == 'GaussianHeatmap':
            _, avg_acc, _ = pose_pck_accuracy(
                output.pred.detach().cpu().numpy(),
                target.detach().cpu().numpy(),
                target_weight.detach().cpu().numpy().squeeze(-1) > 0)
            accuracy['acc_pose'] = float(avg_acc)

        return accuracy

    def inference_model(self, x, flip_pairs=None):
        """Inference function.

        Returns:
            output_heatmap (np.ndarray): Output heatmaps.

        Args:
            x (torch.Tensor[N,K,H,W]): Input features.
            flip_pairs (None | list[tuple]):
                Pairs of keypoints which are mirrored.
        """
        output = self.forward(x)
        output = output.pred

        if flip_pairs is not None:
            output_heatmap = flip_back(
                output.detach().cpu().numpy(),
                flip_pairs,
                target_type=self.target_type)
            # feature is not aligned, shift flipped heatmap for higher accuracy
            if self.test_cfg.get('shift_heatmap', False):
                output_heatmap[:, :, :, 1:] = output_heatmap[:, :, :, :-1]
        else:
            output_heatmap = output.detach().cpu().numpy()
        return output_heatmap

    def decode(self, img_metas, output, **kwargs):
        """Decode keypoints from heatmaps.

        Args:
            img_metas (list(dict)): Information about data augmentation
                By default this includes:

                - "image_file: path to the image file
                - "center": center of the bbox
                - "scale": scale of the bbox
                - "rotation": rotation of the bbox
                - "bbox_score": score of bbox
            output (np.ndarray[N, K, H, W]): model predicted heatmaps.
        """
        batch_size = len(img_metas)

        if 'bbox_id' in img_metas[0]:
            bbox_ids = []
        else:
            bbox_ids = None

        c = np.zeros((batch_size, 2), dtype=np.float32)
        s = np.zeros((batch_size, 2), dtype=np.float32)
        image_paths = []
        score = np.ones(batch_size)
        for i in range(batch_size):
            c[i, :] = img_metas[i]['center']
            s[i, :] = img_metas[i]['scale']
            image_paths.append(img_metas[i]['image_file'])

            if 'bbox_score' in img_metas[i]:
                score[i] = np.array(img_metas[i]['bbox_score']).reshape(-1)
            if bbox_ids is not None:
                bbox_ids.append(img_metas[i]['bbox_id'])

        preds, maxvals = keypoints_from_heatmaps(
            output,
            c,
            s,
            unbiased=self.test_cfg.get('unbiased_decoding', False),
            post_process=self.test_cfg.get('post_process', 'default'),
            kernel=self.test_cfg.get('modulate_kernel', 11),
            valid_radius_factor=self.test_cfg.get('valid_radius_factor',
                                                  0.0546875),
            use_udp=self.test_cfg.get('use_udp', False),
            target_type=self.test_cfg.get('target_type', 'GaussianHeatmap'))

        all_preds = np.zeros((batch_size, preds.shape[1], 3), dtype=np.float32)
        all_boxes = np.zeros((batch_size, 6), dtype=np.float32)
        all_preds[:, :, 0:2] = preds[:, :, 0:2]
        all_preds[:, :, 2:3] = maxvals
        all_boxes[:, 0:2] = c[:, 0:2]
        all_boxes[:, 2:4] = s[:, 0:2]
        all_boxes[:, 4] = np.prod(s * 200.0, axis=1)
        all_boxes[:, 5] = score

        result = {}

        result['preds'] = all_preds
        result['boxes'] = all_boxes
        result['image_paths'] = image_paths
        result['bbox_ids'] = bbox_ids

        return result

    def init_weights(self):
        # normal_init(self.fc, mean=0, std=0.01, bias=0)
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                # nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                nn.init.normal_(m.weight, std=0.001)
                # nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.BatchNorm2d):
                nn.init.constant_(m.weight, 1)
                nn.init.constant_(m.bias, 0)
            elif isinstance(m, nn.ConvTranspose2d):
                nn.init.normal_(m.weight, std=0.001)
                if self.deconv_with_bias:
                    nn.init.constant_(m.bias, 0)


#Falling Distance Problem
t = float(input("Enter a time (in seconds) "))
g = 9.8
def myFunction():
    results = 0.5 * g * t ** 2
    return results

print("Falling Distance for an object that has been falling for 10 seconds is",myFunction(),"meters")

#Future Value Problem
P = float(input("Enter present value "))
i = float(input("Enter interest rate "))
t = float(input("Enter number of months "))
def futureValue():
    F = P * (1 + i) ** t
    return F

print("The information for your account is:")
print("Present value: $",P)
print("Interest rate: %",i)
print("After 18 months, the value of your account will be $",futureValue())