import pygame, copy, random, math
from Vec2d import Vec2d
from pygame.locals import *
from sys import exit
from threading import *
from time import sleep
background = './bg.jpg'
my_plan_picture = './plane01.png'
enemy_picture = './enemy.png'
my_bullet_picture = './bullet.png'
enemy_bullet_picture = './enemybullet.png'
boom_picture = './boom.png'
boss_picture = './boss.png'
fire_picture = './fire.png'
plan_not_defeat = './plane8888.png'
box = './box.png'
missile = './daodan.png'
lock = './lock.png'
music = './bgm.mp3'
pygame.init()

class Plan(object):
    def __init__(self):
        self.screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN, 32)
        # 游戏组件
        self.background = pygame.image.load(background).convert()
        self.my_plan_picture = pygame.image.load(my_plan_picture).convert_alpha()
        self.enemy_picture = pygame.image.load(enemy_picture).convert_alpha()
        self.my_bullet_picture = pygame.image.load(my_bullet_picture).convert_alpha()
        self.enemy_bullet_picture = pygame.image.load(enemy_bullet_picture).convert_alpha()
        self.small_plan = pygame.transform.scale(self.my_plan_picture, (50, 35))
        self.boom_picture = pygame.image.load(boom_picture).convert_alpha()
        self.boss_picture = pygame.image.load(boss_picture).convert_alpha()
        self.fire_picture = pygame.image.load(fire_picture).convert_alpha()
        self.not_defeat_picture = pygame.image.load(plan_not_defeat).convert_alpha()
        self.box_picture = pygame.image.load(box).convert_alpha()
        self.missile_picture = pygame.image.load(missile).convert_alpha()
        self.lock_picture = pygame.image.load(lock).convert_alpha()
        pygame.mixer_music.load(music)
        pygame.mixer_music.set_volume(0.2)
        pygame.mixer_music.play(50)
        # 时间标志
        # self.clock = pygame.time.Clock()
        self.time_record = 0
        # 存在的各种子弹数组
        self.my_bullets = []
        self.enemy_bullets = []
        self.missile_list = [[], []]
        # 本机子弹速度和数量
        self.my_bullet_speed = 20
        self.my_bullet_number = 1
        # 能量
        self.my_power = 1000
        self.sub_my_power = 0
        # 存在的敌机
        self.live_enemy = []
        # 正在爆炸的坐标
        self.booming_pos = []
        # 剩余生命
        self.my_life = 3
        # 初始化本机且不无敌
        self.my_plan_pos = [900, 500]
        self.now_plan_picture = self.my_plan_picture
        self.is_not_defeat = 0
        # 初始化导弹数为0
        self.missile_number = 0
        # 初始化字体
        self.my_font = pygame.font.SysFont('kaiti', 22, True, True)
        # 初始化得分
        self.my_count = 0
        # 道具
        self.box_list = []
        self.have_box = 0
        self.fire_time = 0
        # 初始化boss坐标，并且无boss
        self.have_boss = 0
        self.boss_pos = [800, -250]
        self.boss_do_shut = 0
        self.boss_life = 350
        # boss左右移动方向
        self.boss_toward = -1
        # 难度值
        self.hard = 0

    # 移动本机
    def move_my_plan(self):
        my_plan_move = pygame.mouse.get_rel()
        # 超出边界则不移动
        if 0 < self.my_plan_pos[0]+self.my_plan_picture.get_width()/2+my_plan_move[0] < 1920:
            self.my_plan_pos[0] += my_plan_move[0]
        if 0 < self.my_plan_pos[1]+self.my_plan_picture.get_height()/2+my_plan_move[1] < 1080:
            self.my_plan_pos[1] += my_plan_move[1]
        self.screen.blit(self.now_plan_picture, self.my_plan_pos)

    # 创造本机子弹
    def create_my_bullet(self):
        # 间隔某段时间就添加子弹
        if self.time_record % self.my_bullet_speed == 0:
            if self.my_bullet_number == 1:
                self.my_bullets.append([self.my_plan_pos[0]+68, self.my_plan_pos[1]-13])
            elif self.my_bullet_number == 2:
                self.my_bullets.append([self.my_plan_pos[0]+53, self.my_plan_pos[1]-13])
                self.my_bullets.append([self.my_plan_pos[0]+83, self.my_plan_pos[1]-13])
        # 子弹轨迹
        for bullet in self.my_bullets:
            if bullet[1] <= 0:
                # 销毁超出范围的子弹
                self.my_bullets.remove(bullet)
            else:
                # 没超出范围则向上移动4像素
                bullet[1] -= 4
                self.screen.blit(self.my_bullet_picture, bullet)
        # 创造僚机子弹
        if self.fire_time > 0:
            self.screen.blit(self.fire_picture, [self.my_plan_pos[0] - 15, self.my_plan_pos[1] + 30])
            self.screen.blit(self.fire_picture, [self.my_plan_pos[0] + 130, self.my_plan_pos[1] + 30])
            if self.time_record % 20 == 0:
                self.my_bullets.append([self.my_plan_pos[0] - 8, self.my_plan_pos[1] + 30])
                self.my_bullets.append([self.my_plan_pos[0] + 140, self.my_plan_pos[1] + 30])
            self.fire_time -= 1
        # 如果场上没有导弹就创造一个导弹
        if self.missile_number > 0 and len(self.missile_list[0]) == 0:
            # 导弹起始点为当前本机坐标
            missile_pos = copy.deepcopy([self.my_plan_pos[0]+50, self.my_plan_pos[1]-50])
            self.missile_list[0] = missile_pos
            self.missile_number -= 1
        # 发射导弹
        if len(self.missile_list[0]) > 0:
            # 导弹打向敌机
            if len(self.live_enemy) > 0:
                enemy_pos = [self.live_enemy[0][0]-10, self.live_enemy[0][1]-20]
                vec = (Vec2d(enemy_pos) - Vec2d(self.missile_list[0])).normalized()
                self.missile_list[1] = vec
                # 改变导弹朝向
                angle = 270-vec.get_angle()
                toward = pygame.transform.rotate(self.missile_picture, angle)
                # 画出标记
                self.screen.blit(self.lock_picture, [enemy_pos[0]-10, enemy_pos[1]])
                self.screen.blit(toward, (self.missile_list[0]))
                self.missile_list[0][0] += self.missile_list[1][0] * 6
                self.missile_list[0][1] += self.missile_list[1][1] * 6

    # 创造多种道具效果
    def show_box(self):
        # 第一种，创造两个发射普通子弹的僚机
        if self.have_box == 1:
            self.fire_time = 1500
            self.have_box = 0
        # 第二种，清屏
        elif self.have_box == 2:
            self.enemy_bullets = []
            self.have_box = 0
        # 第三种，发射跟踪导弹
        elif self.have_box == 3:
            self.missile_number = 30
            self.have_box = 0
        # 第四种，无敌
        elif self.have_box == 4:
            self.is_not_defeat = 1600
            self.have_box = 0

    # 创造敌机
    def create_enemy(self):
        # 间隔某段时间就创建新的敌机
        if self.time_record % (250-self.hard*40) == 0:
            x = random.randint(0, 1920)
            vec_x = random.randint(-1920, 1920)
            vec_y = random.randint(200, 500)
            vec_normal = Vec2d(vec_x, vec_y).normalized()
            self.live_enemy.append([x, 0, vec_normal, [vec_x, vec_y]])
        # 移动敌机
        for enemy_pos in self.live_enemy:
            # 销毁超出范围的敌机并扣一分
            if enemy_pos[1] >= 1080:
                self.live_enemy.remove(enemy_pos)
                if self.my_count > 0:
                    self.my_count -= 1
            # 改变碰壁敌机的移动方向
            elif enemy_pos[0] < 10 or enemy_pos[0] > 1910:
                new_vec_x = 1000-enemy_pos[0]
                new_vec_y = random.randint(enemy_pos[3][1] + 200, enemy_pos[3][1] + 500)
                new_vec_normal = Vec2d(new_vec_x, new_vec_y).normalized()
                self.live_enemy[self.live_enemy.index(enemy_pos)][2] = new_vec_normal
                self.live_enemy[self.live_enemy.index(enemy_pos)][3] = [new_vec_x, new_vec_y]
        for enemy_pos in self.live_enemy:
            # 到达随机方向向量的y坐标附近就随机一个新的方向
            if enemy_pos[3][1]-30 < enemy_pos[1] < enemy_pos[3][1]+30:
                new_vec_x = random.randint(-1920, 1920)
                new_vec_y = random.randint(enemy_pos[3][1]+400, enemy_pos[3][1]+500)
                new_vec_normal = Vec2d(new_vec_x, new_vec_y).normalized()
                self.live_enemy[self.live_enemy.index(enemy_pos)][2] = new_vec_normal
                self.live_enemy[self.live_enemy.index(enemy_pos)][3] = [new_vec_x, new_vec_y]
            # 否则按单位向量移动敌机
            else:
                self.live_enemy[self.live_enemy.index(enemy_pos)][0] += self.live_enemy[self.live_enemy.index(enemy_pos)][2][0]
                self.live_enemy[self.live_enemy.index(enemy_pos)][1] += self.live_enemy[self.live_enemy.index(enemy_pos)][2][1]
        # 画出敌机
        for enemy_pos in self.live_enemy:
            # 按照飞机中心为标准
            self.screen.blit(self.enemy_picture, [enemy_pos[0]-self.enemy_picture.get_width()/2, enemy_pos[1]-self.enemy_picture.get_height()/2])

    # 创造敌机子弹
    def create_enemy_bullet(self):
        # 敌机随机概率发射朝向本机的子弹
        for enemy in self.live_enemy:
            if random.randint(0, 1600-300*self.hard) == 0:
                enemy_pos = [enemy[0]-20, enemy[1]+15]
                normal_vec = (Vec2d(self.my_plan_pos[0]+self.my_plan_picture.get_width()/4+20, self.my_plan_pos[1]+self.my_plan_picture.get_height()/4) - Vec2d(enemy_pos)).normalized()
                self.enemy_bullets.append([enemy_pos, normal_vec])
        # 画出子弹轨迹
        for bullet in self.enemy_bullets:
            if 0 < bullet[0][0] < 1920 and bullet[0][1] < 1080:
                bullet[0][0] += bullet[1][0]*2
                bullet[0][1] += bullet[1][1]*2
                self.screen.blit(self.enemy_bullet_picture, bullet[0])
            # 销毁超出范围的子弹
            else:
                self.enemy_bullets.remove(bullet)

    # boss发射子弹
    def boss_shut(self):
        do_shut = random.randint(1, 3)
        # 第一种方法,圆形
        if do_shut == 1:
            for x in range(21):
                angle = math.pi / 10
                copy_pos = copy.deepcopy([self.boss_pos[0] + 140, self.boss_pos[1] + 100])
                normal_vec = Vec2d(math.cos(x*angle), math.sin(x*angle)).normalized()
                self.enemy_bullets.append([copy_pos, normal_vec])
        # 第二种方法，螺旋
        elif do_shut == 2:
            for x in range(-10, 11):
                angle = math.pi / 10
                copy_pos = copy.deepcopy([self.boss_pos[0] + 140, self.boss_pos[1] + 100])
                normal_vec = Vec2d(math.cos(x * angle), math.sin(x * angle)).normalized()
                self.enemy_bullets.append([copy_pos, normal_vec])
                sleep(0.05)
        # 第三种方法，来回
        elif do_shut == 3:
            for x in range(-10, 11):
                angle = math.pi / 10
                copy_pos = copy.deepcopy([self.boss_pos[0] + 140, self.boss_pos[1] + 100])
                normal_vec = Vec2d(math.cos(x * angle), abs(math.sin(x * angle))).normalized()
                self.enemy_bullets.append([copy_pos, normal_vec])
                sleep(0.1)

    # 创造boss
    def create_boss(self):
        if self.my_count == 100 and self.have_boss == 0:
            self.have_boss = 1
        if self.have_boss == 1:
            # 登场
            if self.boss_pos[1] < 60:
                it_font = pygame.font.SysFont('heiti', 60, True)
                text = it_font.render('Boss Coming!', True, (random.randint(100, 205), self.time_record % 255, random.randint(100, 200)))
                self.screen.blit(text, (800, 500))
                self.boss_pos[1] += 0.3
                self.screen.blit(self.boss_picture, self.boss_pos)
            else:
                if self.time_record % (800-self.hard*100) == 0:
                    Thread(target=self.boss_shut).start()
                # 左右移动
                if self.boss_pos[0] < 0 or self.boss_pos[0] > 1600:
                    self.boss_toward = self.boss_toward - 2 * self.boss_toward
                self.boss_pos[0] += self.boss_toward / 2
                self.screen.blit(self.boss_picture, self.boss_pos)

    # 判断是否击中敌机
    def judge_damage_enemy(self):
        width = self.enemy_picture.get_width()
        height = self.enemy_picture.get_height()
        for enemy in self.live_enemy:
            for bullet_pos in self.my_bullets:
                # 敌机坐标
                enemy_pos = copy.deepcopy([enemy[0], enemy[1]])
                # 判断敌机是否在子弹周围
                if enemy_pos[0]-width/2 <= bullet_pos[0] <= enemy_pos[0]+width/2 and enemy_pos[1] <= bullet_pos[1] <= enemy_pos[1]+height:
                    # 删除击中敌机的子弹
                    self.my_bullets.remove(bullet_pos)
                    # 在没有道具的情况下有概率爆出道具
                    if random.randint(1, 15) == 5 and self.have_box == 0 and len(self.box_list) == 0:
                        self.box_list.append([enemy_pos[0]-30, enemy_pos[1]-70])
                    # 向爆炸列表中添加坐标并初始化爆炸时间为0
                    try:
                        self.live_enemy.remove(enemy)
                    except ValueError:
                        pass
                    self.booming_pos.append([[enemy_pos[0]-width/2, enemy_pos[1]-height/2], 0])
                    # 得分+1
                    self.my_count += 1
                # 判断导弹是否击中敌机
                if len(self.missile_list[0]) > 0:
                    if enemy_pos[0]-width/2 <= self.missile_list[0][0] <= enemy_pos[0]+width/2 and enemy_pos[1]-20 <= self.missile_list[0][1] <= enemy_pos[1]+20:
                        # 删除该导弹
                        self.missile_list = [[], []]
                        # 在没有道具的情况下有概率爆出道具
                        if random.randint(1, 15) == 5 and self.have_box == 0 and len(self.box_list) == 0:
                            self.box_list.append([enemy_pos[0]-30, enemy_pos[1]-70])
                        # 向爆炸列表中添加坐标并初始化爆炸时间为0
                        try:
                            self.live_enemy.remove(enemy)
                        except ValueError:
                            pass
                        self.booming_pos.append([[enemy_pos[0]-width/2, enemy_pos[1]-height/2], 0])
                        # 得分+1
                        self.my_count += 1
        # 判断是否击中boss
        if self.have_boss == 1:
            for bullet in self.my_bullets:
                if self.boss_pos[0] < bullet[0] < self.boss_pos[0]+280 and self.boss_pos[1] < bullet[1] < self.boss_pos[1]+100:
                    self.booming_pos.append([bullet, 0])
                    self.my_bullets.remove(bullet)
                    # boss血量-1
                    self.boss_life -= 1
                    self.my_count += 1

    # 判断是否击中本机
    def judge_damage_me(self):
        width = self.enemy_picture.get_width()
        height = self.enemy_picture.get_height()
        for bullet in self.enemy_bullets:
            if self.my_plan_pos[0]+20 < bullet[0][0] < self.my_plan_pos[0]+80 and self.my_plan_pos[1] < bullet[0][1] < self.my_plan_pos[1]+80:
                # 删除该子弹并添加爆炸
                self.enemy_bullets.remove(bullet)
                self.booming_pos.append([self.my_plan_pos, 0])
                # 生命-1
                self.my_life -= 1
                # 设置无敌时间并重置坐标
                self.is_not_defeat = 400
                self.my_plan_pos = [900, 800]
        # 判断撞击
        for enemy in self.live_enemy:
            enemy_pos = copy.deepcopy([enemy[0] - width / 2, enemy[1] - height / 2])
            if enemy_pos[0]-10 < self.my_plan_pos[0]+self.my_plan_picture.get_width()/2 < enemy_pos[0]+60 and enemy_pos[1]-10 < self.my_plan_pos[1]+self.my_plan_picture.get_height()/2 < enemy_pos[1]+60:
                # 向爆炸列表中添加坐标并初始化爆炸时间为0
                try:
                    self.live_enemy.remove(enemy)
                except ValueError:
                    pass
                self.booming_pos.append([[enemy_pos[0], enemy_pos[1]], 0])
                self.booming_pos.append([self.my_plan_pos, 0])
                # 生命-1
                self.my_life -= 1
                # 设置无敌时间并重置坐标
                self.is_not_defeat = 400
                self.my_plan_pos = [900, 800]

    # 移动道具盒子
    def move_box(self):
        for box_pos in self.box_list:
            box_pos[1] += 1
            self.screen.blit(self.box_picture, box_pos)
            # 判断是否捡到
            if self.my_plan_pos[0]-50 < box_pos[0] < self.my_plan_pos[0]+70 and self.my_plan_pos[1]-60 < box_pos[1] < self.my_plan_pos[1]+20:
                self.box_list.remove(box_pos)
                # 随机一个道具效果
                self.have_box = random.randint(1, 4)

    # 使本机无敌
    def remove_not_defeat(self):
        if self.is_not_defeat > 0:
            self.now_plan_picture = self.not_defeat_picture
            self.is_not_defeat -= 1
        else:
            # 恢复普通状态
            self.now_plan_picture = self.my_plan_picture

    # 显示数据
    def draw_life_count(self):
        # 显示剩余生命
        for number in range(self.my_life):
            self.screen.blit(self.small_plan, [number*50, 10])
        # 显示得分
        string = '得分 %d' % self.my_count
        submit = self.my_font.render(string, True, (150, 200, 0))
        self.screen.blit(submit, (1800, 20))
        # 显示难度系数
        how_hard = self.my_font.render('难度 %d' % self.hard, True, (0, 50, 230))
        pygame.draw.line(self.screen, (255, 100, 0), (1850, 150), (1850, 150-self.hard*10), 10)
        pygame.draw.lines(self.screen, (0, 150, 150), True, [(1844, 100), (1856, 100), (1856, 110), (1844, 110), (1844, 120), (1856, 120), (1856, 130), (1844, 130), (1844, 140), (1856, 140), (1856, 150), (1844, 150)], 2)
        pygame.draw.line(self.screen, (0, 150, 150), (1856, 100), (1856, 150), 2)
        # 显示剩余能量
        self.screen.blit(how_hard, (1800, 50))
        how_hard = self.my_font.render('能量', True, (0, 230, 50))
        self.screen.blit(how_hard, (28, 215))
        pygame.draw.line(self.screen, (0, 50, 255), (50, 200), (50, 200-self.my_power/10), 14)
        pygame.draw.lines(self.screen, (255, 50, 0), True, [(43, 100), (58, 100), (58, 200), (43, 200)], 2)
        # 显示boss血条
        if self.boss_life > 0:
            pygame.draw.line(self.screen, (5, 250, 100), self.boss_pos, (self.boss_pos[0] + self.boss_life*1.1, self.boss_pos[1]), 13)

    # 爆炸特效
    def boom(self):
        # 依次爆炸
        for pos in self.booming_pos:
            if pos[1] <= 80:
                self.screen.blit(self.boom_picture, pos[0])
                # 爆炸延迟
                pos[1] += 1

    # 开始主循环
    def began(self):
        over = 0
        while 1:
            # 隐藏鼠标
            pygame.mouse.set_visible(False)
            # 时间标志
            self.time_record += 1
            # time_pass = self.clock.tick()
            # pass_second = self.time_pass/1000.0
            # 判断退出
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.display.quit()
                    exit()
                elif event.type == KEYDOWN:
                    keys_press = pygame.key.get_pressed()
                    # alt+f4退出
                    if keys_press[K_LALT] and keys_press[K_F4]:
                        pygame.display.quit()
                        exit()
                    # 调节难度
                    elif keys_press[K_LCTRL]:
                        if self.hard != 5:
                            self.hard += 1
                        else:
                            self.hard = 0
                # 使用能量
                elif event.type == MOUSEBUTTONDOWN and self.my_power > 0:
                        self.sub_my_power = 1
                elif event.type == MOUSEBUTTONUP:
                    self.my_bullet_speed = 20
                    self.my_bullet_number = 1
                    self.sub_my_power = 0
            # 消耗能量
            if self.sub_my_power == 1 and self.my_power > 0:
                self.my_bullet_speed = 10
                self.my_bullet_number = 2
                self.my_power -= 1.9
            else:
                self.my_bullet_speed = 20
                self.my_bullet_number = 1
            # 恢复能量
            if self.my_power < 1000:
                self.my_power += 0.4
            self.screen.blit(self.background, (0, 0))
            self.remove_not_defeat()
            if self.boss_life > 0:
                self.create_boss()
            else:
                self.have_boss = 0
            self.move_my_plan()
            self.create_enemy()
            self.create_my_bullet()
            self.create_enemy_bullet()
            self.judge_damage_enemy()
            # 无敌状态
            if self.is_not_defeat == 0:
                self.judge_damage_me()
            self.move_box()
            self.show_box()
            self.boom()
            self.draw_life_count()
            # 结束游戏
            if self.my_life < 0:
                over += 1
            if over == 1:
                font = pygame.font.SysFont('kaiti', 50, True)
                text = font.render('Game Over!', True, (255, 20, 50))
                self.screen.blit(text, (800, 400))
                text = font.render('最终得分 %d' % self.my_count, True, (255, 20, 50))
                self.screen.blit(text, (780, 500))
                pygame.display.update()
            if self.my_life >= 0:
                pygame.display.update()

