#7.	Dadas dos listas enlazadas simples ya creadas (PTR1 y PTR2) ordenadas
#ascendentemente, hacer un algoritmo que cree una tercera lista PTR3
#ordenada descendentemente con los elementos comunes de las dos listas.

from List import List,Node

PTR1 = List(list=[1,3,5,7,9,10])
PTR2 = List(list=[1,2,4,5,6,6,7,8,9,11])

PTR3 = List()

i = PTR1.first
while i:
    if PTR2.count(i.data) > 0:
        PTR3.append(i.data)
    i = i.next

PTR3.reverse()

PTR3.show()


from __future__ import annotations

import traceback

from PySide6 import QtWidgets

from randovania.games.prime2.patcher.claris_randomizer import ClarisRandomizerExportError

def create_box_for_exception(val: Exception) -> QtWidgets.QMessageBox:
    box = QtWidgets.QMessageBox(
        QtWidgets.QMessageBox.Critical,
        "An exception was raised",
        (
            f"An unhandled Exception occurred:\n{val}\n\n"
            "When reporting, make sure to paste the entire contents of the following box."
            "\nIt has already be copied to your clipboard."
        ),
        QtWidgets.QMessageBox.Ok,
    )
    from randovania.gui.lib import common_qt_lib

    common_qt_lib.set_default_window_icon(box)

    detailed_exception = "".join(traceback.format_exception(val))
    if isinstance(val, ClarisRandomizerExportError):
        detailed_exception += "\n\n"
        detailed_exception += val.detailed_text()

    box.setDetailedText(detailed_exception)

    common_qt_lib.set_clipboard(detailed_exception)

    # Expand the detailed text
    for button in box.buttons():
        if box.buttonRole(button) == QtWidgets.QMessageBox.ActionRole:
            button.click()
            break

    box_layout: QtWidgets.QGridLayout = box.layout()
    box_layout.addItem(
        QtWidgets.QSpacerItem(600, 0, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding),
        box_layout.rowCount(),
        0,
        1,
        box_layout.columnCount(),
    )
    return box


import scrapy

class KistaSpider(scrapy.Spider):
    name = "kista"

    def start_requests(self):
        urls = ['https://www.hemnet.se/bostader?location_ids%5B%5D=473377&item_types%5B%5D=bostadsratt',
        ]
        for url in urls:
            yield scrapy.Request(url=url, callback=self.parse)

    def parse(self, response):
        yield {
            'sold': response.css("span.result-type-toggle__sold-count::text").re(r'\d+'),
            'for_sell': response.css("span.result-type-toggle__for-sale-count::text").re(r'\d+')
        }


# 从爬虫生成的Excel表格中读取数据并生成词云图
import os
import sys
import PIL
import jieba
import openpyxl
import wordcloud
import configparser
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
from multiprocessing import Pool

# 定义一些参数，参数的详细介绍见GitHub上的readme.md
config_file = 'config/config.ini'
config_Section_Name = 'GC_DEFAULT'  # 要读取的配置页名
stop_Word = ['!', '！', ':', '*', '，', ',', '？','《','》',
             '。', ' ', '的', '了', '是', '啊', '吗', '吧','这','你','我','他','就']  # 停用词表

def read_Danmu(workbook_Name, sheet_Name):  # 从Excel表中读取数据
    try:
        workbook = openpyxl.load_workbook(workbook_Name)
        worksheet = workbook[sheet_Name]  # 当然也可以通过索引读sheet,为了可读性选择用名称
        data = worksheet.iter_rows(values_only=1)
        return data
    #若报错，则返回空迭代器
    except openpyxl.utils.exceptions.InvalidFileException:
        print(f"输入文件的路径或格式错误，请打开{config_file}文件重新配置路径\n")
        return iter(())
    except KeyError:
        print(f"工作表页名错误，请检查Sheet的名字和{config_file}中是否一致\n")
        return iter(())
    except:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        print(f"发生错误: {exc_type} - {exc_value}")
        return iter(())

def cut_words(row):
    try:
        # 每行第一列是弹幕，第二列是出现次数
        sentence = row[0]
        count = row[1]
        # 运用jieba 进行分词，将结果储存在Counter中，再将其中词语的出现次数翻count倍
        words = jieba.lcut(sentence)
        # 去除停用词表中的词
        cut_Words = pd.Series(words)
        cut_Words = cut_Words[~cut_Words.isin(stop_Word)]
        # 将分词存入计数器中
        new_Counter = Counter(cut_Words.tolist())
        for item in new_Counter:
            new_Counter[item] *= count              # 弹幕中词语出现数 = 弹幕出现次数*弹幕中词语出现次数
        return new_Counter
    except TypeError:
        return Counter()                            #遇见异常输入的情况，返回空计数器。

def generate_Word_Cloud(counter):  # 生成词云图
    try:
        if not counter:  # 如果计数器对象为空，则给出提示并退出函数
            return "输入的词频为空！"
        img = PIL.Image.open(pic_Path).convert('RGBA') # 解决灰度图像ERROR
        pic = np.array(img)
        image_colors = wordcloud.ImageColorGenerator(pic)
        word_Cloud = wordcloud.WordCloud(
            font_path=font_Path, mask=pic, width=WC_Width, height=WC_Height, mode="RGBA", background_color='white')
        word_Cloud.generate_from_frequencies(counter)
        plt.imshow(word_Cloud.recolor(color_func=image_colors),
                interpolation='bilinear')
        word_Cloud.to_file(output_Path)
        plt.axis('off')
        plt.show()
        return f"词云图生成完成，请前往{output_Path}查看"
    except FileNotFoundError : #pic_Path 或 font_Path错误的情况
        return f"图片或字体路径错误，请前往{config_file}核查。"
    except TypeError or ValueError : #WC_Width 或WC_Height类型或数组错误的情况
        return f"图片的Height与Width设置有误，请前往{config_file}核查。"
    except PIL.UnidentifiedImageError :
        return f"不支持该类型的图片，请修改图片路径。"
    except Exception as e:
        return f"生成词云图时发生错误：{e}"

def main():
    rows = read_Danmu(workbook_Name, sheet_Name)
    word_counts = Counter()
    # 利用线程池优化分词速度，在生成所有弹幕的词云图是能节省时间
    with Pool() as pool:
        cut_words_results = pool.map(cut_words, rows)
        for result in cut_words_results:
            word_counts.update(result)

    print(generate_Word_Cloud(word_counts))

if __name__ == "__main__":
    # 读取参数的配置
    config = configparser.ConfigParser()
    if not os.path.exists(config_file):
        print(f"配置文件 {config_file} 不存在！")
        exit(1)
    config.read(config_file)
    workbook_Name = config.get(config_Section_Name, 'workbook_name',
                               fallback='output/Top_20_danmu.xlsx')  # 要读取的Excel表的名称，默认为crawler.py生成的文件
    # 要读取的Excel表的页的名称，可从['Top 20', '所有弹幕']中选择
    sheet_Name = config.get(config_Section_Name, 'sheet_Name', fallback='所有弹幕')
    WC_Width = config.getint(
        config_Section_Name, 'WC_Width', fallback=1200)  # 词云图的宽度
    WC_Height = config.getint(
        config_Section_Name, 'WC_Height', fallback=1200)  # 词云图的高度
    font_Path = config.get(config_Section_Name, 'font_Path',
                           fallback="config/msyh.ttc")  # 字体存储路径
    pic_Path = config.get(config_Section_Name, 'pic_Path',
                          fallback="config/m.png")  # 词云背景图路径
    output_Path = config.get(
        config_Section_Name, 'output_Path', fallback="output/word_could.png")
    main()


import math
from visual import*
import Image
dx=-50
dy=15

#Green comment block was originally user input for drop position, etc.,
#but was commented out, just not deleted.
"""
dx=-20
dy=input("please input the drop y position....recommand 10 or higher")

w=input("if you know the bounce height press '1', if you dont press '2' :")
if w==1:
    bh=input("enter the 1st bounce height")
    res=sqrt(bh/dy)##the equation for resitution
else:
    res=.89

else :
    print("try the balls we know!" )
    type1=input("press '1' for b-ball, '2' for tennis ball")
    if type1==1:#b ball
        res=0.83#restitution
    elif type1==2:#t ball
        res=0.72
    else:           #no friction ball. no restitution
        res=1
"""

im = Image.open('tennisball.jpg')
tex = materials.texture(data=im, mapping='spherical')

im2 = Image.open('BasketballColor.jpg')
tex2 = materials.texture(data=im2, mapping='spherical')

im3 = Image.open('golfball.jpg')
tex3 = materials.texture(data=im3, mapping='spherical')

floor = box(pos=(0,0,0), length=100, height=0.5, width=2, color= (1,1,1), material=materials.wood) #width=5, #edit
floor1 = box(pos=(0,0,-5), length=100, height=0.5, width=2, color= (1,1,1), material=materials.wood)
floor2 = box(pos=(0,0,5), length=100, height=0.5, width=2, color= (1,1,1), material=materials.wood)
floor3 = box(pos=(0,0,-10), length=100, height=0.5, width=2, color= (1,1,1), material=materials.wood)

pball = sphere(pos=(dx,dy,-10), radius=1.5, color=color.red, make_trail=True, material=materials.emissive) #edit
ball = sphere(pos=(dx,dy,0), radius=1, material=tex, make_trail=True, color=color.green)
ball2 = sphere(pos=(dx,dy,-5), radius=2, material=tex2, make_trail=True, color=color.orange) #the starting point of the ball .. add z value to make it 3d
ball3 = sphere(pos=(dx,dy,5), radius=.5, material=tex3, make_trail=True)

pball.velocity = vector(4,0)
ball.velocity = vector(4,0)
ball2.velocity = vector(4,0)
ball3.velocity = vector(4,0)#(4,0,0) for 3d motion

gravity = 9.81

dt = 0.01 #delta time frame of the ball
while true:

    rate(100) #rate of speed

    pball.pos = pball.pos + pball.velocity*dt   #ball.pos += velocity*dt
    ball.pos = ball.pos + ball.velocity*dt      #ball.pos += velocity*dt
    ball2.pos = ball2.pos + ball2.velocity*dt   #ball.pos += velocity*dt
    ball3.pos = ball3.pos + ball3.velocity*dt   #ball.pos += velocity*dt

    if pball.y < .5:
        pball.velocity.y = abs(pball.velocity.y)
    else:
        pball.velocity.y = pball.velocity.y - gravity*dt

    if ball.y < .5:
        ball.velocity.y = abs(ball.velocity.y*0.905)
    else:
        ball.velocity.y = ball.velocity.y - gravity*dt

    if ball2.y < .5:
        ball2.velocity.y = abs(ball2.velocity.y*0.79)
    else:
        ball2.velocity.y = ball2.velocity.y - gravity*dt

    if ball3.y < .5:
        ball3.velocity.y = abs(ball3.velocity.y*0.78)
    else:
        ball3.velocity.y = ball3.velocity.y - gravity*dt