plane = Plan()
plane.began()


from posixpath import split

from itertools import combinations
def comb(inarr,innum):
    c=combinations(inarr,4)
    count=0
    for i in list(c):
        if sum(i)==innum:
            count+=1

inarr=map(int,input().split(''))
innum=int(input())


from http.server import HTTPServer, CGIHTTPRequestHandler

def run_server():
    server_address = ("127.0.0.1",2222)
    print("Веб-сервер запущено!")
    httpd = HTTPServer(server_address, CGIHTTPRequestHandler)
    httpd.serve_forever()

if __name__ == "__main__":
    run_server()


import json
import re
import sqlite3
import string

def addWord(wordDf, rStr):
    print(f"input: '{rStr}'")
    wEnd = rStr.find(' (')
    wd = rStr[:wEnd]
    altern = []
    if wd.find('/') > 0:
        mwd = wd.split('/')
        wd = mwd[0].strip()
        altern = mwd[1:]
    elif wd.find('(') >= 0:
        altern = [re.sub(r'[\(\)]', '', wd)]
        wd = re.sub(r'\(.*\)', '', wd)
    wNotes = [wn.rstrip(' )') for wn in rStr[wEnd:].split('(')[1:]]
    wordDf[wd] = {
        'alternatives': altern,
        'notes':        wNotes[1:],
        'partOfSpeech': wNotes[0],
        'example':      [],
    }
    return wd