"""NOTE:
        All lines are original, except for the if-else statements, which are edited, unless otherwise stated.
"""


import random
import numpy as np
from math import sqrt, log
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

x1_list = []
x2_list = []
y_list = []
counter = 0

def drawFunc(minX, minY, maxX, maxY, ax = None):
    #fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
    #ax.set_xlabel('x1')
    #ax.set_ylabel('x2')
    #ax.set_zlabel('f(x1,x2)')

    x1_array = np.arange(minX, maxX, 0.1)
    x2_array = np.arange(minY, maxY, 0.1)
    x1_array, x2_array = fill_arrays(x1_array, x2_array)
    R = fill_z(x1_array, x2_array)

    x1_array = np.arange(minX, maxX, 0.1)
    x2_array = np.arange(minY, maxY, 0.1)
    x1_array, x2_array = np.meshgrid(x1_array, x2_array)
    #R = f(x1_array, x2_array)

    #drawBoder(ax, x1_array, g1_1)
    #drawBoder(ax, x1_array, g2_1)
    #drawBoder(ax, x1_array, g3_1)
    #drawBoder(ax, x1_array, g4_1)

    #print(R)
    ax.plot_surface(x1_array, x2_array, R, alpha = 0.6)
    #plt.show()

def fill_arrays(x, y):
    final_y = []
    final_x = []
    for i in range(len(y)):
        final_y.append([])
        for j in range(len(x)):
            if (barier(x[j], y[i])):
                #if f(x[j], y[i]) > 50:
                    #print("i =", i, "j =", j)
                    #print("x =", x[j], "y =", y[i], "f =", f(x[j], y[i]))
                final_y[i].append(x[j])
            else: final_y[i].append(0)

    for i in range(len(x)):
        final_x.append([])
        for j in range(len(y)):
            if (barier(x[j], y[i])):
                final_x[i].append(y[j])
            else: final_x[i].append(0)

    #for i in range(len(final_x)):
    #    print(i,")", final_x[i])
    return final_y, final_x

def fill_z(x, y):
    z = []
    for i in range(len(x)):
        z.append([])
        for j in range(len(x[i])):
            if (x[i][j] != 0 and y[j][i] != 0):
                z[i].append(f(x[i][j], y[j][i]))
            else: z[i].append(0.0)
            #print("i =", i, "j =", j)
            #print("x =", x[i][j], "y =", y[j][i], "z =", z[i][j])

    #for i in range(len(z)):
    #    print(i,")", z[i])
    r = np.array(z)
    #for i in range(len(z)):
    #    r.__add__(np.array[z[i]])
    return r

def fill_F2(x, y):
    z = []
    for i in range(len(x)):
        z.append([])
        for j in range(len(x[i])):
            if (barier(x[i][j], y[i][j])):
                z[i].append(f(x[i][j], y[i][j]))
            else: z[i].append(0.0)

    r = np.array(z)
    #for i in range(len(z)):
    #    r.__add__(np.array[z[i]])
    #print(r)
    return r

def g1_1(x1):
    return (-3*x1 + 6) / 2

def g2_1(x1):
    return (-x1 - 3) / (-1)

def g3_1(x1):
    return (x1 - 7) / (-1)

def g4_1(x1):
    return (2*x1 - 4) / 3

def drawBoder(ax, x1, g):
    zs = np.arange(0, 80, 35)

    X, Z = np.meshgrid(x1, zs)
    Y = g(X)

    #fig = plt.figure()
    #ax = fig.add_subplot(111, projection='3d')
    ax.plot_surface(X, Y, Z, alpha = 0.4)

def show(x1_list, x2_list):
    N = int(x1_list.__len__())
    if (N <= 0):
        return

    fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
    ax.set_xlabel('x1')
    ax.set_ylabel('x2')
    ax.set_zlabel('f(x1,x2)')
    #x1_array = np.arange(min(x1_list) - 0.1, max(x1_list) + 0.1, 0.1)
    #x2_array = np.arange(min(x2_list) - 0.1, max(x2_list) + 0.1, 0.1)
    #x1_array, x2_array = np.meshgrid(x1_array, x2_array)
    #R = f(x1_array, x2_array)
    #ax.plot_surface(x1_array, x2_array, R, color='b', alpha=0.5)
    drawFunc(0, 0, 5, 5, ax)

    x1_list2 = []
    x2_list2 = []
    f_list = []

    ax.scatter(x1_list[0], x2_list[0], f(x1_list[0], x2_list[0]), c='black')
    x1_list2.append(x1_list[0])
    x2_list2.append(x2_list[0])
    f_list.append(f(x1_list[0], x2_list[0]))

    for n in range(1, N - 1):
        ax.scatter(x1_list[n], x2_list[n], f(x1_list[n], x2_list[n]), c='red')
        x1_list2.append(x1_list[n])
        x2_list2.append(x2_list[n])
        f_list.append(f(x1_list[n], x2_list[n]))

    ax.scatter(x1_list[N - 1], x2_list[N - 1], f(x1_list[N - 1], x2_list[N - 1]), c='green')
    x1_list2.append(x1_list[N - 1])
    x2_list2.append(x2_list[N - 1])
    f_list.append(f(x1_list[N - 1], x2_list[n]))

    ax.plot(x1_list2, x2_list2, f_list, color="black")

    plt.show()

# <---------- f
def f(x1, x2):
    return (x1-6)**2 +(x2-7)**2

def f_x1(x1, x2):
    return 2*x1 - 12

def f_x2(x1, x2):
    return 2*x2 - 14
# -------------->

# <---------- gi
def g1(x1, x2):
    return -3*x1 - 2*x2 + 6

def g2(x1, x2):
    return -x1 + x2 - 3

def g3(x1, x2):
    return x1 + x2 - 7

def g4(x1, x2):
    return 2*x1 - 3*x2 - 4
# -------------->

# <---------- gi_bool
def g1_bool(x1, x2):
    return -3*x1 - 2*x2 + 6 <= 0

def g2_bool(x1, x2):
    return -x1 + x2 - 3 <= 0

def g3_bool(x1, x2):
    return x1 + x2 - 7 <= 0

def g4_bool(x1, x2):
    return 2*x1 - 3*x2 - 4 <= 0

def barier(x1, x2):
    return (g1_bool(x1, x2) and g2_bool(x1, x2) and g3_bool(x1, x2) and g4_bool(x1, x2))

# -------------->

# <---------- X
def F(x1, x2, r):
    return f(x1,x2) + P(x1, x2, r)

def F_x1(x1, x2, r):
    return f_x1(x1, x2) + P_x1(x1, x2, r)

def F_x2(x1, x2, r):
    return f_x2(x1, x2) + P_x2(x1, x2, r)
# -------------->

# <-------------- P
def P(x1, x2, r):
    sum = 1/g1(x1, x2) + 1/g2(x1, x2) + 1/g3(x1, x2) + 1/g4(x1, x2)
    return -r*sum

def P_x1(x1, x2, r):
    sum = 3/(g1(x1, x2)**2) + 1/(g2(x1, x2)**2) - 1/(g3(x1, x2)**2) - 1/(g4(x1, x2)**2)
    return -r*sum

def P_x2(x1, x2, r):
    sum = 2/(g1(x1, x2)**2) - 1/(g2(x1, x2)**2) - 1/(g3(x1, x2)**2) + 3/(g4(x1, x2)**2)
    return -r*sum

# ------------>

def gradient(x1, x2, r):
    i = F_x1(x1, x2, r)
    j = F_x2(x1, x2, r)
    return [i, j]

def module_of_gradient(grad):
    i = 0; j = 1
    return sqrt(grad[i]**2 + grad[j]**2)

def method_of_gradient_descent_with_a_constant_step(x1, x2, e, M, r):
    global counter
    k = 0
    counter += 1
    x1_next = x1
    x2_next = x2
    while True:
        counter += 2
        grad = gradient(x1, x2, r)
        module_grad = module_of_gradient(grad)

        if ((module_grad < e) and (k >= M)):
            return (x1_next, x2_next)

        gamma = 0.1
        x1_next = x1 - gamma * grad[0]
        x2_next = x2 - gamma * grad[1]

        counter += 2
        while (F(x1_next, x2_next, r) - F(x1, x2, r) >= 0 or not barier(x1_next, x2_next)):
            gamma /= 4
            x1_next = x1 - gamma * grad[0]
            x2_next = x2 - gamma * grad[1]
            counter += 1

        #print(grad, 'x1 =', x1, 'x2 =', x2, 'x1_next =', x1_next, 'x2_next =', x2_next, 'gamma =', gamma)

        x1_list.append(x1); x2_list.append(x2)
        if ((sqrt(abs(x1_next - x1)**2 + abs(x2_next - x2)**2) <= e)
            & (abs(F(x1_next, x2_next, r) - F(x1, x2, r)) <= e)):
            return (x1_next, x2_next)

        x1 = x1_next
        x2 = x2_next
        k += 1

def barrier_function_method(x1, x2, r, C, e, M, k):
    min_x1, min_x2 = method_of_gradient_descent_with_a_constant_step(x1, x2, e, M, r)
    #print("x1 =", min_x1, "x2 =", min_x2)
    fine = P(min_x1, min_x2, r)
    #print("fine =", fine)
    if (abs(fine) <= e):
            return [(round(min_x1, round_num),
                     round(min_x2, round_num),
                     round(f(min_x1, min_x2), round_num)),
                    k]
    k += 1
    r = r/C
    return barrier_function_method(min_x1, min_x2, r, C, e, M, k)

round_num = 4
x1 = 2.5
x2 = 1
e = 0.0001
M = 100
r = 1
c = 10
k = 0

result = barrier_function_method(x1, x2, r, c, e, M, k)
print(f"Barrier function method: {result[0]}; count of iteractions = {result[1]}")
print('Count of compute function =', counter + 1)

show(x1_list, x2_list)
#drawFunc(0, 0, 5, 5)

6 Семестр/Оптимизация/Lab_6_grad.py


from datetime import datetime
from maico.sensor.stream import Confluence
from maico.sensor.targets.human import Human
from maico.sensor.targets.human_feature import MoveStatistics
from maico.sensor.targets.first_action import FirstActionFeature
import maico.sensor.streams.human_stream as hs