def addExample(wordDf, wd, example):
    wordDf[wd]['example'].append(example)
    # print(f"'{wd}' example: {wordDf[wd]['example']}")

def fileTowordDf(wordFile, wordDf):
    with open(wordFile) as f:
        curWd = None
        for line in f:
            if line.isspace():  # ignore empty line
                continue
            line = line.strip()
            if line.isupper() and len(line) == 1:
                print(f"ignore '{line}'\n")
                continue
            # new word or example
            if line.startswith('.'):  # example of current word
                if not curWd:
                    continue  # no current word
                addExample(wordDf, curWd, line.lstrip(" ."))
            else:
                curWd = addWord(wordDf, line)

def dbQueryWord(cur, wd):
    sql = f'select phonetic, definition, translation from ecdict where word = "{wd}"'
    cur.execute(sql)
    return cur.fetchone()

def lookupDict(wordDf, dbFile):
    maxlen = 640
    # ecdict imported from https://github.com/skywind3000/ECDICT
    conn = sqlite3.connect(dbFile)
    cur = conn.cursor()
    invalidWords = []
    # lookup the ecdict
    for wd in wordDf:
        lwd = wd.strip('.!?')
        row = dbQueryWord(cur, lwd)
        if row:
            wordDf[wd]['phonetic'], wordDf[wd]['definition'], wordDf[wd]['translation'] = row
        else:  # try lookup lower case word
            row = dbQueryWord(cur, lwd.lower())
            if row:
                wordDf[wd]['phonetic'], wordDf[wd]['definition'], wordDf[wd]['translation'] = row
            else:
                print(f"{wd} not found in ecdict, deleting")
                invalidWords.append(wd)
                continue
        deflen = len(wordDf[wd]['definition']) + len(wordDf[wd]['translation'])
        if deflen > maxlen:
            print(f'!!def of {wd} is {deflen}!!')
    conn.close()
    return invalidWords