class OneToManyStream(Confluence):
    KINECT_FPS = 30
    FRAMES_FOR_MOVE = 15
    MOVES_FOR_STAT = 4

    def __init__(self, human_stream):

        self._observation_begin = None

        # hyper parameters (it will be arguments in future)
        self.move_threshold = 0.1  # above this speed, human act to move (not searching items)

        self.move_stream = hs.MoveStream(human_stream, self.FRAMES_FOR_MOVE, self.KINECT_FPS, self.move_threshold)
        self.move_stat_stream = hs.MoveStatisticsStream(self.move_stream, self.MOVES_FOR_STAT)
        super(OneToManyStream, self).__init__(human_stream, self.move_stat_stream)

    def notify(self, target):
        key = target.__class__

        if key is Human:
            self._pool[key] = [target]  # store only 1 (latest) human
            if self._observation_begin is None:
                self._observation_begin = datetime.utcnow()  # remember first human
        else:
            if key not in self._pool:
                self._pool[key] = []
            self._pool[key].append(target)

        if self.is_activated():
            t = self.merge()
            self.out_stream.push(t)
            self.reset()

    def is_activated(self):
        hs = self.get(Human)
        stats = self.get(MoveStatistics)

        if len(hs) == 1 and len(stats) == 1:
            return True
        else:
            return False

    def merge(self):
        h = self.get(Human)[0]
        stat = self.get(MoveStatistics)[0]
        staying_time = (datetime.utcnow() - self._observation_begin).total_seconds()

        feature = FirstActionFeature(
            _id=h._id,
            staying_time=staying_time,
            mean_moving_rate=stat.moving_time.sum_ / stat.seconds.sum_,
            max_moving_rate=stat.moving_time.max_ / stat.seconds.mean_,
            min_moving_rate=stat.moving_time.min_ / stat.seconds.mean_,
            mean_moving_speed=stat.moving_speed.mean_
            )
        return feature


"""
This file is part of Candela.

Candela is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Candela is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Candela.  If not, see <http://www.gnu.org/licenses/>.
"""
import curses
import sys
import signal
import threading
import textwrap
import platform

import constants

class Shell():
    """
    The main Candela class
    Controls the shell by taking control of the current terminal window.
    Performs input and output to the user
    """
    def __init__(self, scriptfile=None):
        """
        Create an instance of a Shell
        This call takes over the current terminal by calling curses.initscr()
        Sets global shell state, including size information, menus, stickers,
        the header, and the prompt.

        Kwargs:
        scriptfile - the name of the script file to run. If not None and the
                     file exists, the script will be immediately run.
        """
        self._register_sigint_handler()

        self.script_lines = self._parse_script_file(scriptfile)
        self.script_counter = 0
        self.scriptfile = ""

        self.stdscr = curses.initscr()
        self.stdscr.keypad(1)

        self.platform = self._get_platform()

        # holds the backlog of shell output
        self.backbuffer = []
        self.height,self.width = self.stdscr.getmaxyx()

        # the list of menus in the shell app
        self.menus = []
        # the currently visible stickers in the app
        self.stickers = []

        # should the command menu be shown
        self.should_show_help = True
        # for commands with only positional args, show the
        # name of the next argument as the user types
        self.should_show_hint = False

        # dictionary of functions to call on key events
        # keys are chars representing the pressed keys
        self.keyevent_hooks = {}

        # the text to stick in the upper left corner of the window
        self.header = ""
        self._header_bottom = 0
        self._header_right = 0
        self._header_right_margin = 50

        self.prompt = "> "

    def _parse_script_file(self, filename):
        """
        Open a file if it exists and return its contents as a list of lines

        Args:
        filename - the file to attempt to open
        """
        self.scriptfile = filename
        try:
            f = open(filename, 'r')
            script_lines = f.readlines()
            script_lines = [a.strip('\n') for a in script_lines]
            f.close()
        except Exception as e:
            return
        return script_lines

    def runscript(self, scriptfile):
        """
        Set up the global shell state necessary to run a script from a file

        Args:
        scriptfile - the string name of the file containing the script.
                     paths are relative to system cwd
        """
        self.script_lines = self._parse_script_file(scriptfile)
        self.script_counter = 0

    def get_helpstring(self):
        """
        Get the help string for the current menu.

        This string contains a preformatted list of commands and their
        descriptions from the current menu.
        """
        _menu = self.get_menu()
        if not _menu:
            return

        helpstring = "\n\n" + _menu.title + "\n" + "-"*20 + "\n" + _menu.options()
        return helpstring

    def sticker(self, output, new_output="", pos=None):
        """
        Place, change, or remove a sticker from the shell window.

        Candela has the concept of a sticker - a small block of text that
        is "stuck" to the window. They can be used to convey persistent
        information to the shell user.

        If only output is specified, this creates a new sticker with the string
        output. If output and new_output are specified, and there is an existing
        sticker whose text is the same as output, this will replace that
        sticker's text with new_output.

        Args:
        output      - The text of the sticker to manipulate

        Kwargs:
        new_output  - The text that will replace the text of the chosen sticker
        pos         - The (y, x) tuple indicating where to place the sticker
        """
        if len(self.stickers) > 0:
            sort = sorted(self.stickers, key=lambda x: x[1][0], reverse=True)
            ht = sort[0][1][0]+1
        else:
            ht = 3

        pos = pos or (ht, self.width - 20)

        match = None
        for text,_pos in self.stickers:
            if output == text:
                match = (text,_pos)
                break
        if match:
            self.remove_sticker(match[0])

        sticker = (new_output or output, match[1] if match else pos)
        self.stickers.append(sticker)

        self._update_screen()

    def remove_sticker(self, text):
        """
        Remove the sticker with the given text from the window

        Args:
        text    - The text of the sticker to remove
        """
        self.stickers = [a for a in self.stickers if a[0] != text]

    def _print_stickers(self):
        """
        Print all current stickers at the appropriate positions
        """
        for text,pos in self.stickers:
            _y,_x = pos
            if _x + len(text) > self.width:
                _x = self.width - len(text) - 1
            self.stdscr.addstr(_y, _x, text)

    def _print_header(self):
        """
        Print the header in the appropriate position
        """
        ht = 0
        for line in self.header.split("\n"):
            self.stdscr.addstr(ht, 0, line + (" "*self._header_right_margin))
            if len(line) > self._header_right:
                self._header_right = len(line)
            ht += 1
        self.stdscr.addstr(ht, 0, " "*(self._header_right+self._header_right_margin))
        self._header_bottom = ht
        self.mt_width = self._header_right + 49

    def clear(self):
        """
        Remove all scrollback text from the window
        """
        backbuffer = list(self.backbuffer)
        printstring = "\n"
        for i in range(self.height):
            self.put(printstring)

    def _print_backbuffer(self):
        """
        Print the previously printed output above the current command line.

        candela.shell.Shell stores previously printed commands and output
        in a backbuffer. Like a normal shell, it handles printing these lines
        in reverse order to allow the user to see their past work.
        """
        rev = list(self.backbuffer)
        rev.reverse()

        for i, tup in zip(range(len(rev)), rev):
            string, iscommand = tup
            ypos = self.height-2-i
            if ypos > 0:
                printstring = string
                if iscommand:
                    printstring = "%s%s" % (self.prompt, string)
                self.stdscr.addstr(ypos,0,printstring)

    def _print_help(self):
        """
        Print the menu help box for the current menu
        """
        _helpstring = self.get_helpstring()
        if not _helpstring:
            return
        helpstrings = [" %s" % a for a in _helpstring.split("\n")]
        ht = 0
        longest = len(max(helpstrings, key=len))
        _x = self._header_right + self._header_right_margin
        if _x + longest > self.width:
            _x = self.width - longest - 1
        for line in helpstrings:
            self.stdscr.addstr(ht, _x, line + " "*15)
            ht += 1

    def put(self, output, command=False):
        """
        Print the output string on the bottom line of the shell window
        Also pushes the backbuffer up the screen by the number of lines
        in output.

        Args:
        output  - The string to print. May contain newlines

        Kwargs:
        command - False if the string was not a user-entered command,
                  True otherwise (users of Candela should always use False)
        """
        self._update_screen()

        if not output:
            return

        output = str(output)

        _x,_y = (self.height-1, 0)

        lines = []
        for line in output.split('\n'):
            if len(line) > self.width - 3:
                for line in textwrap.wrap(line, self.width-3):
                    lines.append(line)
            else:
                lines.append(line)

        for line in lines:
            # put the line
            self.stdscr.addstr(_x, _y, line)

            # add it to backbuffer
            backbuf_string = line
            to_append = (backbuf_string, command)
            if line != self.prompt:
                index = 0
                if len(self.backbuffer) >= 200:
                    index = 1
                self.backbuffer = self.backbuffer[index:] + [to_append]

    def _input(self, prompt):
        """
        Handle user input on the shell window.
        Works similarly to python's raw_input().
        Takes a prompt and returns the raw string entered before the return key
        by the user.

        The input is returned withnewlines stripped.

        Args:
        prompt  - The text to display prompting the user to enter text
        """
        self.put(prompt)
        keyin = ''
        buff = ''
        hist_counter = 1
        while keyin != 10:
            keyin = self.stdscr.getch()
            _y,_x = self.stdscr.getyx()
            index = _x - len(self.prompt)
            #self.stdscr.addstr(20, 70, str(keyin))  # for debugging
            try:
                if chr(keyin) in self.keyevent_hooks.keys():
                    cont = self.keyevent_hooks[chr(keyin)](chr(keyin), buff)
                    if cont == False:
                        continue
            except:
                pass
            if keyin in [127, 263]:  # backspaces
                del_lo, del_hi = self._get_backspace_indices()
                buff = buff[:index+del_lo] + buff[index+del_hi:]
                self._redraw_buffer(buff)
                self.stdscr.move(_y, max(_x+del_lo, len(self.prompt)))
            elif keyin in [curses.KEY_UP, curses.KEY_DOWN]:  # up and down arrows
                hist_counter,buff = self._process_history_command(keyin, hist_counter)
            elif keyin in [curses.KEY_LEFT, curses.KEY_RIGHT]:  # left, right arrows
                if keyin == curses.KEY_LEFT:
                    newx = max(_x - 1, len(self.prompt))
                elif keyin == curses.KEY_RIGHT:
                    newx = min(_x + 1, len(buff) + len(self.prompt))
                self.stdscr.move(_y, newx)
            elif keyin == curses.KEY_F1:  # F1
                curses.endwin()
                sys.exit()
            elif keyin in [9]:  # tab
                choices = self._tabcomplete(buff)
                if len(choices) == 1:
                    if len(buff.split()) == 1 and not buff.endswith(' '):
                        buff = choices[0]
                    else:
                        if len(buff.split()) != 1 and not buff.endswith(' '):
                            buff = ' '.join(buff.split()[:-1])
                        if buff.endswith(' '):
                            buff += choices[0]
                        else:
                            buff += ' ' + choices[0]
                elif len(choices) > 1:
                    self.put("    ".join(choices))
                elif len(choices) == 0:
                    pass
                self._redraw_buffer(buff)
            elif keyin >= 32 and keyin <= 126:  # ascii input
                buff = buff[:index-1] + chr(keyin) + buff[index-1:]
                self._redraw_buffer(buff)
                self.stdscr.move(_y, min(_x, len(buff) + len(self.prompt)))
                if self.should_show_hint and keyin == 32:
                    command = self._get_command(buff)
                    if hasattr(command, 'definition') and '-' not in command.definition:
                        try:
                            nextarg = command.definition.split()[len(buff.split())]
                            self.stdscr.addstr(_y, _x+1, nextarg)
                            self.stdscr.move(_y, _x)
                        except:
                            pass
        self.put(buff, command=True)
        self.stdscr.refresh()
        return buff

    def _get_backspace_indices(self):
        if self.platform == "Linux":
            return (0, 1)
        elif self.platform == "Darwin":
            return (-len(self.prompt)-1, -len(self.prompt))

    def _tabcomplete(self, buff):
        """
        Get a list of possible completions for the current buffer

        If the current buffer doesn't contain a valid command, see if the
        buffer is a prefix of any valid commands. If so, return those as possible
        completions. Otherwise, delegate the completion finding to the command object.

        Args:
        buff    - The string buffer representing the current unfinished command input

        Return:
        A list of completion strings for the current token in the command
        """
        menu = self.get_menu()
        commands = []
        if menu:
            commands = menu.commands
        output = []
        if len(buff.split()) <= 1 and ' ' not in buff:
            for command in commands:
                if command.name.startswith(buff):
                    output.append(command.name)
                for alias in command.aliases:
                    if alias.startswith(buff):
                        output.append(alias)
        else:
            command = self._get_command(buff)
            if command:
                output = command._tabcomplete(buff)
        return output

    def _get_command(self, buff):
        """
        Get the command instance referenced by string in the current input buffer

        Args:
        buff    - The string version of the current command input buffer

        Return:
        The Command instance corresponding to the buffer command
        """
        menu = self.get_menu()
        commands = []
        if menu:
            commands = menu.commands
        if len(commands) == 0:
            self.put("No commands found. Maybe you forgot to set self.menus or self.menu?")
            self.put("Hint: use F1 to quit")
        for command in commands:
            if command.name == buff.split()[0] or buff.split()[0] in command.aliases:
                return command
        return None

    def _redraw_buffer(self, buff):
        """
        Clear the bottom line and re-print the given string on that line

        Args:
        buff    - The line to print on the cleared bottom line
        """
        self.stdscr.addstr(self.height-1, 0, " "*(self.width-3))
        self.stdscr.addstr(self.height-1, 0, "%s%s" % (self.prompt, buff))

    def _process_history_command(self, keyin, hist_counter):
        """
        Get the next command from the backbuffer and return it
        Also return the modified buffer counter.

        Args:
        keyin           - The key just pressed
        hist_counter    - The current position in the backbuffer
        """
        hist_commands = [(s,c) for s,c in self.backbuffer if c]
        if not hist_commands:
            return hist_counter, ""

        buff = hist_commands[-hist_counter][0]

        self.stdscr.addstr(self.height-1, 0, " "*(self.width-3))
        self.stdscr.addstr(self.height-1, 0, "%s%s" % (self.prompt, buff))

        if keyin == curses.KEY_UP and hist_counter < len(hist_commands):
            hist_counter += 1
        elif keyin == curses.KEY_DOWN and hist_counter > 0:
            hist_counter -= 1
        return hist_counter, buff

    def _script_in(self):
        """
        Substitute for _input used when reading from a script.
        Returns the next command from the script being read.
        """
        if not self.script_lines:
            return None

        if self.script_counter < len(self.script_lines):
            command = self.script_lines[self.script_counter]
            self.script_counter += 1
        else:
            command = None
        return command

    def main_loop(self):
        """
        The main shell IO loop.
        The sequence of events is as follows:
            get an input command
            split into tokens
            find matching command
            validate tokens for command
            run command

        This loop can be broken out of only with by a command returning
        constants.CHOICE_QUIT or by pressing F1
        """
        ret_choice = None
        while ret_choice != constants.CHOICE_QUIT:
            success = True
            ret_choice = constants.CHOICE_INVALID
            choice = self._script_in()
            if choice:
                self.put("%s%s" % (self.prompt, choice))
            else:
                choice = self._input(self.prompt)
            tokens = choice.split()
            if len(tokens) == 0:
                self.put("\n")
                continue
            command = self._get_command(choice)
            if not command:
                self.put("Invalid command - no match")
                continue
            try:
                args, kwargs = command.parse_command(tokens)
                success, message = command.validate(*args, **kwargs)
                if not success:
                    self.put(message)
                else:
                    ret_choice = command.run(*args, **kwargs)
                    if ret_choice == constants.CHOICE_INVALID:
                        self.put("Invalid command")
                    else:
                        menus = [a.name for a in self.menus]
                        if str(ret_choice).lower() in menus:
                            self.menu = ret_choice.lower()
                        else:
                            self.put("New menu '%s' not found" % ret_choice.lower())
            except Exception as e:
                self.put(e)
        return self

    def get_menu(self):
        """
        Get the current menu as a Menu
        """
        if not self.menus: return
        try:
            return [a for a in self.menus if a.name == self.menu][0]
        except:
            return

    def defer(self, func, args=(), kwargs={}, timeout_duration=10, default=None):
        """
        Create a new thread, run func in the thread for a max of
        timeout_duration seconds
        This is useful for blocking operations that must be performed
        after the next window refresh.
        For example, if a command should set a sticker when it starts executing
        and then clear that sticker when it's done, simply using the following
        will not work:

        def _run(*args, **kwargs):
            self.sticker("Hello!")
            # do things...
            self.remove_sticker("Hello!")

        This is because the sticker is both added and removed in the same
        refresh loop of the window. Put another way, the sticker is added and
        removed before the window gets redrawn.

        defer() can be used to get around this by scheduling the sticker
        to be removed shortly after the next window refresh, like so:

        def _run(*args, **kwargs):
            self.sticker("Hello!")
            # do things...
            def clear_sticker():
                time.sleep(.1)
                self.remove_sticker("Hello!")
            self.defer(clear_sticker)

        Args:
        func        - The callback function to run in the new thread

        Kwargs:
        args        - The arguments to pass to the threaded function
        kwargs      - The keyword arguments to pass to the threaded function
        timeout_duration - the amount of time in seconds to wait before
                           killing the thread
        default     - The value to return in case of a timeout
        """
        class InterruptableThread(threading.Thread):
            def __init__(self):
                threading.Thread.__init__(self)
                self.result = default
            def run(self):
                self.result = func(*args, **kwargs)
        it = InterruptableThread()
        it.start()
        it.join(timeout_duration)
        if it.isAlive():
            return it.result
        else:
            return it.result

    def end(self):
        """
        End the current Candela shell and safely shut down the curses session
        """
        curses.endwin()

    def _register_sigint_handler(self):
        """
        Properly handle ^C and any other method of sending SIGINT.
        This avoids leaving the user with a borked up terminal.
        """
        def signal_handler(signal, frame):
            self.end()
            sys.exit(0)
        signal.signal(signal.SIGINT, signal_handler)

    def _update_screen(self):
        """
        Refresh the screen and redraw all elements in their appropriate positions
        """
        self.height,self.width = self.stdscr.getmaxyx()
        self.stdscr.clear()

        self._print_backbuffer()

        if self.width < self._header_right + 80 or self.height < self._header_bottom + 37:
            pass
        else:
            self._print_header()
            if self.should_show_help:
                self._print_help()
        self._print_stickers()

        self.stdscr.refresh()

    def _get_platform(self):
        """
        Return the platform name. This is fine, but it's used in a hacky way to
        get around a backspace-cooking behavior in Linux (at least Ubuntu)
        """
        return platform.uname()[0]


import os
import LuckyDraw
import Quiz
import hangman
import time

def main():
    def title():
        clear()
        print("\t\t_______Game Vault______\n\n")

    def clear():
        os.system('cls')

    def delay():
        time.sleep(1)

    status = True
    while(status!=False):
        title()
        print("The available games are:")
        print("\n1.Hangman\n2.Luckydraw\n3.Quiz")
        ch=int(input("\n\nEnter your selection..\n\t\t:"))
        delay()
        if (ch==1):
            hangman.main()
        elif (ch==2):
            LuckyDraw.main()
        else:
            Quiz.main()
        title()
        c=input("Do you want to play another game?(y/n)\n\t\t:")
        c=c.lower()
        if c=='y':
            status=True
        else:
            status=False
    clear()
    print("\t\tThank you for visiting!!!!")
    delay()

if __name__ == "__main__":
    main()


# Exercise 1 : Family

# 1. Create a class called Family and implement the following attributes:

#       - members: list of dictionaries with the following keys : name, age, gender and is_child (boolean).
#       - last_name : (string)

    # Initial members data:

    # [
    #     {'name':'Michael','age':35,'gender':'Male','is_child':False},
    #     {'name':'Sarah','age':32,'gender':'Female','is_child':False}
    # ]

class Family() :
    def __init__(self, last_name):
        self.members = []
        self.last_name = last_name

    def member(self, name, age, gender, is_child):
        member = {
            'name': name,
            'age': age,
            'gender': gender,
            'is_child': is_child
        }
        self.members.append(member)

# 2. Implement the following methods:

#       - born: adds a child to the members list (use **kwargs), don’t forget to print a message congratulating the family.

    def born(self, **kwargs):
        self.child = {}
        for key, value in kwargs.items():
            self.child[key] = value
        self.members.append(self.child)
        if 'name' in self.child :
            print(f"Congratulations to the {self.last_name} family on the birth of {self.child['name']}!")
        elif 'gender' in self.child and self.child['gender'] == 'Male' :
            print(f"Congratulations to the {self.last_name} family on the birth of their babyboy!")
        elif 'gender' in self.child and self.child['gender'] == 'Female' :
            print(f"Congratulations to the {self.last_name} family on the birth of their babygirl!")
        else :
            print(f"Congratulations to the {self.last_name} family on the birth of their child!")

#       - is_18: takes the name of a family member as a parameter and returns True if they are over 18 and False if not.

    def is_18(self, name) :
        for member in self.members:
            if 'name' in member and member['name'] == name:
                return member['age'] >= 18
        return False

#       - family_presentation: a method that prints the family’s last name and all the members’ first name.

    def family_presentation(self) :
        print(f"The {self.last_name} family:")
        name_list = []
        for member in self.members:
            if 'name' in member:
                name_list.append(member['name'])
            elif 'gender' in member :
                if member['gender'] == 'Male' :
                    name_list.append('babyboy')
                elif member['gender'] == 'Female' :
                    name_list.append('babygirl')
                else :
                    name_list.append('baby')
            else :
                name_list.append('baby')
        names = ', '.join(name_list)
        print(names)

smiths = Family("Smith")
smiths.member('Michael', 35, 'Male', False)
smiths.member('Sarah', 32, 'Female', False)
for member in smiths.members:
    print(member)

smiths.born(name='Emily', age=0, gender='Female')
smiths.born(age=0, gender='Female')
smiths.born(age=0, gender='Male')
smiths.born(age=0)
for member in smiths.members:
    print(member)
print(smiths.is_18('Michael'))  # Output: True
print(smiths.is_18('Sarah'))  # Output: True
print(smiths.is_18('Emily'))  # Output: False
smiths.family_presentation()

# print(smiths.members)

# Exercise 2 : TheIncredibles Family