def wordListToHtml(wordList, wordDf, ignoreWords, htmlFile, title):
    jscript = '''

    '''
    htmlHead = f'''
    <meta charset="UTF-8">
        <title>{title}</title>
        <link href="flashcard.css" rel="stylesheet">
        {jscript}

    '''
    htmlTail = '''

    '''
    outFile = open(htmlFile, 'w', encoding='utf-8')
    outFile.write(htmlHead)
    # format word list to html
    for wd in wordList:
        if wd not in wordDf:
            print(f"{wd} not found, ignore!")
            continue
        partOfSpeech = ''
        if wordDf[wd]['partOfSpeech']:
            partOfSpeech += f"({wordDf[wd]['partOfSpeech']})"
        alternatives = ''
        if wordDf[wd]['alternatives']:
            alternatives = '/' + '/'.join(wordDf[wd]['alternatives'])
        phonetic = ''
        if wordDf[wd]['phonetic']:
            phonetic = f"[{wordDf[wd]['phonetic']}]"
        notes = ''
        if wordDf[wd]['notes']:
            notes = '
' + '; '.join(wordDf[wd]['notes']) + '
'
        examples = ''
        if wordDf[wd]['example']:
            for item in wordDf[wd]['example']:
                examples += f"
{item}
\n"
        if examples:
            examples = '