# 1. Create a class called TheIncredibles. This class should inherit from the Family class:
# This is no random family they are an incredible family, therefore we need to add the following
# keys to our dictionaries: power and incredible_name.

    # Initial members data:

    # [
    #     {'name':'Michael','age':35,'gender':'Male','is_child':False,'power': 'fly','incredible_name':'MikeFly'},
    #     {'name':'Sarah','age':32,'gender':'Female','is_child':False,'power': 'read minds','incredible_name':'SuperWoman'}
    # ]

class TheIncredibles(Family):
    def __init__(self, last_name):
        super().__init__(last_name)

    # def incredible_member(self, name, age, gender, is_child, power, incredible_name):
    #     super().member(name, age, gender, is_child)
    #     incredible_member = {
    #         'name': name,
    #         'age': age,
    #         'gender': gender,
    #         'is_child': is_child,
    #         'power' : power,
    #         'incredible_name' : incredible_name
    #     }
    #     self.members.append(incredible_member)

    def incredible_member(self, name, age, gender, is_child, power, incredible_name):
            member = {
                'name': name,
                'age': age,
                'gender': gender,
                'is_child': is_child,
                'power': power,
                'incredible_name': incredible_name
            }
            self.members.append(member)

# 2. Add a method called use_power, this method should print the power of a member only if they are over 18 years old.
#    If not raise an exception (look up exceptions) which stated they are not over 18 years old.

    def use_power(self, name):
        for member in self.members:
            if member['name'] == name:
                if member['age'] >= 18:
                    print(f"{member['name']} can use their power: {member['power']}")
                else:
                    raise Exception(f"{member['name']} is not over 18 years old and cannot use their power.")

# 3. Add a method called incredible_presentation which :
#       - Prints the family’s last name and all the members’ first name (ie. use the super() function,
#         to call the family_presentation method)
#       - Prints all the members’ incredible name and power.

    def incredible_presentation(self):
        super().family_presentation()
        for member in self.members:
            print(f"{member['incredible_name']} - Power: {member['power']}")

incredible_family = TheIncredibles("Incredible")
incredible_family.incredible_member('Michael', 35, 'Male', False, 'fly', 'MikeFly')
incredible_family.incredible_member('Sarah', 32, 'Female', False, 'read minds','SuperWoman')

# 4. Call the incredible_presentation method.

incredible_family.incredible_presentation()

# 5. Use the born method inherited from the Family class to add Baby Jack with the following power: “Unknown Power”.

incredible_family.born(name="Baby Jack", age=0, gender="Male", is_child=True, power="Unknown Power", incredible_name="BabyJack")

# 6. Call the incredible_presentation method again.

incredible_family.incredible_presentation()
incredible_family.use_power("Michael")
incredible_family.use_power("Sarah")
incredible_family.use_power("Baby Jack")


#!/usr/bin/env python3
"""Tools to define Templates.

Templates are very similar to plugins, but use jinja to transform `.enbt` template files upon installation.
"""
__author__ = "Miguel Hernández-Cabronero"
__since__ = "2021/08/01"

import sys
import argparse
import inspect
import os
import glob
import shutil
import tempfile
import jinja2
import stat

from .installable import Installable, InstallableMeta
import enb.config
from enb.config import options

class MetaTemplate(InstallableMeta):
    def __init__(cls, *args, **kwargs):
        if cls.__name__ != "Template":
            cls.tags.add("template")
        super().__init__(*args, **kwargs)

class Template(Installable, metaclass=MetaTemplate):
    """
    Base class to define templates. Subclasses must be defined in the __plugin__.py file of the template's
    source dir.

    - Templates copy the source dir's contents (except for __plugin__.py) and then transforms
      any `*.enbt` file applying jinja and removing that extension.

    - Templates may require so-called fields in order to produce output.
      These fields can be automatically taken from enb.config.ini (e.g., file-based configuration),
      passed as arguments to the template installation CLI, and programmatically.

    - One or more templates can be installed into an existing directory, the __plugin__.py file is not written
      by default to the installation dir.
    """
    # Map of required field names to their corresponding help
    required_fields_to_help = dict()

    # Files in the template's source dir ending with templatable_extension
    # are subject to jinja templating upon installation.
    templatable_extension = ".enbt"

    @classmethod
    def get_fields(cls, original_fields=None):
        try:
            return cls._fields
        except AttributeError:
            # If there are required fields, satisfy them or fail
            fields = dict(original_fields) if original_fields is not None else dict()
            if cls.required_fields_to_help:
                ini_cli_fields, unused_options = cls.get_field_parser().parse_known_args()
                # Syntax is "plugin install <template> <installation>, so
                # four non-parsed options are expected
                assert len(unused_options) >= 4, (sys.argv, ini_cli_fields, unused_options)
                unused_options = unused_options[4:]
                for field_name in cls.required_fields_to_help:
                    if field_name not in fields:
                        try:
                            fields[field_name] = getattr(ini_cli_fields, field_name)
                            assert fields[field_name] is not None
                        except (KeyError, AssertionError) as ex:
                            raise SyntaxError(
                                f"Missing field {repr(field_name)}. Help for {field_name}:\n"
                                f"{cls.required_fields_to_help[field_name]}\n\n"
                                f"Invoke again with --{field_name}=\"your value\" or with -h for additional help.\n") from ex
                if unused_options:
                    print(f"Warning: unused option{'s' if len(unused_options) > 1 else ''}. \n  - ", end="")
                    print('\n  - '.join(repr(o) for o in unused_options))
                    print(f"NOTE: You can use '' or \"\" to define fields with spaces in them.")
                    print()
            cls._fields = fields
            return fields

    @classmethod
    def install(cls, installation_dir, overwrite_destination=False, fields=None):
        """Install a template into the given dir. See super().install for more information.

        :param installation_dir: directory where the contents of the template are placed.
          It will be created if not existing.
        :param overwrite_destination: if False, a SyntaxError is raised if any of the
          destination contents existed prior to this call. Note that installation_dir
          can already exist, it is the files and directories moved into it that can
          trigger this SyntaxError.
        :param fields: if not None, it must be a dict-like object containing a field to field value
          mapping. If None, it is interpreted as an empty dictionary.
          Required template fields not present in fields will be then read from the CLI
          arguments. If those are not provided, then the default values read from `*.ini`
          configuration files. If any required field cannot not satisfied after this,
          a SyntaxError is raised.
        """
        # If there are required fields, satisfy them or fail
        fields = cls.get_fields(original_fields=fields)

        template_src_dir = os.path.dirname(os.path.abspath(inspect.getfile(cls)))
        for input_path in glob.glob(os.path.join(template_src_dir, "**", "*"), recursive=True):
            if "__pycache__" in input_path:
                continue
            if os.path.basename(input_path) == "__plugin__.py":
                continue

            # By default, the original structure and file names are preserved.
            output_path = os.path.abspath(input_path).replace(
                os.path.abspath(template_src_dir),
                os.path.abspath(installation_dir))

            # Directories are created when found
            if os.path.isdir(input_path):
                os.makedirs(output_path, exist_ok=True)
                continue

            input_is_executable = os.access(input_path, os.X_OK)

            # Files ending in '.enbt' will be identified as templates, processed and stripped of their extension.
            is_templatable = os.path.isfile(input_path) \
                             and os.path.basename(input_path).endswith(cls.templatable_extension)

            os.makedirs(os.path.dirname(output_path), exist_ok=True)
            if is_templatable:
                with tempfile.NamedTemporaryFile(mode="w+") as templated_file:
                    jinja_env = jinja2.Environment(
                        loader=jinja2.FileSystemLoader(os.path.dirname(os.path.abspath(input_path))),
                        autoescape=jinja2.select_autoescape())
                    template = jinja_env.get_template(os.path.basename(input_path))
                    templated_file.write(template.render(**fields))
                    templated_file.flush()
                    templated_file.seek(0)
                    if os.path.exists(output_path[:-len(cls.templatable_extension)]) and not options.force:
                        raise ValueError(
                            f"Error installing template {cls.name}: output file {repr(output_path)} already exists "
                            f"and options.force={options.force}. Run with -f to overwrite.")
                    with open(output_path[:-len(cls.templatable_extension)], "w") as output_file:
                        output_file.write(templated_file.read())
                    if input_is_executable:
                        os.chmod(output_path[:-len(cls.templatable_extension)],
                                 os.stat(output_path[:-len(cls.templatable_extension)]).st_mode | stat.S_IEXEC)
            else:
                if os.path.exists(output_path) and not options.force:
                    raise ValueError(
                        f"Error installing template {cls.name}: output file {repr(output_path)} already exists "
                        f"and options.force={options.force}. Run with -f to overwrite.")
                shutil.copy(input_path, output_path)

        cls.build(installation_dir=installation_dir)
        print(f"Template {repr(cls.name)} successfully installed into {repr(installation_dir)}.")

    @classmethod
    def get_field_parser(cls):
        description = f"Template {repr(cls.name)} installation help."
        if cls.required_fields_to_help:
            description += f"\n\nFields are automatically read from the following paths (in this order):\n"
            description += "\n".join(enb.config.ini.used_config_paths)

            # defined_description = f"\n\nAlready refined fields:"
            defined_field_lines = []
            for field_name in sorted(cls.required_fields_to_help.keys()):
                try:
                    defined_field_lines.append(f"  {field_name} = {enb.config.ini.get_key('template', field_name)}")
                except KeyError:
                    pass
            if defined_field_lines:
                description += f"\n\nFile-defined fields:\n"
                description += "\n".join(defined_field_lines)

        parser = argparse.ArgumentParser(
            prog=f"enb plugin install {cls.name}",
            description=description,
            formatter_class=argparse.RawTextHelpFormatter)
        required_flags_group = parser.add_argument_group(
            "Required flags (use '' or \"\" quoting for fields with spaces)")
        for field_name, field_help in cls.required_fields_to_help.items():
            try:
                default_field_value = enb.config.ini.get_key("template", field_name)
            except KeyError:
                default_field_value = None
            if field_help[-1] != ".":
                field_help += "."
            required_flags_group.add_argument(
                f"--{field_name}",
                default=default_field_value,
                help=field_help,
                metavar=field_name)
        # This argument is for showing help to the user only, since it will have already been parsed
        # by enb.config.ini by the time this is called.
        parser.add_argument(f"--ini", nargs="*", required=False, type=str,
                            help="Additional .ini paths with a [field] section containing field = value lines")
        return parser


N, A, B, C, D = map(int, input().split())
S = "#{}#".format(input())

def reachable(start, end):
    now = start
    while now <= end:
        nex = now
        while nex <= end and S[now] == S[nex]:
            nex += 1
        if S[now] == '#' and nex - now >= 2:
            return False
        now = nex
    return True

if not reachable(A, C) or not reachable(B, D):
    print("No")
    quit()

if C > D:
    can_over = False
    for i in range(B, D+1):
        if S[i-1] == S[i] == S[i+1] == ".":
            can_over = True
    if not can_over:
        print("No")
        quit()

print("Yes")


from keras.applications import resnet50
from keras.applications import mobilenetv2
from keras.applications import mobilenet
from keras.applications import vgg19

# from keras_squeezenet import SqueezeNet
import conv.networks.get_vgg16_cifar10 as gvc
import conv.networks.gen_conv_net as gcn
# import conv.networks.MobileNet as mobilenet
import conv.networks.MobileNet_for_mobile as mobilenet_for_mobile
import conv.networks.VGG19_for_mobile as vgg19_for_mobile

import conv.networks.SqueezeNet as sqn
import conv.networks.DenseNet as dn
import conv.networks.ResNet50 as rn50

from keras_applications.imagenet_utils import decode_predictions
from keras.preprocessing.image import img_to_array
from keras.applications import imagenet_utils
from keras.engine.input_layer import Input

from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D, BatchNormalization
from keras import optimizers
from keras.layers.core import Lambda
from keras import backend as K
from keras import regularizers
from keras.models import Model
from keras import optimizers
import keras

import numpy as np

from os import listdir
from os.path import isfile, join
import os

import matplotlib.image as mpimg
import time

# SqueezeNet: https://github.com/rcmalli/keras-squeezenet/blob/master/examples/example_keras_squeezenet.ipynb
# https://keras.io/applications/

def get_all_nets(network_name, include_top=True, num_filter=4):
	if(network_name=="ResNet50"):
		model = resnet50.ResNet101(weights='imagenet',
			include_top=include_top, input_shape=(224, 224, 3))
		# if(include_top==False):
		# 	model.pop()
	elif(network_name=="MobileNetV2"):
		model = mobilenetv2.MobileNetV2(weights='imagenet',
			include_top=include_top, input_shape=(224, 224, 3))
	elif(network_name=="MobileNet"):
		model = mobilenet.MobileNet(weights='imagenet',
			include_top=include_top,# pooling='avg',
			input_shape=(224, 224, 3))
	elif(network_name=="MobileNet_for_mobile"):
		model = mobilenet_for_mobile.MobileNet(
			include_top=include_top, weights='imagenet',
			input_shape=(224, 224, 3), num_filter=num_filter)
	elif(network_name=="VGG19"):
		model = vgg19.VGG19(weights='imagenet',
			include_top=include_top, input_shape=(224, 224, 3))
	elif(network_name=="VGG19_for_mobile"):
		model = vgg19_for_mobile.VGG19(
			include_top=include_top, weights='imagenet',
			input_shape=(224, 224, 3), num_filter=num_filter)
	elif(network_name=="SqueezeNet"):
		model = SqueezeNet(weights='imagenet',
		include_top=include_top, input_shape=(224, 224, 3))
		# if(include_top==False):
		# 	model.pop()
		# 	model.pop()
		# 	model.pop()
		# 	model.pop()

	if(include_top):
		opt = optimizers.rmsprop(lr=0.0001, decay=1e-6)

		# Let's train the model using RMSprop
		model.compile(loss='categorical_crossentropy',
		      optimizer=opt,
		      metrics=['accuracy'])
	return model

def get_nets_wo_weights(network_name, num_classes, include_top=False,
	input_shape=(32, 32, 3), num_filter=4, use_bias=False):
	if(network_name=="ResNet50"):
		model = rn50.ResNet50(include_top=include_top,
			input_shape=input_shape, weights=None,
			classes=num_classes,  num_vert_filters=num_filter)
	elif(network_name=="DenseNet121"):
		model = dn.DenseNet121(include_top=include_top,
			input_shape=input_shape, weights=None,
			classes=num_classes, num_filter=num_filter)
	elif(network_name=="MobileNetV2"):
		model = mobilenetv2.MobileNetV2(include_top=include_top,
			input_shape=input_shape, weights=None,
			classes=num_classes)
	elif(network_name=="MobileNet"):
		model = mobilenet.MobileNet(
			include_top=include_top, input_shape=input_shape, weights=None,
			classes=num_classes, num_filter=num_filter)
	elif(network_name=="MobileNet_for_mobile"):
		model = mobilenet_for_mobile.MobileNet(
			include_top=include_top, input_shape=input_shape, weights=None,
			classes=num_classes, num_filter=num_filter)
	elif(network_name=="VGG19"):
		model = vgg19.VGG19(input_shape=input_shape,
			include_top=include_top, weights=None,
			classes=num_classes)
	elif(network_name=="SqueezeNet"):
		model = sqn.SqueezeNet(input_shape=input_shape,
			include_top=include_top, weights=None, num_filter=num_filter,
			use_bias=use_bias, classes=num_classes)
	elif(network_name=="vgg"):
		model = gvc.get_conv_vert_net(x_shape=input_shape,
			num_classes=num_classes, num_vert_filters=num_filter,
    		use_bias=use_bias)
	elif(network_name=="conv"):
		model = gcn.get_conv_vert_net(input_shape=input_shape,
			num_classes=num_classes,
			num_extra_conv_layers=2, num_ver_filter=num_filter,
			use_bias=use_bias)

	if(include_top == False):
		x = model.output
		# x = keras.layers.GlobalAveragePooling2D()(x)
		x = Flatten()(x)
		x = Dense(256, activation='relu')(x)
		# x = Activation('relu')(x)
		x = Dropout(0.5)(x)
		# x = Dense(num_output)(x)
		# x = Activation('softmax')(x)
		x = keras.layers.Dense(num_classes, activation='softmax',
	                         use_bias=True, name='Logits')(x)

		full_model = Model(inputs = model.input,outputs = x)
	else:
		full_model = model
	opt = optimizers.rmsprop(lr=0.0001, decay=1e-6)

	# Let's train the model using RMSprop
	full_model.compile(loss='categorical_crossentropy',
	      optimizer=opt,
	      metrics=['accuracy'])
	return full_model

def get_box_nets(network_name, num_classes, include_top=False,
	input_shape=(32, 32, 3), num_filter=4, num_layer=4, use_bias=False):
	if(network_name=="ResNet50"):
		model = resnet50.ResNet50(include_top=include_top,
			input_shape=input_shape, weights=None)
		# if(include_top==False):
		# 	model.pop()
	elif(network_name=="DenseNet121"):
		model = dn.DenseNet121(include_top=include_top,
			input_shape=input_shape, weights=None,
			classes=num_classes, num_filter=num_filter,
			num_layer=num_layer)
	elif(network_name=="MobileNetV2"):
		model = mobilenetv2.MobileNetV2(include_top=include_top,
			input_shape=input_shape, weights=None,
			classes=num_classes)
	elif(network_name=="MobileNet"):
		model = mobilenet.MobileNet(
			include_top=include_top, input_shape=input_shape, weights=None,
			classes=num_classes, num_filter=num_filter, num_layers=num_layer)
	elif(network_name=="MobileNet_for_mobile"):
		model = mobilenet_for_mobile.MobileNet(
			include_top=include_top, input_shape=input_shape, weights=None,
			classes=num_classes, num_filter=num_filter)
	elif(network_name=="VGG19"):
		model = vgg19.VGG19(input_shape=input_shape,
			include_top=include_top, weights=None,
			classes=num_classes)
	elif(network_name=="SqueezeNet"):
		model = sqn.SqueezeNet(input_shape=input_shape,
			include_top=include_top, weights=None, num_filter=num_filter,
			use_bias=use_bias, classes=num_classes,
			num_layers=num_layer)
	elif(network_name=="vgg"):
		model = gvc.get_conv_vert_net(x_shape=input_shape,
			num_classes=num_classes, num_vert_filters=num_filter,
    		use_bias=use_bias)
	elif(network_name=="conv"):
		model = gcn.get_conv_vert_net(input_shape=input_shape,
			num_classes=num_classes,
			num_extra_conv_layers=num_layers, num_ver_filter=num_filter,
			use_bias=use_bias)

	opt = optimizers.rmsprop(lr=0.0001, decay=1e-6)

	# Let's train the model using RMSprop
	model.compile(loss='categorical_crossentropy',
	      optimizer=opt,
	      metrics=['accuracy'])
	return model

def preprocess_image(network_name, x):
	if(network_name=="ResNet50"):
		x = resnet50.preprocess_input(x)
	elif(network_name=="MobileNetV2"):
		x = mobilenetv2.preprocess_input(x)
	elif(network_name=="MobileNet"):
		x = mobilenet.preprocess_input(x)
	elif(network_name=="VGG19"):
		x = vgg19.preprocess_input(x)
	elif(network_name=="SqueezeNet"):
		x = imagenet_utils.preprocess_input(x)
	return x

def preprocess_image_fn(network_name):
	if(network_name=="ResNet50"):
		x = resnet50.preprocess_input
	elif(network_name=="MobileNetV2"):
		x = mobilenetv2.preprocess_input
	elif(network_name=="MobileNet"):
		x = mobilenet.preprocess_input
	elif(network_name=="VGG19"):
		x = vgg19.preprocess_input
	elif(network_name=="SqueezeNet"):
		x = imagenet_utils.preprocess_input
	return x

def decodepred(network_name, preds):
	if(network_name=="ResNet50"):
		preds = resnet50.decode_predictions(preds, top=3)[0]
	elif(network_name=="MobileNetV2"):
		preds = mobilenetv2.decode_predictions(preds, top=3)[0]
	elif(network_name=="MobileNet"):
		preds = mobilenet.decode_predictions(preds, top=3)[0]
	elif(network_name=="VGG19"):
		preds = vgg19.decode_predictions(preds, top=3)[0]
	elif(network_name=="SqueezeNet"):
		preds = imagenet_utils.decode_predictions(preds, top=3)[0]
	return x

def analyse_model(model):
	print("All functions ", dir(model))
	print("Summary model ", model.summary())
	print("Layer details ", dir(model.layers[2]))
	for i, layer in enumerate(model.layers):
		print("Length in each layer ", i, layer.name,
			layer.input_shape, layer.output_shape,
			len(layer.weights))
		if(len(layer.weights)):
			for j, weight in enumerate(layer.weights):
				print("Weights ", j, weight.shape)
	return

def add_classifier(base_model, num_output):

	for layer in base_model.layers:
		layer.trainable = False

	x = base_model.output
	x = keras.layers.GlobalAveragePooling2D()(x)
	# x = Dense(16, kernel_regularizer=regularizers.l2(0.01))(x)
	# x = Activation('relu')(x)
	# x = Dropout(0.5)(x)
	# x = Dense(num_output)(x)
	# x = Activation('softmax')(x)
	x = keras.layers.Dense(num_output, activation='softmax',
                         use_bias=True, name='Logits')(x)

	model = Model(inputs = base_model.input,outputs = x)
	# initiate RMSprop optimizer
	opt = optimizers.rmsprop(lr=0.0001, decay=1e-6)

	# Let's train the model using RMSprop
	model.compile(loss='binary_crossentropy',
	              optimizer=opt,
	              metrics=['accuracy'])
	return model