' + examples + '
'
        translation = wordDf[wd]['translation'].replace('\\n', '
\n')
        if translation:
            translation = '
' + translation + '
'
        definition = ''
        if wd not in ignoreWords:
            definition = wordDf[wd]['definition'].replace('\\n', '
\n')
        if definition:
            definition = '
' + definition + '
'

        cardHtml = f'''

Charlie

                        {wd}{alternatives}
                         {partOfSpeech}

                        {phonetic}

                    {notes}
                    {examples}

                    {translation}
                    {definition}

        '''
        outFile.write(cardHtml)

    outFile.write(htmlTail)
    outFile.close()

def printWrodDfStats(wordDf):
    # general info of wordDf
    words = wordDf.keys()
    for c in string.ascii_lowercase:
        cnt = len([wd for wd in words if wd[0].lower() == c])
        print(f'{c}: {cnt}')
    print("total words: " + str(len(words)))

def woriteWordDfHtmlByGrp(wordDf, workDir, ignoreWords):
    htmlOutGrp = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'ijk',
                  'l', 'm', 'no', 'p', 'qr', 's', 't', 'uvwxyz']
    for i in htmlOutGrp:
        htmlFile = f'{workDir}words_{i}.html'
        wlist = [wd for wd in wordDf if (wd[0].lower() in i)]
        wordListToHtml(wlist, wordDf, ignoreWords, htmlFile, f'Cambridge English A2 vocabulary Flashcards {i}')

if __name__ == "__main__":
    workDir = 'd:\\data\\flashcards\\'
    wordDf = {}
    readWordsFromJson = True
    wdJsnFile = workDir + 'a2keyWL.json'
    if readWordsFromJson:
        wordDf = json.load(open(wdJsnFile, 'r', encoding='utf-8'))
    else:
        wordFile = workDir + 'a2vl.txt'
        fileTowordDf(wordFile, wordDf)
        dbFile = workDir + 'ecdict.db'
        invalidWords = lookupDict(wordDf, dbFile)
        for wd in invalidWords:
            del wordDf[wd]
        # write wordDf to json file
        with open(wdJsnFile, 'w', encoding='utf-8') as jf:
            json.dump(wordDf, jf, sort_keys=True)
    #printWrodDfStats(wordDf)
    # words with loong definitions
    # wlist = ['CD', 'against', 'answer', 'as', 'capital', 'chips', 'colour', 'directions', 'father', 'field',
    #          'for', 'from', 'gas', 'glasses', 'green', 'herself', 'himself', 'hot', 'into', 'kite', 'left',
    #          'long', 'lots', 'more', 'mouse', 'mushroom', 'of', 'post', 'programme', 'right', 'shall', 'shorts',
    #          'since', 'stripes', 'studies', 'subject', 'than', 'that', 'to', 'us', 'water', 'what', 'when', 'where',
    #          'which', 'with', 'without', 'work']
    # wordListToHtml(wlist, wordDf, [], f'{workDir}test.html', 'flashcard test')

    # write all words in one large html file
    wordListToHtml(wordDf.keys(), wordDf, [], f'{workDir}test.html', 'Cambridge English A2 vocabulary Flashcards')

    # grp = 'uvwxyz'
    # wlist = [wd for wd in wordDf if (wd[0].lower() in grp)]
    # wordListToHtml(wlist, wordDf, [], f'{workDir}words_{grp}.html', f'Cambridge English A2 vocabulary Flashcards {grp}')

    # write html group by leading letter
    # woriteWordDfHtmlByGrp(wordDf, workDir, [])


import os
import shutil
import subprocess

import pytest
from sos import execute_workflow
from sos.parser import SoS_Script
from sos.targets import file_target
from sos.utils import env

def test_progress_bar():
    # progress bar with nested workflow
    execute_workflow(
        '''
import time
time.sleep(0)
[sub_1]
[sub_2]
[sub_3]
[sub_4]
[a_1]
[a_2]
[a_3]
sos_run('sub')
[a_4]
[a_5]
''',
        workflow='a')

def test_nested_workflow(temp_factory, clear_now_and_after):
    '''Test the creation and execution of combined workfow'''
    clear_now_and_after('a.done')
    temp_factory('a.txt', 'b.txt', 'b.begin')
    execute_workflow(
        '''
        if 'executed' not in locals():
            executed = []
        if 'inputs' not in locals():
            inputs = []

        [a_1: shared=['executed', 'inputs']]
        executed.append(step_name)
        inputs.append(_input)

        [a_2: shared=['executed', 'inputs']]
        executed.append(step_name)
        inputs.append(_input)

        [a_3: shared=['executed', 'inputs']]
        executed.append(step_name)
        inputs.append(_input)

        [a_4: shared=['executed', 'inputs']]
        executed.append(step_name)
        output: 'a.done'
        inputs.append(_input)
        run: expand=True
        touch {_output}

        [b_1: shared=['executed', 'inputs']]
        executed.append(step_name)
        input: 'b.begin'
        inputs.append(_input)

        [b_2: shared=['executed', 'inputs']]
        executed.append(step_name)
        inputs.append(_input)

        [b_3: shared=['executed', 'inputs']]
        executed.append(step_name)
        inputs.append(_input)

        [b_4: shared=['executed', 'inputs']]
        executed.append(step_name)
        output: 'b.txt'
        inputs.append(_input)

        [c: shared=['executed', 'inputs']]
        executed.append(step_name)
        input: 'a.txt'
        output: 'b.txt'
        inputs.append(_input)
        sos_run('a+b', shared=['executed', 'inputs'])
        ''',
        workflow='c',
        options={'sig_mode': 'ignore'})

    # order of execution is not guaranteed
    assert sorted(env.sos_dict['executed']) == sorted(
        ['c', 'a_1', 'a_2', 'a_3', 'a_4', 'b_1', 'b_2', 'b_3', 'b_4'])
    env.sos_dict.pop('executed', None)

def test_looped_nested_workflow(temp_factory, clear_now_and_after):
    # step will be looped
    clear_now_and_after('a.txt.a1', 'a.txt.a1.a2', 'b.txt.a1', 'b.txt.a1.a2')
    temp_factory('a.txt', 'b.txt')

    execute_workflow(
        '''
        if 'executed' not in locals():
            executed = []
        if 'inputs' not in locals():
            inputs = []

        [a_1:shared=['executed', 'inputs']]
        executed.append(step_name)
        output: _input[0] + '.a1'
        inputs.append(_input)
        run: expand=True
        touch {_output}

        [a_2:shared=['executed', 'inputs']]
        executed.append(step_name)
        output: _input[0] + '.a2'
        inputs.append(_input)
        run: expand=True
        touch {_output}

        [c:shared=['executed', 'inputs']]
        executed.append(step_name)
        input: 'a.txt', 'b.txt', group_by='single'
        inputs.append(_input)
        sos_run('a', shared=['executed', 'inputs'])
        ''',
        workflow='c')
    assert env.sos_dict['executed'] == ['c', 'a_1', 'a_2', 'a_1', 'a_2']

def test_single_looped_nested_workflow(temp_factory, clear_now_and_after):
    temp_factory('a.txt', 'b.txt')
    env.sos_dict.pop('executed', None)

    execute_workflow(
        '''
        if 'executed' not in locals():
            executed = []
        [a_1:shared='executed']
        executed.append(step_name)
        [a_2:shared='executed']
        executed.append(step_name)
        [c_0:shared='executed']
        executed.append(step_name)
        [c_1:shared='executed']
        depends: sos_variable('executed')
        executed.append(step_name)
        input: 'a.txt', 'b.txt', group_by='single'
        sos_run('a:2', shared='executed')
        ''',
        workflow='c')
    assert env.sos_dict['executed'] == ['c_0', 'c_1', 'a_2', 'a_2']
    env.sos_dict.pop('executed', None)
    # allow specifying a single step
    # step will be looped
    execute_workflow(
        '''
        if 'executed' not in locals():
            executed = []

        [a_1:shared='executed']
        executed.append(step_name)

        [a_2:shared='executed']
        executed.append(step_name)

        [c_0:shared='executed']
        executed.append(step_name)

        [c_1:shared='executed']
        depends: sos_variable('executed')
        executed.append(step_name)
        input: 'a.txt', 'b.txt', group_by='single'
        sos_run('a:2', shared='executed')
        ''',
        workflow='c')

    assert env.sos_dict['executed'] == ['c_0', 'c_1', 'a_2', 'a_2']

def test_recursive_nested_workflow(temp_factory):
    # recursive subworkflow not allowed
    temp_factory('a.txt', 'b.txt')
    with pytest.raises(Exception):
        execute_workflow(
            '''
            if 'executed' not in locals():
                executed = []
            [a_1:shared='executed']
            executed.append(step_name)
            [a_2:shared='executed']
            executed.append(step_name)
            [c_0:shared='executed']
            executed.append(step_name)
            [c_1:shared='executed']
            executed.append(step_name)
            input: 'a.txt', 'b.txt', group_by='single'
            sos_run('a_2+c', shared='executed')
            ''',
            workflow='c')
    #
    env.sos_dict.pop('executed', None)
    # nested subworkflow is allowed
    execute_workflow(
        '''
        if 'executed' not in locals():
            executed = []
        [a_1:shared='executed']
        executed.append(step_name)
        [a_2:shared='executed']
        executed.append(step_name)
        [a_3:shared='executed']
        executed.append(step_name)
        [b_1:shared='executed']
        executed.append(step_name)
        [b_2:shared='executed']
        executed.append(step_name)
        sos_run('a:1-2', shared='executed')
        [c_0:shared='executed']
        executed.append(step_name)
        [c_1:shared='executed']
        depends: sos_variable('executed')
        executed.append(step_name)
        input: 'a.txt'
        sos_run('a+b', shared='executed')
        ''',
        workflow='c')

    assert env.sos_dict['executed'] == [
        'c_0', 'c_1', 'a_1', 'a_2', 'a_3', 'b_1', 'b_2', 'a_1', 'a_2'
    ]

    env.sos_dict.pop('executed', None)

def test_subworkflow_with_options(temp_factory, clear_now_and_after):
    # nested subworkflow with step option and others
    temp_factory('a.txt', 'b.txt')
    clear_now_and_after('a.done')
    script = '''
        if 'executed' not in locals():
            executed = []
        [a_1:shared='executed']
        executed.append(step_name)

        [a_2:shared='executed']
        executed.append(step_name)

        [a_3:shared='executed']
        executed.append(step_name)

        [b:shared='executed']
        executed.append(step_name)
        input: 'a.txt', 'b.txt', group_by='single'
        sos_run('a:3+a:1', shared='executed')

        [d:shared='executed']
        executed.append(step_name)
        input: 'a.txt', 'b.txt', group_by='single'
        sos_run('a:2', shared='executed')

        [e2_2:shared='executed']
        executed.append(step_name)
        input: 'a.txt', 'b.txt', group_by='single'
        '''
    execute_workflow(script, workflow='b')
    assert env.sos_dict['executed'] == ['b', 'a_3', 'a_1', 'a_3', 'a_1']

    env.sos_dict.pop('executed', None)

    execute_workflow(script, workflow='d')
    assert env.sos_dict['executed'] == ['d', 'a_2', 'a_2']
    env.sos_dict.pop('executed', None)

    execute_workflow(script, workflow='e2')
    assert env.sos_dict['executed'] == ['e2_2']

def test_dynamic_nested_workflow():
    '''Test nested workflow controlled by command line option'''
    script = '''
        if 'executed' not in locals():
            executed = []

        parameter: wf='a'

        [a_1:shared='executed']
        executed.append(step_name)
        [a_2:shared='executed']
        executed.append(step_name)
        [a_3:shared='executed']
        executed.append(step_name)
        [b_1:shared='executed']
        executed.append(step_name)
        [b_2:shared='executed']
        executed.append(step_name)
        [b_3:shared='executed']
        executed.append(step_name)

        [default:shared='executed']
        executed.append(step_name)
        sos_run(wf, shared='executed')
        '''
    execute_workflow(script, args=['--wf', 'b'])
    assert env.sos_dict['executed'] == ['default', 'b_1', 'b_2', 'b_3']
    #
    env.sos_dict.pop('executed', None)
    execute_workflow(script, args=['--wf', 'a'])
    assert env.sos_dict['executed'] == ['default', 'a_1', 'a_2', 'a_3']

def test_sos_run(clear_now_and_after):
    '''Test action sos_run with keyword parameters'''
    clear_now_and_after('0.txt', '1.txt')
    execute_workflow(
        r'''
        [A]
        parameter: num=5

        run: expand=True
            touch {num}.txt

        [batch]
        for k in range(2):
            sos_run('A', num=k)
        ''',
        workflow='batch')

    for f in ['0.txt', '1.txt']:
        assert file_target(f).target_exists()
    #
    clear_now_and_after('0.txt', '1.txt', '5.txt')

    execute_workflow(
        r'''
        [A]
        parameter: num=5
        run: expand=True
            touch {num}.txt

        [batch]
        for num in range(2):
            sos_run('A')
        ''',
        workflow='batch')
    for f in ['0.txt', '1.txt']:
        assert not file_target(f).target_exists()

    assert file_target('5.txt').target_exists()

    clear_now_and_after('10.txt', '11.txt')
    #
    # test parameter shared to send and return vars
    #
    execute_workflow(
        r'''
        [A: shared='k']
        k += 10

        [batch]
        for k in range(2):
            sos_run('A', shared='k')
            run(f"touch {k}.txt")
        ''',
        workflow='batch')
    for f in ['10.txt', '11.txt']:
        assert file_target(f).target_exists()

def test_da_gof_dynamic_nested_workflow(clear_now_and_after):
    #
    # Because we are not sure which workflows would be executed
    # until run time, the DAG should not contain nested workflow
    # until runtime.
    #
    clear_now_and_after('B0.txt', 'B0.txt.p', 'B1.txt', 'B1.txt.p', 'B2.txt',
                        'B2.txt.p')
    #
    #  A1 <- P <- B
    #  A1 <- P <- B
    #  A2
    #
    #  ALL calls A and B with parameter
    #
    execute_workflow(
        '''
        [A_1]
        parameter: num = 2
        input: f"B{num}.txt.p"

        [B: provides='B{num}.txt']
        run: expand=True
        touch 'B{num[0]}.txt'

        [P: provides='{filename}.p']
        input: filename
        run: expand=True
        touch {_output}

        [ALL]

        for i in range(3):
            sos_run('A', num=i)
    ''',
        workflow='ALL')
    for f in ['B0.txt', 'B0.txt.p', 'B1.txt', 'B1.txt.p', 'B2.txt', 'B2.txt.p']:
        assert file_target(f).target_exists()

def test_outcome_oriented_nested_workflow(clear_now_and_after):
    '''test nested workflow triggered by targets'''
    clear_now_and_after('test_15.txt')

    execute_workflow('''
[A: provides='test_{idx}.txt']
_output.touch()

[default]
sos_run(targets='test_15.txt')
    ''')
    assert os.path.isfile('test_15.txt')

def test_passing_vars_to_nested_workflow():
    '''Test if variables can be passed to nested workflows'''
    execute_workflow(r"""
        import time
        import random

        [nested]
        parameter: nested=True
        parameter: seed=1
        print(f'I am nested {nested} with seed {seed}')

        [0]
        reps = range(5)
        input: for_each='reps'
        import random
        nested = _reps
        seed = random.randint(1, 1000)
        print(f'Passing {seed} to {nested}')
        sos_run('nested', nested=nested, seed=seed)
    """)

def test_user_defined_func():
    '''Test the use of user-defined functions in SoS script'''
    execute_workflow(
        r"""
        def myfunc():
            return 'a'

        [1: shared={'test':'_output'}]
        output: myfunc()

        myfunc()

        """,
        options={'run_mode': 'dryrun'})
    assert env.sos_dict['test'] == ['a']
    # User defined function should also work under nested workflows
    # This is difficult because the 'local namespace' is usually
    # not seen inside function definition. The solution now is to
    # use a single workspace.
    execute_workflow(
        r"""
        def myfunc():
            # test if builtin functions (sum and range) can be used here.
            return 'a' + str(sum(range(10)))

        [1: shared={'test':'_output'}]
        output: [myfunc() for i in range(10)][0]

        myfunc()

        """,
        options={'run_mode': 'dryrun'})
    assert env.sos_dict['test'] == ['a45']

def test_config_file_of_nested_workflow(config_factory):
    '''Test passing of configurationg to nested workflow'''
    cfg = config_factory("""{'1':'hi'}""")

    execute_workflow(
        '''
[test_1]
parameter: key = None
print(CONFIG[key])

[default_1]
sos_run('test:1', key = '1')
''',
        options={'config_file': cfg})

def test_error_from_subworkflow():
    '''Test if error from subworkflow is passed to master (#396)'''
    with pytest.raises(Exception):
        execute_workflow('''
            [test_1]
            R:
            set.seed(xxx)

            [default]
            sos_run('test')
            ''')

def test_fun_def(temp_factory):
    '''Test defintion of function that can be used by other steps'''
    temp_factory('aa.txt', 'ab.txt')
    # in nested workflow?
    execute_workflow(
        r"""
        def myfunc(a):
            return ['a' + x for x in a]

        [mse: shared={'test':'_output'}]
        input: myfunc(['a.txt', 'b.txt'])

        [1]
        sos_run('mse')
        """,
        options={'run)mode': 'dryrun'})
    #
    # Names defined in subworkflow is not returned to the master dict
    assert 'test' not in env.sos_dict

def test_search_path(clear_now_and_after):
    '''Test if any action should exit in five seconds in dryrun mode'''
    clear_now_and_after('crazy_path', 'test.yml')

    sos_config_file = os.path.join(
        os.path.expanduser('~'), '.sos', 'config.yml')
    shutil.copy(sos_config_file, 'test.yml')
    #
    subprocess.call(
        'sos config --set sos_path {0}/crazy_path {0}/crazy_path/more_crazy/'
        .format(os.getcwd()),
        shell=True)
    #
    if not os.path.isdir('crazy_path'):
        os.mkdir('crazy_path')
        os.mkdir(os.path.join('crazy_path', 'more_crazy'))
    with open(os.path.join('crazy_path', 'crazy_master.sos'), 'w') as crazy:
        crazy.write('''
[0]
sos_run('cc', source='crazy_slave.sos')

''')
    with open(os.path.join('crazy_path', 'more_crazy', 'crazy_slave.sos'),
              'w') as crazy:
        crazy.write('''
[cc_0]
print('hay, I am crazy')
''')

    script = SoS_Script(filename='crazy_master.sos')
    script.workflow()
    #
    os.remove(sos_config_file)
    shutil.copy('test.yml', sos_config_file)

def test_nested_workdir(clear_now_and_after, purge_tasks):
    '''Test nested runtime option for work directory'''
    clear_now_and_after('tmp', 'tmp1')
    execute_workflow(
        '''
        [step]
        task: workdir='tmp1'
        run:
            touch 'a.txt'

        [default]
        sos_run('step', workdir='tmp')
        ''',
        options={'default_queue': 'localhost'})

    assert os.path.isfile('tmp1/a.txt')

def test_failure_of_nested_workflow(clear_now_and_after):
    '''Test failure of nested workflow #838'''
    clear_now_and_after('a.txt')
    with pytest.raises(Exception):
        execute_workflow('''
            [something]
            input: 'a.txt'

            [default]
            sos_run('something')
            ''')

def test_nested_from_another_file(clear_now_and_after):
    '''Test nested runtime option for work directory'''
    clear_now_and_after('a.txt', 'another.sos')
    with open('another.sos', 'w') as another:
        another.write('''
[whatever]
run:
touch 'a.txt'

''')
    execute_workflow('''
        [default]
        sos_run('whatever', source='another.sos')
        ''')
    assert os.path.isfile(
        'a.txt'
    ), 'a.txt should have been created by nested workflow from another file'

def test_concurrent_sub_workflow():
    '''Test concurrent subworkflow sos_run '''
    import time
    st = time.time()

    execute_workflow(
        '''
        [A]
        parameter: idx=0
        import time
        time.sleep(5)

        [default]
        input: for_each=dict(i=range(6))
        sos_run('A', idx=i)
        ''',
        options={'worker_procs': ['8']})
    assert time.time() - st < 30

def test_sos_multi_workflow():
    '''Test multiple workflows in sos_run '''
    import time
    st = time.time()

    execute_workflow(
        '''
        [B]
        parameter: idx=2
        import time
        time.sleep(idx)

        [A]
        import time
        time.sleep(idx)

        [default]
        input: for_each=dict(i=range(4))
        sos_run(['A', 'B'], idx=i)
    ''',
        options={'worker_procs': ['8']})
    assert time.time() - st < 20

def test_pass_of_args():
    '''Test passing of arguments through sos_run #1164'''
    with pytest.raises(Exception):
        execute_workflow('''
            parameter: b=2
            [A]
            parameter: c=1
            print(c)

            [default]
            sos_run('A', a=2)
        ''')
    #
    execute_workflow('''
        parameter: b=2
        [A]
        parameter: c=1
        print(c)

        [default]
        sos_run('A', b=2)
        ''')
    #
    execute_workflow('''
        parameter: b=2
        [A]
        parameter: c=1
        print(c)

        [default]
        sos_run('A', c=2)
    ''')

def test_nested_dynamic_depends(clear_now_and_after):
    '''Test the execution of nested workflow with dynamic depends'''
    clear_now_and_after('B30.txt', 'B30.txt.p', 'B0.txt.p', 'B0.txt')
    execute_workflow('''
        [A_1]
        parameter: num = 20
        input: f"B{num}.txt"
        depends: _input + '.p'

        [B: provides='B{num}.txt']
        run: expand=True
            touch {_output}

        [P: provides='{filename}.p']
        input: filename
        run: expand=True
            touch {_output}

        [default]
        sos_run('A', num=0)
    ''')

def test_neste_with_both_workflow_and_targets(clear_now_and_after):
    '''Test nested workflow with both workflow and targets'''
    clear_now_and_after('A_out.txt', 'B_out.txt')
    execute_workflow(r'''
        [A_20]
        output: 'A_out.txt'
        _output.touch()

        [B]
        output: 'B_out.txt'
        _output.touch()

        [default]
        sos_run('A', targets='B_out.txt')
        ''')
    assert os.path.isfile('A_out.txt')
    assert os.path.isfile('B_out.txt')


import collections
import re

# Intervalo de palabras que se incluirán en el diccionario
b = 0   # Inicio del intervalo
n = 40000 # Final del intervalo
sorted_vocab = []

vocab_file_path = "./corpora/quijote.txt"
tokenizer = re.compile("\W+")
with open(vocab_file_path, "r", encoding='utf-8') as fr:
    c= collections.Counter(tokenizer.split(fr.read().lower()))
    if '' in c:
        del c['']
    reversed_c = [(freq, word) for (word, freq) in c.items()]
    sorted_reversed = sorted(reversed_c, reverse=True)
    sorted_vocab = [word for (freq, word) in sorted_reversed]

with open("./corpora/quijote_"+str(b)+"_"+str(n)+".txt", "w", encoding='utf-8') as new_dict:
    new_dict.write(" ".join(sorted_vocab[b:n]))


import streamlit as st
import pandas as pd
import numpy as np

sorama = pd.read_csv('https://raw.githubusercontent.com/Jordds/gemEindhoven/main/sorama.csv',  nrows = 5)
vinotion = pd.read_csv('https://raw.githubusercontent.com/Jordds/gemEindhoven/main/csv_vinotion_sept.csv', nrows = 5)
tno = pd.read_csv('https://raw.githubusercontent.com/Jordds/gemEindhoven/main/csv_dust_sept.csv', nrows = 5)

devID = sorama['deviceId']
s = sorama['content'].str.split(',', n=3, expand = True)
s = s.rename(columns={0: 'measurementType', 1 :'timestamp', 2:'duration', 3:'value'})
s['timestamp'] = s['timestamp'].str[10:29]
s['date'] = pd.to_datetime(s['timestamp']).dt.date
s['time'] = pd.to_datetime(s['timestamp']).dt.time
s['hour'] = pd.to_datetime(s['timestamp']).dt.hour
s['value'] = s['value'].str.extract('(\d*\.\d+|\d+)', expand = False).astype(float)
s['measurementType'] = s['measurementType'].str[21:25]
s = s[['date', 'time', 'hour','measurementType', 'value']]
df3 = pd.concat([s, devID], axis=1)
df3['value'] = df3['value'].astype('float16') #reducing load on RAM

vinotion['Date'] = pd.to_datetime(vinotion['timestamp']).dt.date
vinotion['Time'] = pd.to_datetime(vinotion['timestamp']).dt.time
vinotion['camID'] = vinotion['cameraId'].str[17:19]
vinotion['direction'] = vinotion['ruleId'].str[20:27].str.replace('/', ' ')
vinotion['speed'] = vinotion['speed'] * 3.6 #csv contains m/s not km/h
df2 = vinotion[['Date', 'Time', 'speed', 'classification', 'camID','direction']]

conditions = [
        (df2['camID'] == '12') & (df2['direction'] == 'Count 0'),
        (df2['camID'] == '12') & (df2['direction'] == 'Count 1'),
        (df2['camID'] == '12') & (df2['direction'] == 'Count 2'),
        (df2['camID'] == '11') & (df2['direction'] == 'Count 0'),
        (df2['camID'] == '11') & (df2['direction'] == 'Count 1'),
        (df2['camID'] == '13') & (df2['direction'] == 'Count 0'),
        (df2['camID'] == '15') & (df2['direction'] == 'Count 0'),
        (df2['camID'] == '15') & (df2['direction'] == 'Count 1'),
        (df2['camID'] == '15') & (df2['direction'] == 'Count 2'),
        (df2['camID'] == '15') & (df2['direction'] == 'Count 3'),
        (df2['camID'] == '14') & (df2['direction'] == 'Count 0'),
        (df2['camID'] == '14') & (df2['direction'] == 'Count 1'),
        (df2['camID'] == '14') & (df2['direction'] == 'Count 2')
    ]
values = ['Onze Lieve Vrouwestraat',
          'Crossover from city',
          'Crossover to city',
          'From Kennedylaan',
          'Ring',
          'Ring',
          'From City',
          'From Ring',
          'Crossover to left',
          'Crossover to right',
          'Ring',
          'To the city',
          'Illegal turning'
         ]
df2['real_direction'] = np.select(conditions, values)
df2 = df2[['Date', 'Time', 'speed', 'classification', 'camID','real_direction']]

tno = tno.drop(tno.iloc[:,15:23], axis = 1)
tno['Lat'] = tno['geoPointLocation'].str.extract('(\d*\.\d+|\d+)', expand = False).astype(float)
tno['Lon'] = tno['geoPointLocation'].str[15:].str.extract('(\d*\.\d+|\d+)', expand = False).astype(float)
tno['Date'] = pd.to_datetime(tno['timestamp']).dt.date
tno['Time'] = pd.to_datetime(tno['timestamp']).dt.time
df = tno[['Date', 'Time', 'Lat', 'Lon', 'pm1', 'pm10', 'pm25']]

st.title("Data verzameld door de sensoren")
st.subheader("Sorama")
st.write(sorama)
st.write(df3)

st.subheader("vinotion")
st.write(vinotion)
st.write(df2)

st.subheader("TNO")
st.write(tno)
st.write(df)


from dotenv import load_dotenv
from pprint import pprint
from newsapi import NewsApiClient
import urllib
import os
from bs4 import BeautifulSoup
from readability import Document
from find_entity import find_entity
import pickle
import pandas as pd
from mysql_caching import set_cache_entities, get_cached_entities
import functools

load_dotenv()

newsapi = NewsApiClient(api_key=os.environ.get("GOOGLE_NEWS_API"))

@functools.lru_cache(maxsize=512)
def html2text(url: str) -> str:
    request = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0'})
    html = urllib.request.urlopen(request).read()
    doc = Document(html)
    cleaned = "
" + doc.short_title() + "

" + doc.summary()
    soup = BeautifulSoup(cleaned, features="html.parser")

    # kill all script and style elements
    for script in soup(["script", "style"]):
        script.extract()  # rip it out

    # get text
    text = soup.get_text()

    # break into lines and remove leading and trailing space on each
    lines = (line.strip() for line in text.splitlines())
    # break multi-headlines into a line each
    chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
    # drop blank lines
    text = "\n".join(chunk for chunk in chunks if chunk)
    return text

def process_headlines(language="en", country="gb"):
    top_headline = newsapi.get_top_headlines(
        language=language, country=country, page_size=100
    )
    result = []
    for article in top_headline["articles"]:
        try:

            article["text"] = html2text(article["url"])
            entities = get_cached_entities(article["url"])
            if entities is None:
                entities = find_entity(article["text"], language=language)
                set_cache_entities(article["url"], entities)
            article["entities"] = entities
            print("It worked for", article["url"], flush=True)
            result.append(article)
        except urllib.error.HTTPError as e:
            print(f"We cannot fetch for", article["url"], e, flush=True)
        except urllib.error.URLError as e:
            print(f"the url is wrong", article["url"], e, flush=True)

    df = pd.DataFrame(result)
    with open("headline_google.pickle", "wb") as output_file:
        pickle.dump(df, output_file)
    return df.to_json()

if __name__ == "__main__":
    process_headlines(language="en", country="gb")


''' Ketika fotonya ditampilin
ada dua pilihan,
mencet escape lalu keluar aja
atau mencet save yang akan mensave si gambarnya'''

import cv2
img = cv2.imread('D:/A LEARN/Image Processing/Program Youtube/Gambar/lena.jpg', 0)
cv2.imshow('Gambar Grayscale', img)
print ('Press ESC to Out\nOr \nPress S to save the picture')

k = cv2.waitKey() & 0xFF

if k == 27:
    cv2.destroyAllWindows()

elif k == ord('s'):
    cv2.imwrite('D:/A LEARN/Image Processing/Program Youtube/Gambar/lena_grayscale.PNG', img)
    cv2.destroyAllWindows()


import pygame as pg
import random
import math
import params

class Block(pg.sprite.Sprite):
    def __init__(self, speed):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface([40, 20])
        self.image.fill(pg.Color('black'))

        self.rect = self.image.get_rect()
        self.width = 40
        self.height = 20
        self.pos = [50,50]
        self.speed = speed

    def reset_pos(self):
        self.rect.y = random.randrange(-100, -10)
        self.rect.x = random.randrange(params.screen_width)

    def update(self):
        self.pos[1] += self.speed
        self.rect.x = int(self.pos[0])
        self.rect.y = int(self.pos[1])
        if self.rect.y > params.screen_height:
            self.reset_pos()

class Player(pg.sprite.Sprite):
    def __init__(self):
        self.width = 100
        self.height = 20
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface([self.width, self.height])
        #self.image = pg.image.load("player.png").convert()
        #self.image.set_colorkey(pg.Color('white'))
        self.image.fill(pg.Color('red'))

        self.rect = self.image.get_rect()

    def update(self):
        pos = pg.mouse.get_pos()
        self.rect.x = pos[0] - self.width / 2

class Bullet(pg.sprite.Sprite):
    def __init__(self):
        self.width = 4
        self.height = 10
        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface([self.width,self.height])
        self.image.fill(pg.Color('red'))
        self.rect = self.image.get_rect()

    def update(self):
        self.rect.y -= 6

class Ball(pg.sprite.Sprite):
    def __init__(self):

        pg.sprite.Sprite.__init__(self)
        self.image = pg.Surface([10,10])
        self.image = pg.image.load('ball.png').convert()
        self.image.set_colorkey(pg.Color('black'))

        self.rect = self.image.get_rect()
        self.rect.x = 50
        self.rect.y = 50
        self.angle = 180
        self.speed = 2.0
        self.rad = 5
        self.pos = [50.0,50.0]
        self.acc = 0.001

    def update(self):
        self.pos[0] += math.sin(self.angle * math.pi / 180.0) * self.speed
        self.pos[1] -= math.cos(self.angle * math.pi / 180.0) * self.speed
        self.rect.x = int(self.pos[0])
        self.rect.y = int(self.pos[1])
        self.speed += self.acc


"""
==================================================
Andrés Felipe García Albarracín
2021-07-02
==================================================

Loads data from TFDS, builds a Text Vectorization layer
and a model for classification
"""

"""
==================================================
1. Load libraries
==================================================
"""
import tensorflow as tf
import tensorflow_datasets as tfds
import tensorflow_hub as hub
import time, os

batch_size = 64
embedding_dim = 50 # 50 or 128
"""
==================================================
2. Load data
==================================================
"""
dsTrain, dsEval = tfds.load('imdb_reviews', as_supervised=True, split=['train', 'test'], batch_size=batch_size)

"""
==================================================
3. Callbacks
==================================================
"""
class MyCallback(tf.keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs={}):
        if logs.get('accuracy') > 0.99:
            print('Accuracy achieved')
            self.model.stop_training = True

my_cb = MyCallback()

es_cb = tf.keras.callbacks.EarlyStopping(
    monitor='val_accuracy',
    restore_best_weights=True,
    patience=25
)

tb_cb = tf.keras.callbacks.TensorBoard(
    log_dir=os.path.join('99_TensorBoard_logs', time.strftime('run_NLP_70_%Y%m%d_%H%M%S'))
)

"""
==================================================
3. Model
==================================================
"""
# This Hub model tokenizes, pads, cast into an embedding and Reduces the sequence embedding
model_url = f"https://tfhub.dev/google/nnlm-en-dim{embedding_dim}/2"
emb_layer = hub.KerasLayer(model_url, trainable=True, input_shape=[], dtype=tf.string)

model = tf.keras.Sequential([
    emb_layer,
    tf.keras.layers.Dropout(0.4),
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.Dropout(0.4),
    tf.keras.layers.Dense(1, activation='sigmoid')
])

model.compile(
    loss='binary_crossentropy',
    metrics=['accuracy'],
    optimizer='adam'
)

model.fit(
    dsTrain,
    validation_data=dsEval,
    epochs=100,
    callbacks=[es_cb, my_cb, tb_cb]
)


import pygame
from game_data import *
from sprite import SpriteSheet
from game_data import *

class Enemy(pygame.sprite.Sprite):
    def __init__(self, pos, size = tile_size, type = "ball", change_x = 0, change_y = 0, period = 1):
        super().__init__()
        self.frameIndex = 0
        self.animationSpeed = 0.15
        self.type = type
        self.pos = pos
        self.size = size
        self.animations = []

        self.period = period
        self.change_x = change_x
        self.change_y = change_y
        self.frames = 0

        self.setupEnemy()

    def setupEnemy(self):
        if self.type == "ball":
            self.image = pygame.image.load('./midia/ball.png').convert_alpha()
            self.image = pygame.transform.scale(self.image, (self.size, self.size))

            self.rect = self.image.get_rect(topleft = self.pos)
            self.collideRect = pygame.Rect(self.rect.x + 13, self.rect.y + 17, self.rect.width - 22, self.rect.height - 30)

        if self.type == "saw":
            enemySheet = SpriteSheet("./midia/saw38x38.png")

            for num in range(8):
                self.animations.append(enemySheet.get_image(num* 38, 0, 38, 38))

            self.image = self.animations[0]
            self.rect = self.image.get_rect(topleft = self.pos)
            self.collideRect = pygame.Rect(self.rect.x + 12, self.rect.y + 11, self.rect.width - 22, self.rect.height - 22)

    def animate(self):
        if len(self.animations) > 0:
            #loop over index
            self.frameIndex += self.animationSpeed

            if self.frameIndex >= len(self.animations):
                self.frameIndex = 0

            self.image = self.animations[int(self.frameIndex)]
            self.image = pygame.transform.scale(self.image, (self.size, self.size)).convert_alpha()

    def move(self):
        self.frames += 1
        if self.frames % int(self.period*FPS) == 0:
            if self.type == "saw":
                self.change_x *= -1
                self.change_y *= -1
        self.rect.x += self.change_x
        self.rect.y += self.change_y
        self.collideRect.x += self.change_x
        self.collideRect.y += self.change_y

    def update(self, dx):
        self.animate()
        self.move()
        self.rect.x += dx
        self.collideRect.x += dx


import plotly.offline as py
import plotly.graph_objs as go

# Create random data with numpy
Y = []

file = open('EnVStime.txt', 'r')
# file.readline()
# file.readline()
X = [int(i) for i in range(1, 7000)]
i = 0
for line in file:
    row = line.split()
    Y.append(row[0])
file.close()
# Create a trace
trace = go.Scattergl(
x = X,
y = Y,
mode = 'lines+markers',
marker = dict(size = 3)

)

data = [trace]

py.plot(data, filename='EnVStime')


#!/usr/bin/python3
"""Function that creates an Object from a json file"""
import json

def load_from_json_file(filename):
    """Creates an object from a json file
    Args:
        filename (str): name of the json file
    Returns:
        Python Object
    """
    Object = None
    with open(filename, 'r', encoding='utf-8') as f:
        Object = json.load(f)
    return Object


#!/usr/bin/env python3
"""
Base Model Class of Models Module
"""

import json
from application import models
from uuid import uuid4, UUID
from datetime import datetime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Float, DateTime

Base = declarative_base()

class BaseModel:
    """
    The base model for our database models
    """

    id = Column(String(60), nullable=False, primary_key=True)
    created_at = Column(DateTime, nullable=False,
                        default=datetime.utcnow())
    updated_at = Column(DateTime, nullable=False,
                        default=datetime.utcnow())

    def __init__(self, *args, **kwargs):
        """
        initialize new BaseModel Class
        """
        if kwargs:
            self.__set_attributes(kwargs)
        else:
            self.id = str(uuid4())
            self.created_at = datetime.utcnow()

    def __set_attributes(self, attr_dict):
        """
        private: converts attr_dict values to python class attributes
        """
        if 'id' not in attr_dict:
            attr_dict['id'] = str(uuid4())
        if 'created_at' not in attr_dict:
            attr_dict['created_at'] = datetime.utcnow()
        elif not isinstance(attr_dict['created_at'], datetime):
            attr_dict['created_at'] = datetime.strptime(
                attr_dict['created_at'], "%Y-%m-%d %H:%M:%S.%f"
            )
        if 'updated_at' not in attr_dict:
            attr_dict['updated_at'] = datetime.utcnow()
        elif not isinstance(attr_dict['updated_at'], datetime):
            attr_dict['updated_at'] = datetime.strptime(
                attr_dict['updated_at'], "%Y-%m-%d %H:%M:%S.%f"
            )
        for attr, val in attr_dict.items():
            setattr(self, attr, val)

    @staticmethod
    def __is_serializable(obj_v):
        """
        private: checks if object is serializable
        """
        try:
            obj_to_str = json.dumps(obj_v)
            return obj_to_str is not None and isinstance(obj_to_str, str)
        except:
            return False

    def bm_update(self, attr_dict=None):
        """
        updates the basemodel and sets updated attributes
        """
        ignore = [
            'id', 'created_at', 'updated_at', 'user_id'
        ]
        if attr_dict:
            updated_dict = {
                k: v for k, v in attr_dict.items() if k not in ignore
            }
            for key, value in updated_dict.items():
                setattr(self, key, value)
            self.save()

    def save(self):
        """
        updates attribute updated_at to current time and saves class to database
        """
        self.updated_at = datetime.utcnow()
        models.database.new(self)
        models.database.save()

    def to_json(self, saving_file_storage=False):
        """
        Creates dictionary of class with sqlalchemy instance state removed
        :param saving_file_storage:
        :return:
        The dictionary of our class with relevant values
        """
        obj_class = self.__class__.__name__
        bm_dict = {
            k: v if self.__is_serializable(v) else str(v)
            for k, v in self.__dict__.items()
        }
        bm_dict.pop('_sa_instance_state', None)
        bm_dict.update({
            '__class__': obj_class
            })
        if not saving_file_storage and obj_class == 'User':
            bm_dict.pop('password', None)
        return bm_dict

    def __str__(self):
        """
        str magic method
        :return:
        formatted string representation of class
        """
        class_name = type(self).__name__
        return '[{}] ({}) {}'.format(class_name, self.id, self.__dict__)

    def delete(self):
        """
        deletes instance from storage
        """
        models.database.delete(self)


import pyttsx3
from gtts import gTTS
import urllib3

engine = pyttsx3.init() # object creation

""" RATE"""
rate = engine.getProperty('rate')   # getting details of current speaking rate
print (rate)                        #printing current voice rate
engine.setProperty('rate', 125)     # setting up new voice rate

"""VOLUME"""
volume = engine.getProperty('volume')   #getting to know current volume level (min=0 and max=1)
print (volume)                          #printing current volume level
engine.setProperty('volume',1.0)    # setting up volume level  between 0 and 1

"""VOICE"""
voices = engine.getProperty('voices')       #getting details of current voice
#engine.setProperty('voice', voices[0].id)  #changing index, changes voices. o for male
engine.setProperty('voice', voices[1].id)   #changing index, changes voices. 1 for female

#engine.say("Hello World!")
#engine.say('My current speaking rate is ' + str(rate))

#engine.say("olá")
#engine.runAndWait()
#engine.stop()

def format(text):
    text = text.replace("\n", "")
    text = text.replace(" ", "")
    text = text[:10]
    text = "audio_" + text + ".wav"
    return text

text = ('''
    Sua ligação será transferida para um consultor de serviço. Para a sua segurança a ligação será gravada.
        ''')

tts = gTTS(text=text, lang='pt')
tts.save(format(text))
print("File saved!")