def get_all_prediction(image_filelist):
	prediction_list = []
	for filename in image_filelist:

		# img = image.load_img(os.path.join(imagenet_path, filename), target_size=(224, 224))
		img = image.load_img(os.path.join(imagenet_path, filename), target_size=(227, 227)) # Squeezenet
		# img1 = mpimg.imread(os.path.join(imagenet_path, filename))
		# print(img1.shape)
		x = image.img_to_array(img)
		x = np.expand_dims(x, axis=0)
		x = imagenet_utils.preprocess_input(x)

		preds = model.predict(x)
		# decode the results into a list of tuples (class, description, probability)
		# (one such list for each sample in the batch)
		print('Predicted:', filename, imagenet_utils.decode_predictions(preds, top=3)[0])
		print("Pred values ", np.argmax(preds))
		# Predicted: [(u'n02504013', u'Indian_elephant', 0.82658225), (u'n01871265', u'tusker', 0.1122357), (u'n02504458', u'African_elephant', 0.061040461)]
		prediction_list.append(preds)
	return prediction_list

if __name__ == '__main__':

	network_types_list = ["MobileNetV2"]#, "ResNet50", "MobileNetV2", "VGG19"] # , "SqueezeNet"
	for network_type in network_types_list:
		print("Network Type ", network_type)
		model = get_all_nets(network_type, include_top=True)
		analyse_model(model)
		# model = get_all_nets(network_type, include_top=False)
		# model = add_classifier(model)

	imagenet_path = "/mnt/additional/aryan/imagenet_validation_data/ILSVRC2012_img_val/"
	# http://www.image-net.org/challenges/LSVRC/2012/
	# https://cv-tricks.com/tensorflow-tutorial/keras/
	# Finding actual predictions
	# http://machinelearninguru.com/deep_learning/data_preparation/hdf5/hdf5.html

	image_filelist = [f for f in listdir(imagenet_path) if isfile(join(imagenet_path, f))]

	print("Number of files ", len(image_filelist))

	start_time = time.time()
	get_all_prediction(image_filelist[:10])
	total_time = time.time() - start_time
	print("Total prediction time ", total_time)

	print("File list ", image_filelist[:10])


# encoding: utf-8
# pylint: disable=redefined-outer-name,missing-docstring
import pytest

from tests import utils

from app import create_app

@pytest.yield_fixture(scope='session')
def flask_app():
    app = create_app(flask_config='testing')
    from app.extensions import db

    with app.app_context():
        db.create_all()
        yield app
        db.drop_all()

@pytest.yield_fixture()
def db(flask_app):
    # pylint: disable=unused-argument,invalid-name
    from app.extensions import db as db_instance
    yield db_instance
    db_instance.session.rollback()

@pytest.fixture(scope='session')
def flask_app_client(flask_app):
    flask_app.test_client_class = utils.AutoAuthFlaskClient
    flask_app.response_class = utils.JSONResponse
    return flask_app.test_client()

@pytest.yield_fixture(scope='session')
def regular_user(flask_app):
    # pylint: disable=invalid-name,unused-argument
    from app.extensions import db

    regular_user_instance = utils.generate_user_instance(
        username='regular_user'
    )

    db.session.add(regular_user_instance)
    db.session.commit()
    yield regular_user_instance
    db.session.delete(regular_user_instance)
    db.session.commit()

@pytest.yield_fixture(scope='session')
def readonly_user(flask_app):
    # pylint: disable=invalid-name,unused-argument
    from app.extensions import db

    readonly_user_instance = utils.generate_user_instance(
        username='readonly_user',
        is_readonly=True
    )

    db.session.add(readonly_user_instance)
    db.session.commit()
    yield readonly_user_instance
    db.session.delete(readonly_user_instance)
    db.session.commit()

@pytest.yield_fixture(scope='session')
def admin_user(flask_app):
    # pylint: disable=invalid-name,unused-argument
    from app.extensions import db

    admin_user_instance = utils.generate_user_instance(
        username='admin_user',
        is_admin=True
    )

    db.session.add(admin_user_instance)
    db.session.commit()
    yield admin_user_instance
    db.session.delete(admin_user_instance)
    db.session.commit()


'''Instead of giving some hard coded values and changing it later in the entire code which will be very time consuming and troublesome
    we are going to create a class which will manage all the settings parameter so even if we have to change later we only need to make
    changes in this file
'''
class settings:
    def __init__(self) -> None:
        #screen
        self.width = 1200
        self.height = 800
        self.bg_color = ("cyan")

        #ship
        self.ship_speed_factor= 2.0
        self.ship_limit = 3

        #Bullets
        self.bullet_speed_factor = 3
        self.bullet_width = 5
        self.bullet_height = 15
        self.bullet_color = 25,25,112
        self.bullets_allowed = 5

        #alien
        self.alien_speed = 0.5
        self.fleet_drop_speed = 10
        self.fleet_direction = 1

        #Amount by which difficulty of game should be increased
        self.speedup = 1.2

        self.initialize_dynamic_settings()

        self.alien_points = 50

    #These are the initial settings of game
    def initialize_dynamic_settings(self):
        self.ship_speed_factor = 2.0
        self.bullet_speed_factor = 2
        self.alien_speed = 0.5
        self.fleet_direction = 1

    #This function is called when player completes certain level . It increases the difficulty of the game
    def increase_speed(self):
        self.ship_speed_factor *= self.speedup
        self.bullet_speed_factor *= self.speedup
        self.alien_speed *= self.speedup
        self.alien_points *= self.speedup
        print(self.alien_points)


from scipy.interpolate import Rbf  # radial basis functions
import matplotlib.pyplot as plt
import numpy as np

x = [1555,1203,568,1098,397,564,1445,337,1658,1517,948]
y = [860,206,1097,425,594,614,553,917,693,469,306]
x = [0.9, 0.6, 0.1, 0.5, 0.04, 0.1, 0.82, 0.0, 1.0, 0.89, 0.46]
y = [0.73, 0.0, 1.0, 0.24, 0.43, 0.45, 0.38, 0.7, 0.54, 0.29, 0.11]
z = [1]*len(x)

rbf_adj = Rbf(x, y, z, function='gaussian')

x_fine = np.linspace(0, 1, 81)
y_fine = np.linspace(0, 1, 82)

x_grid, y_grid = np.meshgrid(x_fine, y_fine)

z_grid = rbf_adj(x_grid.ravel(), y_grid.ravel()).reshape(x_grid.shape)

plt.gca().invert_yaxis()
#plt.gca().invert_xaxis()
plt.pcolor(x_fine, y_fine, z_grid);
plt.plot(x, y, 'ok');
plt.xlabel('x'); plt.ylabel('y'); plt.colorbar();
plt.title('Heat Intensity Map');
plt.show()


import pytest
from utils import *

from fireplace.exceptions import GameOver

LORD_JARAXXUS = "EX1_323"
LORD_JARAXXUS_HERO = "EX1_323h"
LORD_JARAXXUS_WEAPON = "EX1_323w"
INFERNO = "EX1_tk33"
INFERNO_TOKEN = "EX1_tk34"

def test_jaraxxus():
	game = prepare_game(CardClass.WARRIOR, CardClass.WARRIOR)
	game.player1.hero.power.use()
	game.player1.give(LIGHTS_JUSTICE).play()
	assert game.player1.weapon.id == LIGHTS_JUSTICE
	game.end_turn()
	game.end_turn()

	assert game.player1.hero.health == 30
	assert game.player1.hero.armor == 2
	game.player1.give(LORD_JARAXXUS).play()
	assert game.player1.hero.id == LORD_JARAXXUS_HERO
	assert game.player1.weapon.id == LORD_JARAXXUS_WEAPON
	assert game.player1.hero.health == 15
	assert game.player1.hero.armor == 0
	assert game.player1.hero.power.id == INFERNO
	assert len(game.player1.field) == 0
	game.end_turn()
	game.end_turn()

	game.player1.hero.power.use()
	assert len(game.player1.field) == 1
	assert game.player1.field[0].id == INFERNO_TOKEN

def test_jaraxxus_cult_master():
	game = prepare_game()
	game.player1.discard_hand()
	game.player1.summon("EX1_595")
	game.player1.give(LORD_JARAXXUS).play()
	assert len(game.player1.field) == 1
	assert not game.player1.hand

def test_jaraxxus_knife_juggler():
	game = prepare_game()
	juggler = game.player1.summon("NEW1_019")
	game.player1.give(LORD_JARAXXUS).play()
	assert game.player2.hero.health == 30
	assert juggler.health == 2

def test_jaraxxus_molten_giant():
	game = prepare_game()
	jaraxxus = game.player1.give("EX1_323")
	molten = game.player1.give("EX1_620")
	jaraxxus.play()
	assert game.player1.hero.health == 15
	assert molten.cost == 20

def test_jaraxxus_mirror_entity():
	game = prepare_game()
	mirror = game.player1.give("EX1_294")
	mirror.play()
	game.end_turn()

	jaraxxus = game.player2.give(LORD_JARAXXUS)
	jaraxxus.play()
	assert not game.player1.secrets
	assert game.player2.hero.id == LORD_JARAXXUS_HERO
	assert len(game.player1.field) == 1
	assert game.player1.field[0].id == LORD_JARAXXUS

def test_jaraxxus_repentance():
	game = prepare_game()
	repentance = game.player1.give("EX1_379")
	repentance.play()
	game.end_turn()

	jaraxxus = game.player2.give(LORD_JARAXXUS)
	jaraxxus.play()
	assert not game.player1.secrets
	assert game.player2.hero.id == LORD_JARAXXUS_HERO
	assert game.player2.hero.health == game.player2.hero.max_health == 1

def test_jaraxxus_snipe():
	game = prepare_game()
	snipe = game.player1.give("EX1_609")
	snipe.play()
	game.end_turn()

	jaraxxus = game.player2.give(LORD_JARAXXUS)
	jaraxxus.play()
	assert len(game.player1.secrets) == 1
	assert game.player2.hero.health == 15

def test_jaraxxus_sacred_trial():
	game = prepare_game()
	trial = game.player1.give("LOE_027")
	trial.play()
	game.end_turn()

	game.player2.give(WISP).play()
	game.player2.give(WISP).play()
	game.player2.give(WISP).play()
	jaraxxus = game.player2.give(LORD_JARAXXUS)
	jaraxxus.play()
	# Will not trigger as 4th minion due to timing
	assert trial in game.player1.secrets
	assert not game.player2.hero.dead
	game.end_turn()
	game.end_turn()

	wisp4 = game.player2.summon(WISP)
	assert not wisp4.dead
	jaraxxus = game.player2.give(LORD_JARAXXUS)
	with pytest.raises(GameOver):
		jaraxxus.play()
		assert trial not in game.player1.secrets
		assert game.player2.hero.dead


def stringToInt(s):
    multiply = 1
    if s[0] == '-':
        multiply = -1
        s = s[1:]

    mul = len(s)-1

    num = 0

    for ch in s:
        num = num + (10 ** mul) * (ord(ch)-48)
        mul = mul - 1

    num = num * multiply

    return num

print(stringToInt("-0000045637560003330003"))


"""
Run the model end to end
"""
import argparse
import sys
import torch
from pathlib import Path

import pytorch_lightning as pl
from pytorch_lightning.callbacks.early_stopping import EarlyStopping
from pytorch_lightning.callbacks.model_checkpoint import ModelCheckpoint

from smallteacher.data import DataModule, train_augmentations
from smallteacher.models import FullySupervised, SemiSupervised
from smallteacher.constants import Metrics
from smallteacher.config import BEST_MODEL_NAME

from smallssd.data import LabelledData, UnlabelledData
from smallssd.config import DATAFOLDER_PATH
from smallssd.keys import CLASSNAME_TO_IDX

import mlflow
import mlflow.pytorch

def parse_args(args):
    """Parse the arguments."""
    parser = argparse.ArgumentParser(
        description="Simple training script for training a pytorch lightning model."
    )

    parser.add_argument(
        "--model",
        help="Chooses model architecture",
        type=str,
        default="FRCNN",
        choices=["FRCNN", "RetinaNet", "SSD"],
    )
    parser.add_argument(
        "--workers", help="Number of dataloader workers", type=int, default="1"
    )

    parser.add_argument(
        "--mlflow_experiment", type=str, default="pytorch_lightning_experiment"
    )
    parser.add_argument("--seed", type=int, default="42")

    return parser.parse_args(args)

def get_checkpoint(version: int) -> Path:
    return list(
        Path(f"lightning_logs/version_{version}/checkpoints").glob("best_model*.ckpt")
    )[0]

def train_fully_supervised(datamodule, model_name) -> int:
    model = FullySupervised(
        model_base=model_name,
        num_classes=len(CLASSNAME_TO_IDX),
    )
    fully_supervised_trainer = pl.Trainer(
        callbacks=[
            EarlyStopping(monitor=Metrics.MAP, mode="max", patience=10),
            ModelCheckpoint(filename=BEST_MODEL_NAME, monitor=Metrics.MAP, mode="max"),
        ],
        gpus=torch.cuda.device_count(),
    )
    fully_supervised_trainer.fit(model, datamodule=datamodule)

    best_model = FullySupervised.load_from_checkpoint(
        get_checkpoint(fully_supervised_trainer.logger.version),
        model_base=model_name,
        num_classes=len(CLASSNAME_TO_IDX),
    )
    fully_supervised_trainer.test(best_model, datamodule=datamodule)

    return fully_supervised_trainer.logger.version

def train_teacher_student(datamodule, model_name, model_checkpoint) -> int:
    unlabelled_ds = UnlabelledData(root=DATAFOLDER_PATH)
    datamodule.add_unlabelled_training_dataset(unlabelled_ds)

    org_model = FullySupervised.load_from_checkpoint(
        model_checkpoint,
        model_base=model_name,
        num_classes=len(CLASSNAME_TO_IDX),
    )
    model = SemiSupervised(
        trained_model=org_model.model,
        model_base=model_name,
        num_classes=len(CLASSNAME_TO_IDX),
    )

    trainer = pl.Trainer(
        gpus=torch.cuda.device_count(),
        callbacks=[
            EarlyStopping(monitor=Metrics.MAP, mode="max", patience=10),
            ModelCheckpoint(filename=BEST_MODEL_NAME, monitor=Metrics.MAP, mode="max"),
        ],
    )

    trainer.fit(model, datamodule=datamodule)
    best_model = SemiSupervised.load_from_checkpoint(
        get_checkpoint(trainer.logger.version),
        model_base=model_name,
        num_classes=len(CLASSNAME_TO_IDX),
    )
    trainer.test(best_model, datamodule=datamodule)
    return best_model

def main(args=None):
    if args is None:
        args = sys.argv[1:]
    args = parse_args(args)

    mlflow.set_experiment(experiment_name=args.mlflow_experiment)
    pl.seed_everything(args.seed)

    datamodule = DataModule(
        *LabelledData(root=DATAFOLDER_PATH, eval=False).split(
            transforms=[train_augmentations, None]
        ),
        test_dataset=LabelledData(root=DATAFOLDER_PATH, eval=True),
        num_workers=args.workers,
    )

    mlflow.pytorch.autolog()
    with mlflow.start_run(run_name=f"{args.model}_fully_supervised"):
        version_id = train_fully_supervised(datamodule, args.model)
        best_model_checkpoint = get_checkpoint(version_id)
    with mlflow.start_run(run_name=f"{args.model}_teacher_student"):
        best_model = train_teacher_student(
            datamodule, args.model, best_model_checkpoint
        )
        mlflow.pytorch.log_model(best_model.model, artifact_path="model")

if __name__ == "__main__":
    main()


import turtle
from math import sin, cos, pi

r = 200
inc = 2*pi/100
t = 0
n = 1.5

for i in range (100):
    x1 = r * sin(t)
    y1 = r * cos(t)
    x2 = r * sin(t+n)
    y2 = r * cos(t+n)
    turtle.penup()
    turtle.goto(x1, y1)
    turtle.pendown()
    turtle.goto(x2, y2)
    t += inc


import threading
from datetime import datetime
from time import sleep
from random import randint
from queue import Queue

# loops = [4,2]

# def loop(nloop,nsec):
#   print('start loop',nloop,'at:',datetime.now())
#   sleep(nsec)
#   print('loop',nloop,'done at:',datetime.now())

# def main():
#   print('starting at:',datetime.now())
#   threads = []
#   nloops = range(len(loops))

#   for i in nloops:
#     t = threading.Thread(target=loop,args=(i,loops[i]))
#     threads.append(t)

#   for i in nloops:
#     threads[i].start()

#   for i in nloops:
#     threads[i].join()

#   print('all DONE at:',datetime.now())

# class ThreadFunc(object):

#   def __init__(self,func,args,name=''):
#     self.name = name
#     self.func = func
#     self.args = args

#   def __call__(self): # 可执行函数
#     print(self.name)
#     self.func(*self.args)

# def main():
#   print('starting at:',datetime.now())
#   threads = []
#   nloops = range(len(loops))

#   for i in nloops:
#     t = threading.Thread(target=ThreadFunc(loop,(i,loops[i]),loop.__name__))
#     threads.append(t)

#   for i in nloops:
#     threads[i].start()

#   for i in nloops:
#     threads[i].join()

#   print('all DONE at:',datetime.now())

# class Student(object):
#   def __init__(self,name,age):
#     self.name = name
#     self.age = age

#   def __call__(self):
#     print(self.name,self.age)

class MyThread(threading.Thread):
  def __init__(self,func,args,name=''):
    threading.Thread.__init__(self)
    self.name = name
    self.func = func
    self.args = args

  def run(self):
    self.func(*self.args)

def writeQ(queue):
  print('producing object for Q...')
  queue.put('xxx',1)
  print('size now',queue.qsize())

def readQ(queue):
  val = queue.get(1)
  print(val,'consumed object from Q ... size now',queue.qsize())

def writer(queue,loops):
  for i in range(loops):
    writeQ(queue)
    sleep(randint(1,3))

def reader(queue,loops):
  for i in range(loops):
    readQ(queue)
    sleep(randint(2,5))

funcs = [writer,reader]
nfuncs = range(len(funcs))

def main():
  nloops = randint(2,5)
  print('nloops',nloops)
  q = Queue(32)

  threads = []
  for i in nfuncs:
    t = MyThread(funcs[i],(q,nloops),funcs[i].__name__)
    threads.append(t)

  for i in nfuncs:
    threads[i].start()

  for i in nfuncs:
    threads[i].join()

  print('all DONE')

if __name__ == '__main__':
    main()
    # Student('wc',23)()


import urllib
from xml.dom import minidom
import re

def buildResponse(node_list):
	return_string = ""
	for i in node_list:
		return_string = return_string + i + "\n"
	return return_string.strip()

def buildURL(key, word):
	return "http://www.dictionaryapi.com/api/v1/references/collegiate/xml/" + word + "?key=" + key

def getXML(word):
	url = buildURL("1a276aec-1aa8-42d4-9575-d29c2d4fb105", word)
	response = urllib.urlopen(url).read()
	data = minidom.parseString(str(response))
	return data

def getDefinition(word):
	data = getXML(word)
	itemlist = data.getElementsByTagName('def')
	node_list = []
	for i in itemlist:
		dts = i.getElementsByTagName('dt')
		node_list.append(str(dts[0].childNodes[0].nodeValue))
	if len(node_list) < 3:
		return buildResponse(node_list)
	else:
		return buildResponse(node_list[:3])


from app.models.player import *
import random

player1 = Player("PLayer 1")
player2 = Player("Player 2")
players = [player1, player2]

def one_player(name1):
    player1.name = name1
    player2.name = "Computer"

def add_players(name1, name2):
    player1.name = name1
    player2.name = name2

def random_move(self):
    options = ["rock", "paper", "scissors"]
    move = random.choice(options)
    return move

def set_moves(move1, move2):
    player1.move = move1
    player2.move = move2

def result():
    if player1.move == player2.move:
        return "Oooh it's a draw"
    elif (player1.move == "rock" and player2.move == "scissors"):
        return players[0].name + " wins"
    elif(player1.move == "scissors" and player2.move == "paper"):
        return players[0].name + " wins"
    elif(player1.move == "paper" and player2.move == "rock"):
        return players[0].name + " wins"
    else:
        return players[1].name + " wins"


import sys
from math import sqrt
from itertools import compress

# 利用byte求质数
def get_primes_3(n):
    """ Returns  a list of primes < n for n > 2 """
    sieve = bytearray([True]) * (n // 2)
    for i in range(3, int(n ** 0.5) + 1, 2):
        if sieve[i // 2]:
            sieve[i * i // 2::i] = bytearray((n - i * i - 1) // (2 * i) + 1)

    return [2, *compress(range(3, n, 2), sieve[1:])]

def is_prime(n):
    # Only used to test odd numbers.
    return all(n % d for d in range(3, round(sqrt(n)) + 1, 2))

def f(a, b):
    '''
    Won't be tested for b greater than 10_000_000

    >>> f(3, 3)
    The number of prime numbers between 3 and 3 included is 1
    >>> f(4, 4)
    The number of prime numbers between 4 and 4 included is 0
    >>> f(2, 5)
    The number of prime numbers between 2 and 5 included is 3
    >>> f(2, 10)
    The number of prime numbers between 2 and 10 included is 4
    >>> f(2, 11)
    The number of prime numbers between 2 and 11 included is 5
    >>> f(1234, 567890)
    The number of prime numbers between 1234 and 567890 included is 46457
    >>> f(89, 5678901)
    The number of prime numbers between 89 and 5678901 included is 392201
    >>> f(89, 5678901)
    The number of prime numbers between 89 and 5678901 included is 392201
    '''
    count = 0
    for i in range(a,b+1):
        if is_prime(i):
            count+=1

    less_a_primes = get_primes_3(a + 1)
    less_b_primes = get_primes_3(b + 1)
    for item in less_a_primes:
        if item < a:
            less_b_primes.remove(item)

    count = len(less_b_primes)

    print(f'The number of prime numbers between {a} and {b} included is {count}')

if __name__ == '__main__':
    import doctest
    doctest.testmod()