import numpy as np
import pandas as pd
import torch
import pickle
import random
import re
from tqdm import tqdm
from transformers.modeling_utils import PoolerAnswerClass

data_path={
    'mfc': '/data/news/mfc/',
    'gvfc': '/data/news/GVFC/GVFC/GVFC_headlines_and_annotations.xlsx',
    'twitter': '/data/tweet/twitter/',
    'immi': '/data/tweet/immi/',
    'fora': '/data/debate/issue_framing/data/dialogue/'
}

all_issue_map={
    'climate':0,
    'deathpenalty':1,
    'guncontrol':2,
    'immigration':3,
    'samesex':4,
    'tobacco':5,
    'aca':6,
    'abort':7,
    'immig':3,
    'isis':8,
    'guns':2,
    'lgbt':4

}

def save_obj(obj, name):
    with open('obj' + name + '.pkl', 'wb+') as f:
        pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)

def load_obj(name,path=None):
    if path is None:
        with open('obj' + name + '.pkl', 'rb') as f:
            return pickle.load(f)
    else:
        with open(path+'obj' + name + '.pkl', 'rb') as f:
            return pickle.load(f)

def clean(text):
    pattern1='(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]'
    pattern2='@([^@ ]*)'
    pattern3='pic.twitter.com/.*'
    text=re.sub(pattern1,' [URL]',text)
    text=re.sub(pattern2,' [MENTION]',text)
    text=re.sub(pattern3,' [PIC]',text)
    text=re.sub('\xa0','',text)
    return text

def split_data(data, issue_prepare=False):
    n=len(data['text'])
    idx=list(range(n))
    random.shuffle(idx)
    if issue_prepare:
        train,dev,test={"text": [], "label": [],'issue':[]},{"text": [], "label": [],'issue':[]},{"text": [], "label": [],'issue':[]}
    else:
        train,dev,test={"text": [], "label": []},{"text": [], "label": []},{"text": [], "label": []}
    for i in idx[:int(0.7*n)]:
        train['text'].append(data['text'][i])
        train['label'].append(data['label'][i])
        if issue_prepare:
            train['issue'].append(data['issue'][i])
    for i in idx[int(0.7*n):int(0.9*n)]:
        dev['text'].append(data['text'][i])
        dev['label'].append(data['label'][i])
        if issue_prepare:
            dev['issue'].append(data['issue'][i])
    for i in idx[int(0.9*n):]:
        test['text'].append(data['text'][i])
        test['label'].append(data['label'][i])
        if issue_prepare:
            test['issue'].append(data['issue'][i])
    return train,dev,test

def split_data_for_fewshot(data, num_class, shot=1):
    n=len(data['text'])
    idx=list(range(n))
    random.shuffle(idx)
    train,dev,test={"text": [], "label": []},{"text": [], "label": []},{"text": [], "label": []}
    label_set=list(range(num_class))
    used=[]

    label_dict={l:[] for l in label_set}
    for i in idx:
        for j in range(num_class):
            if data['label'][i][0][j]==1:
                label_dict[j].append(i)
    print({k:len(label_dict[k]) for k in label_dict})
    for l in label_dict:
        if len(label_dict[l])>shot:
            k,j=0,0
            while k<shot:
                if j<len(label_dict[l]) and label_dict[l][j] not in used:
                    train['text'].append(data['text'][label_dict[l][j]])
                    train['label'].append(data['label'][label_dict[l][j]])
                    used.append(label_dict[l][j])
                    k+=1
                    j+=1
                else:
                    j+=1
                    if j>len(label_dict[l]):break
        else:
            for j in range(len(label_dict[l])):
                if label_dict[l][j] not in used:
                    train['text'].append(data['text'][label_dict[l][j]])
                    train['label'].append(data['label'][label_dict[l][j]])
                    used.append(label_dict[l][j])
        if len(label_dict[l])>2*shot:
            k,j=0,0
            while k<shot:
                if j<len(label_dict[l]) and label_dict[l][j] not in used:
                    dev['text'].append(data['text'][label_dict[l][j]])
                    dev['label'].append(data['label'][label_dict[l][j]])
                    used.append(label_dict[l][j])
                    k+=1
                    j+=1
                else:
                    j+=1
                    if j>len(label_dict[l]):break
        else:
            for j in range(len(label_dict[l])):
                if label_dict[l][j] not in used:
                    dev['text'].append(data['text'][label_dict[l][j]])
                    dev['label'].append(data['label'][label_dict[l][j]])
                    used.append(label_dict[l][j])
    return train,dev

def read_mfc_issue(path='/remote-home/xymou/Frame/framework/data/news/mfc/', data_type='article', issue='climate'):
    if data_type=='article':
        data=load_obj('article_data_multi',path)
    elif data_type=='sentence':
        data=load_obj('sentence_data_multi',path)
    else:
        raise Exception('Undefined data type! Choose from [article, sentence]')
    return data[issue]

def read_mfc(path='/remote-home/xymou/Frame/framework/data/news/mfc/', data_type='article', issue='all',issue_prepare=False):
    print('Reading data from MFC dataset!')
    if issue!='all':
        issues= [issue]
    else:
        issues= ['climate', 'deathpenalty', 'guncontrol', 'immigration', 'samesex', 'tobacco']
    if issue_prepare:
        data = {'text':[], 'label':[], 'issue':[]}
    else:
        data = {'text':[], 'label':[]}
    for i in issues:
        tmp = read_mfc_issue(path, data_type, issue=i)
        data['text'].extend(tmp['text'])
        data['label'].extend(tmp['label'])
        if issue_prepare:
            data['issue'].extend([all_issue_map[i]]*len(tmp['label']))
    return data

def read_gvfc(path='/remote-home/xymou/Frame/framework/data/news/GVFC/GVFC/GVFC_headlines_and_annotations.xlsx'):
    print('Reading data from GVFC dataset!')
    df=pd.read_excel(path)
    data,label=[],[]
    for i in tqdm(range(len(df))):
        text=df.loc[i,'news_title']
        if df.loc[i,'Q1 Relevant']==1 and df.loc[i,'Q3 Theme1']!=99:
            data.append(text.lower())
            tmp=[df.loc[i,'Q3 Theme1']-1]
            if df.loc[i,'Q3 Theme2']!=99:
                tmp.append(df.loc[i,'Q3 Theme2']-1)
            label.append(tmp)
    return {"text": data, "label": label}

def read_twitter_issue(path='/remote-home/xymou/Frame/sample_test/Weakly/', issue='aca'):
    tweet_processed=load_obj('tweet_processed', path)
    label_map={
        0:0,1:1,2:2,3:3,4:4,5:6,6:7,7:8,8:9,9:10,10:11,11:12,12:5,13:13
    }
    text,label=[],[]
    for key in tweet_processed:
        if issue in tweet_processed[key]['issue']:
            tmp=tweet_processed[key]['text']
            tmp=clean(tmp.lower())
            tmp=re.sub('\#','',tmp)
            res = [label_map[k-1] for k in tweet_processed[key]['frame'] if k not in [15,16,17]]
            if len(res):
                label.append(res)
                text.append(tmp)
    return {'text':text,'label':label}

def read_twitter(path='/remote-home/xymou/Frame/sample_test/Weakly/', issue='all', issue_prepare = True):
    print('Reading data from Twitter-framing dataset!')
    if issue == 'all':
        issues=['aca','abort','immig','isis','guns','lgbt']
    else:
        issues = [issue]
    if issue_prepare:
        data = {'text':[], 'label':[], 'issue':[]}
    else:
        data = {'text':[], 'label':[]}
    for i in issues:
        tmp = read_twitter_issue(path,  i)
        for j in range(len(tmp['label'])):
            data['text'].append(tmp['text'][j])
            data['label'].append(tmp['label'][j])
            if issue_prepare:
                data['issue'].append(all_issue_map[i])
    return data

def read_immi(path='/remote-home/xymou/Frame/framework/data/tweet/immi/' , issue='issue_specific', issue_prepare=False): #这里的issue其实是ftype
    print('Reading data from immigration twitter dataset!')
    text, label = [],[]
    data = load_obj(issue, path)
    if issue=='issue_generic':
        labels = ['Cultural Identity','Capacity and Resources','Security and Defense','Quality of Life',
    'Crime and Punishment','Policy Prescription and Evaluation','Morality and Ethics','External Regulation and Reputation','Health and Safety',
    'Political Factors and Implications','Public Sentiment','Economic','Fairness and Equality','Legality, Constitutionality, Jurisdiction'    ]
    else:
        labels = ['Victim: Global Economy','Threat: Fiscal', 'Hero: Cultural Diversity', 'Threat: Public Order', 'Threat: Jobs',
    'Victim: Humanitarian', 'Threat: National Cohesion','Hero: Integration','Victim: Discrimination','Victim: War','Hero: Worker']
    label_map={l:labels.index(l) for l in labels}
    for i in range(len(data['text'])):
        text.append(clean(data['text'][i].lower()))
        label.append([label_map[k] for k in data['label'][i]])
    if issue == 'issue_generic' and issue_prepare:
        return {'text':text, 'label':label, 'issue':[all_issue_map['immigration']]*len(label)}
    return {'text':text,'label':label}

def read_fora(path='/remote-home/xymou/Frame/framework/data/debate/issue_framing/data/dialogue/'):
    print('Reading data from Fora dataset!')
    text, label=[],[]
    data = load_obj('fora_data',path)
    for i in range(len(data['label'])):
        text.append(data['text'][i])
        label.append(data['label'][i])
    return {'text':text, 'label':label}

data_func_map={
    'mfc':read_mfc,
    'gvfc':read_gvfc,
    'twitter':read_twitter,
    'immi':read_immi,
    'fora':read_fora

}
def read_data(config):
    dataset = config['dataset']
    if dataset not in data_func_map:
        raise KeyError('Current dataset is not mapped to data_read function! Please define the read data function for this dataset!')
    func = data_func_map[dataset]
    config.pop('dataset')
    if dataset != 'mfc':
        config.pop('data_type')
    if dataset in ['gvfc','fora']:
        config.pop('issue')
    config['path'] = data_path[dataset]
    return func(**config)

def convert_to_one_hot(label, label_num):
    print('# of labels:', label_num)
    res= []
    for l in label:
        tmp=[0]*label_num
        for i in range(len(l)):
            tmp[l[i]]=1
        res.append(torch.tensor(tmp, dtype=torch.float32).view(1,-1))
    return res

from torch.utils.data import Dataset
class mydata(Dataset):
    def __init__(self, data, tokenizer, padding_idx=0, max_len=None):
        self.text_lengths=[len(seq) for seq in data['text']]
        self.max_len=max_len
        if self.max_len is None:
            self.max_len=max(self.text_lengths)
        self.num_sequences = len(data["text"])
        self.data=data
        for i in range(len(data['text'])):
            data['text'][i] = tokenizer.encode(data['text'][i], max_length=self.max_len)
    def __len__(self):
        return self.num_sequences

    def __getitem__(self, index):
        return {"text":self.data['text'][index],
                 "label":self.data['label'][index],
                 "issue":self.data['issue'][index]}


from django.shortcuts import render
from rest_framework import generics
from rest_framework.permissions import IsAuthenticated

from order.models import Order
from order.serializers.order import OrderSerializer

class OrderView(generics.ListCreateAPIView):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        user = self.request.user
        queryset = Order.objects.filter(created_by=user)
        return queryset

class OrderDetails(generics.RetrieveUpdateAPIView):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        user = self.request.user
        queryset = Order.objects.filter(created_by=user)
        return queryset

def orders(request):
    orders = Order.objects.filter(created_by=request.user)
    print(orders)
    return render(request, "home/orders.html", {"orders": orders})


# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""
import numpy as np

import keras
from keras.models import Model
from keras.layers import Dense,Activation,Input
from keras.callbacks import ModelCheckpoint

X = np.random.normal(0,1,(100,8))
Y = np.random.normal(0,1,(100,1))
X.shape

batch = 32
valX,valY = np.random.normal(0,1,(100,8)),np.random.normal(0,1,(100,1))
class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.losses = []
        self.val_loss=[]
        self.weights= []

    def on_epoch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))
        self.val_loss.append(logs.get('val_loss'))
        self.weights.append(self.model.get_weights())
        name = 'weights'+'_'+str(batch)+'.h5'
        self.model.save_weights(name)

def keras_models(X,Y,kernel_init = 'random_uniform',output_activation = 'tanh',input_activation = 'relu',
                validation_data = [valX,valY]):
    losses = LossHistory()
    ip = Input(batch_shape=(batch,X.shape[1]))
    layer1 = Dense(32, kernel_initializer=kernel_init)(ip)
    layer2 = Activation(input_activation)(layer1)
    out = Dense(Y.shape[1],activation = output_activation)(layer2)
    model = Model(inputs = ip,output = out)
    model.compile(optimizer='adam',loss = 'mean_squared_error')
    filepath="weights-improvement-{epoch:02d}-{val_acc:.2f}.hdf5"
    checkpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=True)
    callbacks_list = [losses]#,checkpoint]
    model.fit(X,Y,validation_data=validation_data,batch_size=batch,epochs=100,callbacks=callbacks_list,verbose=1)
    return model,losses

model = keras_models(X,Y,kernel_init = 'random_uniform',output_activation = 'tanh',input_activation = 'relu',
                validation_data = [valX,valY])


import pygame
import math
from global_timer import TimedObject
class BossDeathCutscene(TimedObject):
    def __init__(self, map_center_pos, boss) -> None:
        self.lifetime = 999990
        self.map_center_pos = map_center_pos
        self.boss = boss
        self.boss.global_timer.attach(self)
        self.boss.in_active_spell_action = True
        self.boss.defeated = True
        self.boss_in_map_center = False
        self.emotion_was_sayed = False
        self.emotion_was_sayed2 = False
        #---------
        self.wave_points = []
        self.wave_segment_size = 3

    def timer_tick(self):
        self.boss.in_active_spell_action = True

        if self.boss_in_map_center == True:
            self.lifetime -= 1
            if self.lifetime <= 40:
                self.boss.center_pos = [9999,9999]
                font = pygame.font.SysFont('arial', 40)
                score = font.render("You win!", True, (255, 255, 255))
                self.boss.surface.blit(score, (300, 200))
                self.boss.snake.food.hide()
            if self.lifetime <= 15:
                if self.emotion_was_sayed2 == False:
                    self.emotion_was_sayed2 = True
                    self.boss.aniki.play()
                self.boss.center_pos = [9999,9999]
                font = pygame.font.SysFont('arial', 20)
                score = font.render("Thank you for your attention", True, (255, 255, 255))
                self.boss.surface.blit(score, (300, 260))
                #--------
                self.boss.center_pos = [9999,9999]
                font = pygame.font.SysFont('arial', 20)
                score = font.render("created by Jordenskraften", True, (255, 255, 255))
                self.boss.surface.blit(score, (300, 290))
            else:
                if self.lifetime %3 == 0:
                    self.boss.color = (255,0,0)
                else:
                    self.boss.color = (125,0,0)
            #взрываем её
        else:
            #если босс дошел до центра
            if (
                abs(self.boss.center_pos[0] - self.map_center_pos[0]) <= 1 and
                abs(self.boss.center_pos[1] - self.map_center_pos[1]) <= 1
            ):
                self.boss_in_map_center = True
                self.lifetime = 110
                if self.emotion_was_sayed == False:
                    self.emotion_was_sayed = True
                    self.boss.boss_death.play()
                    self.boss.create_floating_text("Okay, you got me!", True)
                    self.boss.snake.food.hide()
                #print("boss in center")
            else:
                #тута двигаем босса к центру
                d_x = self.map_center_pos[0] - self.boss.center_pos[0]
                d_y = self.map_center_pos[1] - self.boss.center_pos[1]
                distance = math.sqrt(d_x**2 + d_y**2)
                step_x = d_x / distance * 1.5
                step_y = d_y / distance * 1.5
                dir = (step_x,step_y)
                self.boss.center_pos = [
                            self.boss.center_pos[0] + dir[0],
                            self.boss.center_pos[1] + dir[1]
                            ]
                self.boss.snake.food.hide()
        if len(self.wave_points) >= 1:
            for p in self.wave_points:
                self.move_wave_segment(p)
                self.draw_wave_segment(p)
                self.check_for_snakes_bodies_collision(p)

    def enter():
        pass

    def death(self):
        self.boss.global_timer.detach(self)
        self.boss.in_active_spell_action = True
        self.boss.defeated = True
        self.boss.base_abilities_cd = 999999
        self.boss.active_abilities_cd = 999999
        self.boss.boss_ultimate_ability_cd = 999999
        self.boss.minions_cd = 999999
        del(self)


import zedlib
import pygame
import math

class GameSprite:
    def __init__(self, image, x, y):
        self.image = image
        self.rect = self.image.get_rect()
        self.position = zedlib.Position(x, y)
        self.x_acceleration = 0.0
        self.y_acceleration = 0.0
        self.x_velocity = 0.0
        self.y_velocity = 0.0
        self.max_y_velocity = None
        self.max_x_velocity = None
        self.move_x = 0.0
        self.move_y = 0.0

        self.update_rect_x()
        self.update_rect_y()

    def draw(self, surface, camera = None):
        """ Draw image on a given surface, a zedlib.Camera can also be used """
        if camera:
            surface.blit(self.image, camera.apply(self.rect))
        else:
            surface.blit(self.image, self.rect)

    def update_rect_x(self):
        """ Update x position of the rect, from self.position """
        self.rect.x = self.position.get_position()[0]

    def update_rect_y(self):
        """ Update y position of the rect, from self.position """
        self.rect.y = self.position.get_position()[1]

    def update_movement(self, collisions=[]):
        """ Update the position of rect and handle collisions """
        self.apply_acceleration()

        if self.move_x and self.move_y:
            movement = self.get_diagonal_movement(math.fabs(self.move_x))
            self.move_x = math.copysign(movement[0], self.move_x)
            self.move_y = math.copysign(movement[1], self.move_y)

        self.move_x += self.x_velocity
        self.position.move_x(self.move_x)
        self.handle_horizonal_collisions(collisions)
        self.move_x = 0.0

        self.move_y += self.y_velocity
        self.position.move_y(self.move_y)
        self.handle_vertical_collisions(collisions)
        self.move_y = 0.0

    def apply_acceleration(self):
        self.x_velocity += self.x_acceleration
        self.y_velocity += self.y_acceleration
        if self.max_x_velocity:
            if self.x_velocity > self.max_x_velocity:
                self.x_velocity = self.max_x_velocity
        if self.max_y_velocity:
            if self.y_velocity > self.max_y_velocity:
                self.y_velocity = self.max_y_velocity

    def handle_horizonal_collisions(self, collisions):
        """ Stop rect from moving through collisions horizontally """
        self.update_rect_x()
        collision_objects = pygame.sprite.spritecollide(self, collisions, False)
        for collision_obj in collision_objects:
            collision_obj.horizontal_collide(self)
            self.position.set_x(self.rect.x)
        if collision_objects: self.collision_occured()

    def handle_vertical_collisions(self, collisions):
        """ Stop rect from moving through collisions vertically """
        self.update_rect_y()
        collision_objects = pygame.sprite.spritecollide(self, collisions, False)
        for collision_obj in collision_objects:
            collision_obj.vertical_collide(self)
            self.position.set_y(self.rect.y)
        if collision_objects: self.collision_occured()

    def collision_occured(self):
        """ Called when sprite has collided with an object """
        pass

    def get_diagonal_movement(self, speed):
        """ Reduce diagonal movement to be equal to normal movement speed """
        move_speed = math.sqrt( (speed*speed)/2.0 )
        return (move_speed, move_speed)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/3/21 0021
# @Author  : justin.郑 3907721@qq.com
# @File    : covid.py
# @Desc    : 获取疫情数据

import json
import time
import demjson
import jsonpath
import requests
import pandas as pd
from io import BytesIO
from PIL import Image
from bs4 import BeautifulSoup

def covid_163(indicator="实时"):
    """
    网易-新冠状病毒
    https://news.163.com/special/epidemic/?spssid=93326430940df93a37229666dfbc4b96&spsw=4&spss=other&#map_block
    https://news.163.com/special/epidemic/?spssid=93326430940df93a37229666dfbc4b96&spsw=4&spss=other&
    :return: 返回指定 indicator 的数据
    :rtype: pandas.DataFrame
    """
    url = "https://c.m.163.com/ug/api/wuhan/app/data/list-total"
    headers = {
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36",
    }
    payload = {
        "t": int(time.time() * 1000),
    }
    r = requests.get(url, params=payload, headers=headers)
    data_json = r.json()
    # data info
    url = "https://news.163.com/special/epidemic/"
    r = requests.get(url, headers=headers)
    soup = BeautifulSoup(r.text, "lxml")
    data_info_df = pd.DataFrame(
        [
            item.text.strip().split(".")[1]
            for item in soup.find("div", attrs={"class": "data_tip_pop_text"}).find_all(
                "p"
            )
        ]
    )
    data_info_df.columns = ["info"]

    # 中国历史时点数据
    hist_today_df = pd.DataFrame(
        [item["today"] for item in data_json["data"]["chinaDayList"]],
        index=[item["date"] for item in data_json["data"]["chinaDayList"]],
    )

    # 中国历史累计数据
    hist_total_df = pd.DataFrame(
        [item["total"] for item in data_json["data"]["chinaDayList"]],
        index=[item["date"] for item in data_json["data"]["chinaDayList"]],
    )

    # 中国实时数据
    current_df = pd.DataFrame.from_dict(data_json["data"]["chinaTotal"])

    # 世界历史时点数据
    outside_today_df = pd.DataFrame(
        [item["today"] for item in data_json["data"]["areaTree"]],
        index=[item["name"] for item in data_json["data"]["areaTree"]],
    )

    # 世界历史累计数据
    outside_total_df = pd.DataFrame(
        [item["total"] for item in data_json["data"]["areaTree"]],
        index=[item["name"] for item in data_json["data"]["areaTree"]],
    )

    # 全球所有国家及地区时点数据
    all_world_today_df = pd.DataFrame(
        jsonpath.jsonpath(data_json["data"]["areaTree"], "$..today"),
        index=jsonpath.jsonpath(data_json["data"]["areaTree"], "$..name"),
    )

    # 全球所有国家及地区累计数据
    all_world_total_df = pd.DataFrame(
        jsonpath.jsonpath(data_json["data"]["areaTree"], "$..total"),
        index=jsonpath.jsonpath(data_json["data"]["areaTree"], "$..name"),
    )

    # 中国各地区时点数据
    area_total_df = pd.DataFrame(
        [item["total"] for item in data_json["data"]["areaTree"][0]["children"]],
        index=[item["name"] for item in data_json["data"]["areaTree"][0]["children"]],
    )

    # 中国各地区累计数据
    area_today_df = pd.DataFrame(
        [item["today"] for item in data_json["data"]["areaTree"][0]["children"]],
        index=[item["name"] for item in data_json["data"]["areaTree"][0]["children"]],
    )

    # 疫情学术进展
    url_article = "https://vip.open.163.com/api/cms/topic/list"
    payload_article = {
        "topicid": "00019NGQ",
        "listnum": "1000",
        "liststart": "0",
        "pointstart": "0",
        "pointend": "255",
        "useproperty": "true",
    }
    r_article = requests.get(url_article, params=payload_article)
    article_df = pd.DataFrame(r_article.json()["data"]).iloc[:, 1:]

    # 咨询
    url_info = "https://ent.163.com/special/00035080/virus_report_data.js"
    payload_info = {
        "_": int(time.time() * 1000),
        "callback": "callback",
    }
    r_info = requests.get(url_info, params=payload_info, headers=headers)
    data_info_text = r_info.text
    data_info_json = demjson.decode(data_info_text.strip(" callback(")[:-1])

    if indicator == "数据说明":
        print(f"数据更新时间: {data_json['data']['lastUpdateTime']}")
        return data_info_df

    if indicator == "中国实时数据":
        print(f"数据更新时间: {data_json['data']['lastUpdateTime']}")
        return current_df

    if indicator == "中国历史时点数据":
        print(f"数据更新时间: {data_json['data']['lastUpdateTime']}")
        return hist_today_df

    if indicator == "中国历史累计数据":
        print(f"数据更新时间: {data_json['data']['lastUpdateTime']}")
        return hist_total_df

    if indicator == "世界历史时点数据":
        print(f"数据更新时间: {data_json['data']['lastUpdateTime']}")
        return outside_today_df

    if indicator == "世界历史累计数据":
        print(f"数据更新时间: {data_json['data']['lastUpdateTime']}")
        return outside_total_df

    if indicator == "全球所有国家及地区时点数据":
        print(f"数据更新时间: {data_json['data']['lastUpdateTime']}")
        return all_world_today_df

    elif indicator == "全球所有国家及地区累计数据":
        print(f"数据更新时间: {data_json['data']['lastUpdateTime']}")
        return all_world_total_df

    elif indicator == "中国各地区时点数据":
        print(f"数据更新时间: {data_json['data']['lastUpdateTime']}")
        return area_today_df

    elif indicator == "中国各地区累计数据":
        print(f"数据更新时间: {data_json['data']['lastUpdateTime']}")
        return area_total_df

    elif indicator == "疫情学术进展":
        return article_df

    elif indicator == "实时资讯新闻播报":
        return pd.DataFrame(data_info_json["list"])

    elif indicator == "实时医院新闻播报":
        return pd.DataFrame(data_info_json["hospital"])

    elif indicator == "前沿知识":
        return pd.DataFrame(data_info_json["papers"])

    elif indicator == "权威发布":
        return pd.DataFrame(data_info_json["power"])

    elif indicator == "滚动新闻":
        return pd.DataFrame(data_info_json["scrollNews"])

def covid_dxy(indicator="湖北"):
    """
    20200315-丁香园接口更新分为国内和国外
    丁香园-全国统计-info
    丁香园-分地区统计-data
    丁香园-全国发热门诊一览表-hospital
    丁香园-全国新闻-news
    :param indicator: ["info", "data", "hospital", "news"]
    :type indicator: str
    :return: 返回指定 indicator 的数据
    :rtype: pandas.DataFrame
    """
    url = "https://3g.dxy.cn/newh5/view/pneumonia"
    r = requests.get(url)
    r.encoding = "utf-8"
    soup = BeautifulSoup(r.text, "lxml")
    # news-china
    text_data_news = str(
        soup.find_all("script", attrs={"id": "getTimelineServiceundefined"})
    )
    temp_json = text_data_news[
        text_data_news.find("= [{") + 2 : text_data_news.rfind("}catch")
    ]
    if temp_json:
        json_data = pd.DataFrame(json.loads(temp_json))
        chinese_news = json_data[
            ["title", "summary", "infoSource", "provinceName", "sourceUrl"]
        ]

    # news-foreign
    text_data_news = str(soup.find_all("script", attrs={"id": "getTimelineService2"}))
    temp_json = text_data_news[
        text_data_news.find("= [{") + 2 : text_data_news.rfind("}catch")
    ]
    json_data = pd.DataFrame(json.loads(temp_json))
    foreign_news = json_data

    # data-domestic
    data_text = str(soup.find("script", attrs={"id": "getAreaStat"}))
    data_text_json = json.loads(
        data_text[data_text.find("= [{") + 2 : data_text.rfind("catch") - 1]
    )
    big_df = pd.DataFrame()
    for i, p in enumerate(jsonpath.jsonpath(data_text_json, "$..provinceName")):
        temp_df = pd.DataFrame(jsonpath.jsonpath(data_text_json, "$..cities")[i])
        temp_df["province"] = p
        big_df = big_df.append(temp_df, ignore_index=True)
    domestic_city_df = big_df

    data_df = pd.DataFrame(data_text_json).iloc[:, :7]
    data_df.columns = ["地区", "地区简称", "现存确诊", "累计确诊", "-", "治愈", "死亡"]
    domestic_province_df = data_df[["地区", "地区简称", "现存确诊", "累计确诊", "治愈", "死亡"]]
    # data-global
    data_text = str(
        soup.find("script", attrs={"id": "getListByCountryTypeService2true"})
    )
    data_text_json = json.loads(
        data_text[data_text.find("= [{") + 2: data_text.rfind("catch") - 1]
    )
    global_df = pd.DataFrame(data_text_json)

    # info
    dxy_static = soup.find(attrs={"id": "getStatisticsService"}).get_text()
    data_json = json.loads(
        dxy_static[dxy_static.find("= {") + 2 : dxy_static.rfind("}c")]
    )
    china_statistics = pd.DataFrame(
        [
            time.strftime(
                "%Y-%m-%d %H:%M:%S", time.localtime(data_json["modifyTime"] / 1000)
            ),
            data_json["currentConfirmedCount"],
            data_json["confirmedCount"],
            data_json["suspectedCount"],
            data_json["curedCount"],
            data_json["deadCount"],
            data_json["seriousCount"],
            data_json["suspectedIncr"],
            data_json["currentConfirmedIncr"],
            data_json["confirmedIncr"],
            data_json["curedIncr"],
            data_json["deadIncr"],
            data_json["seriousIncr"],
        ],
        index=[
            "数据发布时间",
            "现存确诊",
            "累计确诊",
            "境外输入",
            "累计治愈",
            "累计死亡",
            "现存重症",
            "境外输入较昨日",
            "现存确诊较昨日",
            "累计确诊较昨日",
            "累计治愈较昨日",
            "累计死亡较昨日",
            "现存重症较昨日",
        ],
        columns=["info"],
    )
    foreign_statistics = pd.DataFrame.from_dict(
        data_json["foreignStatistics"], orient="index"
    )
    global_statistics = pd.DataFrame.from_dict(
        data_json["globalStatistics"], orient="index"
    )
    # hospital
    url = (
        "https://assets.dxycdn.com/gitrepo/tod-assets/output/default/pneumonia/index.js"
    )
    payload = {"t": str(int(time.time()))}
    r = requests.get(url, params=payload)
    hospital_df = pd.read_html(r.text)[0].iloc[:, :-1]

    if indicator == "中国疫情分省统计详情":
        return domestic_province_df
    if indicator == "中国疫情分市统计详情":
        return domestic_city_df
    elif indicator == "全球疫情分国家统计详情":
        return global_df
    elif indicator == "中国疫情实时统计":
        return china_statistics
    elif indicator == "国外疫情实时统计":
        return foreign_statistics
    elif indicator == "全球疫情实时统计":
        return global_statistics
    elif indicator == "中国疫情防控医院":
        return hospital_df
    elif indicator == "实时播报":
        return chinese_news

    elif indicator == "中国-新增疑似-新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["quanguoTrendChart"][0]["imgUrl"]).content)
        )
        img_file.show()
    elif indicator == "中国-现存确诊-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["quanguoTrendChart"][1]["imgUrl"]).content)
        )
        img_file.show()
    elif indicator == "中国-现存疑似-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["quanguoTrendChart"][2]["imgUrl"]).content)
        )
        img_file.show()
    elif indicator == "中国-治愈-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["quanguoTrendChart"][3]["imgUrl"]).content)
        )
        img_file.show()
    elif indicator == "中国-死亡-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["quanguoTrendChart"][4]["imgUrl"]).content)
        )
        img_file.show()

    elif indicator == "中国-非湖北新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["hbFeiHbTrendChart"][0]["imgUrl"]).content)
        )
        img_file.show()
    elif indicator == "中国-湖北新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["hbFeiHbTrendChart"][1]["imgUrl"]).content)
        )
        img_file.show()
    elif indicator == "中国-湖北现存确诊-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["hbFeiHbTrendChart"][2]["imgUrl"]).content)
        )
        img_file.show()
    elif indicator == "中国-非湖北现存确诊-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["hbFeiHbTrendChart"][3]["imgUrl"]).content)
        )
        img_file.show()
    elif indicator == "中国-治愈-死亡-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["hbFeiHbTrendChart"][4]["imgUrl"]).content)
        )
        img_file.show()

    elif indicator == "国外-国外新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["foreignTrendChart"][0]["imgUrl"]).content)
        )
        img_file.show()
    elif indicator == "国外-国外累计确诊-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["foreignTrendChart"][1]["imgUrl"]).content)
        )
        img_file.show()
    elif indicator == "国外-国外死亡-趋势图":
        img_file = Image.open(
            BytesIO(requests.get(data_json["foreignTrendChart"][2]["imgUrl"]).content)
        )
        img_file.show()

    elif indicator == "国外-重点国家新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(
                requests.get(
                    data_json["importantForeignTrendChart"][0]["imgUrl"]
                ).content
            )
        )
        img_file.show()
    elif indicator == "国外-日本新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(
                requests.get(
                    data_json["importantForeignTrendChart"][1]["imgUrl"]
                ).content
            )
        )
        img_file.show()
    elif indicator == "国外-意大利新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(
                requests.get(
                    data_json["importantForeignTrendChart"][2]["imgUrl"]
                ).content
            )
        )
        img_file.show()
    elif indicator == "国外-伊朗新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(
                requests.get(
                    data_json["importantForeignTrendChart"][3]["imgUrl"]
                ).content
            )
        )
        img_file.show()
    elif indicator == "国外-美国新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(
                requests.get(
                    data_json["importantForeignTrendChart"][4]["imgUrl"]
                ).content
            )
        )
        img_file.show()
    elif indicator == "国外-法国新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(
                requests.get(
                    data_json["importantForeignTrendChart"][5]["imgUrl"]
                ).content
            )
        )
        img_file.show()
    elif indicator == "国外-德国新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(
                requests.get(
                    data_json["importantForeignTrendChart"][6]["imgUrl"]
                ).content
            )
        )
        img_file.show()
    elif indicator == "国外-西班牙新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(
                requests.get(
                    data_json["importantForeignTrendChart"][7]["imgUrl"]
                ).content
            )
        )
        img_file.show()
    elif indicator == "国外-韩国新增确诊-趋势图":
        img_file = Image.open(
            BytesIO(
                requests.get(
                    data_json["importantForeignTrendChart"][8]["imgUrl"]
                ).content
            )
        )
        img_file.show()
    else:
        try:
            data_text = str(soup.find("script", attrs={"id": "getAreaStat"}))
            data_text_json = json.loads(
                data_text[data_text.find("= [{") + 2 : data_text.rfind("catch") - 1]
            )
            data_df = pd.DataFrame(data_text_json)
            sub_area = pd.DataFrame(
                data_df[data_df["provinceName"] == indicator]["cities"].values[0]
            )
            if sub_area.empty:
                return print("暂无分区域数据")
            sub_area.columns = ["区域", "现在确诊人数", "确诊人数", "疑似人数", "治愈人数", "死亡人数", "id"]
            sub_area = sub_area[["区域", "现在确诊人数", "确诊人数", "疑似人数", "治愈人数", "死亡人数"]]
            return sub_area
        except IndexError as e:
            print("请输入省/市的全称, 如: 浙江省/上海市 等")

def covid_baidu(indicator="湖北"):
    """
    百度-新型冠状病毒肺炎-疫情实时大数据报告
    https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_pc_1
    :param indicator: 看说明文档
    :type indicator: str
    :return: 指定 indicator 的数据
    :rtype: pandas.DataFrame
    """
    url = "https://huiyan.baidu.com/openapi/v1/migration/rank"
    payload = {
        "type": "move",
        "ak": "kgD2HiDnLdUhwzd3CLuG5AWNfX3fhLYe",
        "adminType": "country",
        "name": "全国",
    }
    r = requests.get(url, params=payload)
    move_in_df = pd.DataFrame(r.json()["result"]["moveInList"])
    move_out_df = pd.DataFrame(r.json()["result"]["moveOutList"])

    url = "https://opendata.baidu.com/api.php"
    payload = {
        "query": "全国",
        "resource_id": "39258",
        "tn": "wisetpl",
        "format": "json",
        "cb": "jsonp_1580470773343_11183",
    }
    r = requests.get(url, params=payload)
    text_data = r.text
    json_data_news = json.loads(
        text_data.strip("/**/jsonp_1580470773343_11183(").rstrip(");")
    )

    url = "https://opendata.baidu.com/data/inner"
    payload = {
        "tn": "reserved_all_res_tn",
        "dspName": "iphone",
        "from_sf": "1",
        "dsp": "iphone",
        "resource_id": "28565",
        "alr": "1",
        "query": "肺炎",
        "cb": "jsonp_1606895491198_93137",
    }
    r = requests.get(url, params=payload)
    json_data = json.loads(r.text[r.text.find("({") + 1 : r.text.rfind(");")])
    spot_report = pd.DataFrame(json_data["Result"][0]["DisplayData"]["result"]["items"])

    # domestic-city
    url = "https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_pc_1"
    r = requests.get(url)
    soup = BeautifulSoup(r.text, "lxml")
    data_json = demjson.decode(soup.find(attrs={"id": "captain-config"}).text)

    big_df = pd.DataFrame()
    for i, p in enumerate(
        jsonpath.jsonpath(data_json["component"][0]["caseList"], "$..area")
    ):
        temp_df = pd.DataFrame(
            jsonpath.jsonpath(data_json["component"][0]["caseList"], "$..subList")[i]
        )
        temp_df["province"] = p
        big_df = big_df.append(temp_df, ignore_index=True)
    domestic_city_df = big_df

    domestic_province_df = pd.DataFrame(data_json["component"][0]["caseList"]).iloc[
        :, :-2
    ]

    big_df = pd.DataFrame()
    for i, p in enumerate(
        jsonpath.jsonpath(data_json["component"][0]["caseOutsideList"], "$..area")
    ):
        temp_df = pd.DataFrame(
            jsonpath.jsonpath(
                data_json["component"][0]["caseOutsideList"], "$..subList"
            )[i]
        )
        temp_df["province"] = p
        big_df = big_df.append(temp_df, ignore_index=True)
    outside_city_df = big_df

    outside_country_df = pd.DataFrame(
        data_json["component"][0]["caseOutsideList"]
    ).iloc[:, :-1]

    big_df = pd.DataFrame()
    for i, p in enumerate(
        jsonpath.jsonpath(data_json["component"][0]["globalList"], "$..area")
    ):
        temp_df = pd.DataFrame(
            jsonpath.jsonpath(data_json["component"][0]["globalList"], "$..subList")[i]
        )
        temp_df["province"] = p
        big_df = big_df.append(temp_df, ignore_index=True)
    global_country_df = big_df

    global_continent_df = pd.DataFrame(data_json["component"][0]["globalList"])[
        ["area", "died", "crued", "confirmed", "confirmedRelative"]
    ]

    if indicator == "热门迁入地":
        return move_in_df
    elif indicator == "热门迁出地":
        return move_out_df
    elif indicator == "今日疫情热搜":
        return pd.DataFrame(json_data_news["data"][0]["list"][0]["item"])
    elif indicator == "防疫知识热搜":
        return pd.DataFrame(json_data_news["data"][0]["list"][1]["item"])
    elif indicator == "热搜谣言粉碎":
        return pd.DataFrame(json_data_news["data"][0]["list"][2]["item"])
    elif indicator == "复工复课热搜":
        return pd.DataFrame(json_data_news["data"][0]["list"][3]["item"])
    elif indicator == "热门人物榜":
        return pd.DataFrame(json_data_news["data"][0]["list"][4]["item"])
    elif indicator == "历史疫情热搜":
        return pd.DataFrame(json_data_news["data"][0]["list"][5]["item"])
    elif indicator == "搜索正能量榜":
        return pd.DataFrame(json_data_news["data"][0]["list"][6]["item"])
    elif indicator == "游戏榜":
        return pd.DataFrame(json_data_news["data"][0]["list"][7]["item"])
    elif indicator == "影视榜":
        return pd.DataFrame(json_data_news["data"][0]["list"][8]["item"])
    elif indicator == "小说榜":
        return pd.DataFrame(json_data_news["data"][0]["list"][9]["item"])
    elif indicator == "疫期飙升榜":
        return pd.DataFrame(json_data_news["data"][0]["list"][10]["item"])
    elif indicator == "实时播报":
        return spot_report
    elif indicator == "中国分省份详情":
        return domestic_province_df
    elif indicator == "中国分城市详情":
        return domestic_city_df
    elif indicator == "国外分国详情":
        return outside_country_df
    elif indicator == "国外分城市详情":
        return outside_city_df
    elif indicator == "全球分洲详情":
        return global_continent_df
    elif indicator == "全球分洲国家详情":
        return global_country_df

def covid_hist_city(city="武汉市"):
    """
    疫情历史数据 城市
    https://github.com/canghailan/Wuhan-2019-nCoV
    2019-12-01开始
    :return: 具体城市的疫情数据
    :rtype: pandas.DataFrame
    """
    url = "https://raw.githubusercontent.com/canghailan/Wuhan-2019-nCoV/master/Wuhan-2019-nCoV.json"
    r = requests.get(url)
    data_json = r.json()
    data_df = pd.DataFrame(data_json)
    return data_df[data_df["city"] == city]

def covid_hist_province(province="湖北省"):
    """
    疫情历史数据 省份
    https://github.com/canghailan/Wuhan-2019-nCoV
    2019-12-01开始
    :return: 具体省份的疫情数据
    :rtype: pandas.DataFrame
    """
    url = "https://raw.githubusercontent.com/canghailan/Wuhan-2019-nCoV/master/Wuhan-2019-nCoV.json"
    r = requests.get(url)
    data_json = r.json()
    data_df = pd.DataFrame(data_json)
    return data_df[data_df["province"] == province]

if __name__ == "__main__":
    # 历史数据
    # epidemic_hist_city_df = covid_hist_province()
    # print(epidemic_hist_city_df)
    # epidemic_hist_province_df = covid_hist_province(province="湖北省")
    # print(epidemic_hist_province_df)

    covid_dxy_df = covid_163()
    print(covid_dxy_df)


# https://randerson112358.medium.com/email-spam-detection-using-python-machine-learning-abe38c889855
# https://blog.textedly.com/spam-text-message-examples

#Import libraries

import numpy as numpy
import pandas as panda
import nltk
from nltk.corpus import stopwords
import string

#Load the data

# dataFrame = panda.read_csv('db/emails.csv')
dataFrame = panda.read_csv('db/test.csv')
# print(dataFrame.head(5))

#Print the shape (Get the number of rows and cols)
result = dataFrame.shape
# print (result)
#Get the column names
dataFrame.columns

# print(dataFrame.columns)

#Checking for duplicates and removing them
dataFrame.drop_duplicates(inplace=True)
# result = dataFrame.shape
# print (result)

#Show the number of missing (NAN, NaN, na) data for each column
result = dataFrame.isnull().sum()
# print (result)

#Need to download stopwords
# nltk.download('stopwords')

# Tokenization (a list of tokens), will be used as the analyzer
# 1.Punctuations are [!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]
# 2.Stop words in natural language processing, are useless words (data).
def process_text(text):
    # 1 Remove punctuation
    text_without_punctuation = [char for char in text if char not in string.punctuation]
    text_without_punctuation = ''.join(text_without_punctuation)

    # 2 Remove Stop Words
    text_without_stop_words = [word for word in text_without_punctuation.split() if word.lower() not in stopwords.words('english')]

    # 3 Return a list of clean words
    return text_without_stop_words

#Show the Tokenization (a list of tokens )
# print (dataFrame['text'].head().apply(process_text))

# Convert the text into a matrix of token counts.

from sklearn.feature_extraction.text import CountVectorizer

messages_bow = CountVectorizer(analyzer=process_text).fit_transform(dataFrame['text'])

# print (messages_bow)

#Split data into 80% training & 20% testing data sets

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(messages_bow, dataFrame['spam'], test_size=0.20, random_state=0)

#Get the shape of messages_bow
# messages_bow.shape
# print (messages_bow.shape)

# Create and train the Multinomial Naive Bayes classifier which is suitable for classification with discrete features (e.g., word counts for text classification)

from sklearn.naive_bayes import MultinomialNB

classifier = MultinomialNB()

classifier.fit(X_train, y_train)

# #Print the predictions
# print(classifier.predict(X_train))
#
#
# print ('divider')
# # Print the actual values
# print(y_train.values)

#Evaluate the model on the training data set
from sklearn.metrics import classification_report,confusion_matrix, accuracy_score
pred = classifier.predict(X_train)
print(classification_report(y_train, pred))
print('Confusion Matrix: \n', confusion_matrix(y_train, pred))
print()
print('Accuracy: ', accuracy_score(y_train, pred))

# #Print the predictions
# print('Predicted value: ', classifier.predict(X_test))
# print ('divider')
# #Print Actual Label
# print('Actual value: ', y_test.values)

#Evaluate the model on the test data set
from sklearn.metrics import classification_report,confusion_matrix, accuracy_score
pred = classifier.predict(X_test)
print(classification_report(y_test ,pred ))
print('Confusion Matrix: \n', confusion_matrix(y_test,pred))
print()
print('Accuracy: ', accuracy_score(y_test,pred))


import pygame as pg

pg.init()
COLOR_INACTIVE = pg.Color('lightskyblue3')
COLOR_ACTIVE = pg.Color('dodgerblue2')
FONT = pg.font.Font(None, 32)

class InputBox:

    def __init__(self, x, y, w, h, text=''):
        self.rect = pg.Rect(x, y, w, h)
        self.color = COLOR_INACTIVE
        self.text = text
        self.saved_text = ''
        self.txt_surface = FONT.render(text, True, self.color)
        self.active = False

    def handle_event(self, event):
        if event.type == pg.MOUSEBUTTONDOWN:
            # If the user clicked on the input_box rect.
            if self.rect.collidepoint(event.pos):
                # Toggle the active variable.
                self.active = not self.active
            else:
                self.active = False
            # Change the current color of the input box.
            self.color = COLOR_ACTIVE if self.active else COLOR_INACTIVE
        if event.type == pg.KEYDOWN:
            if self.active:
                if event.key == pg.K_RETURN:
                    #print(self.text)
                    self.saved_text = self.text
                    self.text = ''
                elif event.key == pg.K_BACKSPACE:
                    self.text = self.text[:-1]
                else:
                    self.text += event.unicode
                # Re-render the text.
                self.txt_surface = FONT.render(self.text, True, self.color)

    def update(self):
        # Resize the box if the text is too long.
        width = max(200, self.txt_surface.get_width()+10)
        self.rect.w = width

    def draw(self, screen):
        # Blit the text.
        screen.blit(self.txt_surface, (self.rect.x+5, self.rect.y+5))
        # Blit the rect.
        pg.draw.rect(screen, self.color, self.rect, 2)


'''
author: Ramayan Mardi
email: jaymisra.programmer@gmail.com
=======================================
:about: This is script file of the game,
:name: Flappy Game
:version: 1.0.1
:requirement:
    python -> 3.10.0 or upper
    pygame -> 2.5.2

This script file controls, all the game related stuff i.e game state, rendering etc.
:class Game: controls all the above stuff.
:function main: entry point of the game.
'''

import pygame
from pygame.locals import *
import os

# import in-built module/component
from component.utils import *
from component.flappy import Flappy
from component.pipes import ObsticalControler, MovingImage
from component.ui import GameUI

all = ("Game", "main")

# absolute path of the current files
ASSERT_PATH = "assert"
DATA_FILENAME = "data.json"

# Constants
SCREEN_SIZE = (640, 480)
TITLE = "Flappy Game"

class Game:
    ''':class: control the whole game, handles game state, handles rendering,
        handles inputs, handles I/O in file.
    '''
    FPS = None  # keep information of the the frame-per-second of the game
    all = ("setup", "update", "new_game", "run")

    def __init__(self, window_size: tuple[int, int], window_title: str):
        self.screen = pygame.display.set_mode(window_size)
        pygame.display.set_caption(window_title)

        # clock for the game controls the game time.
        self.clock = pygame.time.Clock()

        # store all the game data need for processing game
        self._gamedata = dict()

        # decide whether the game updates or not
        self._allow_update = True
        # decide whether the game-over or not
        self._gameover = False

        # store the game state
        self._game_state = "Menu"

    def setup(self) -> None:
        ''':method: used to load all the assert for the game'''

        # fetching all the data from the file.
        self._gamedata = fetch(os.path.join(ASSERT_PATH, DATA_FILENAME))

        # fetching all content for the about file.
        with open(os.path.join(ASSERT_PATH, "about.txt"), "r") as f:
            about_data = f.read()

        # load entity for the game.
        flappy_images = []

        for i in range(3):
            flappy_images.append(load_image(self._gamedata["yellowbird"][i], convert=(False, True)))

        # position of the player is in middle of the screen.
        self.flappy = Flappy(flappy_images=flappy_images, weight=self._gamedata["entity"]["weight"],
                             fly_speed=self._gamedata["entity"]["fly_speed"],
                             pos=(320, 184))

        # load all the obstical for the game.
        green_pipe = load_image(self._gamedata["game_objects"]["pipe-green"], convert=(True, False))
        self.obstical = ObsticalControler(green_pipe)

        # load all the environment for the game.
        self.background_day_image = MovingImage(load_image(
                                                self._gamedata["game_objects"]["background-day"],
                                                SCREEN_SIZE, (True, False)), (0, 0))
        self.base_image = MovingImage(load_image(self._gamedata["game_objects"]["base"], (640, 112),
                                                 convert=(True, False)), (0, 368))

        # load all sounds for the game.
        self.hit = pygame.mixer.Sound(self._gamedata["sfx"]["hit"])
        self.wing = pygame.mixer.Sound(self._gamedata["sfx"]["wing"])
        self.point = pygame.mixer.Sound(self._gamedata["sfx"]["point"])
        self.die = pygame.mixer.Sound(self._gamedata["sfx"]["die"])

        # load all the UI for the game.
        self.gameui = GameUI(self._gamedata)
        # text box for the game.
        self.textbox = TextBox(about_data, (0, 0), fontname=self._gamedata["font"]["gamefont"],
                               fontcolor="#F5EBEB", fontsize=22)

    def update(self, delta_time: float, **kw) -> None:
        ''':method: used to update all the game related stuff.

            kw: contains all the inputs data.
        '''

        # game code -------------------------------------
        if self._game_state == "Menu":
            self.screen.fill("#383838")
            self.gameui.show_gamemenu(self.screen)
            self.gameui.show_about_btn(self.screen)

            '''
            if continuation of the game is possible than the continue button gets
            highlighted.
            '''
            self.gameui.gamemenu_boxlayout.chlidren[1].active = self._gamedata["continue"]

            # trigger the functions according to the button pressed.
            # `New Game` button pressed.
            if self.gameui.gamemenu_boxlayout.chlidren[0].pressed:
                self._game_state = "Start New Game"  # game state changed
                '''
                only the the assert would draw and nothing gets updated.
                '''
                self._allow_update = False

            # `Continue` button pressed and continuation is possible.
            elif self.gameui.gamemenu_boxlayout.chlidren[1].pressed and self._gamedata["continue"]:
                # placing entity to the previous position.
                self.flappy.rect.topleft = self._gamedata["entity"]["pos"]

                # placing all the obstical for the game to the previous position.
                self.obstical._custom_pipe_pos(self._gamedata["pipes_pos"]["toppipe_list"],
                                               self._gamedata["pipes_pos"]["bottompipe_list"])

                # placing all the environment for the game to the previous position.
                self.base_image.moving_images["img1"][1].topleft = self._gamedata["other_entity"]["base_pos"]["img1"]
                self.base_image.moving_images["img2"][1].topleft = self._gamedata["other_entity"]["base_pos"]["img2"]
                self.background_day_image.moving_images["img1"][1].topleft = self._gamedata["other_entity"]["background_pos"]["img1"]
                self.background_day_image.moving_images["img2"][1].topleft = self._gamedata["other_entity"]["background_pos"]["img2"]

                # set previous score.
                self.obstical.score = self._gamedata["score"]
                self.obstical.previous_score = self._gamedata["previous_score"]

                # start the game as previous
                self._game_state = "Start New Game"
                self._allow_update = False

            # `Setting` button is pressed.
            elif self.gameui.gamemenu_boxlayout.chlidren[2].pressed:
                '''
                active the fps button which is using by the game.
                '''
                if self._gamedata["fps"] == 30:
                    self.gameui.settingmenu_boxlayout_1.chlidren[1].active = True
                else:
                    self.gameui.settingmenu_boxlayout_1.chlidren[2].active = True

                # changed the game state
                '''
                setting game state is required because in those blocks of settings.
                content a code that are updated in each frame when the game state
                is set to be "Settings"
                '''
                self._game_state = "Settings"

            # `About` button is pressed
            elif self.gameui.about_btn.pressed:
                # same reason as like the `Setting` button.
                self._game_state = "About"

        # Gets updated in each frame when 'Setting' is activate.
        elif self._game_state == "Settings":
            self.screen.fill("#383838")
            self.gameui.show_settingmenu(self.screen)

            if kw["K_x"]:
                self._game_state = "Menu"

            # trigger functions when the button inside the setting menu get pressed.
            children = self.gameui.settingmenu_boxlayout_1.chlidren

            # TODO: make the below code more clean.
            # handles the state of fps buttons and game fps setting
            if children[2].pressed:
                children[2].active = True
                # updates the entire game fps
                self._gamedata["fps"] = 60
            elif children[1].pressed:
                children[2].active = False
                # updates the entire game fps
                self._gamedata["fps"] = 30

            children[1].active = not children[2].active

        # Gets updated in each frame when 'About' is activate.
        elif self._game_state == "About":
            # textbox content all the details for the game gets visible.
            self.textbox.blit(self.screen)

            if kw["K_x"]:
                self._game_state = "Menu"

        # Gets updated in each frame when 'Start New Game' is activate.
        elif self._game_state == "Start New Game":
            # called when the game is not over and ready to play.
            if not self._gameover:
                # drawing game background.
                self.background_day_image.blit(self.screen)

                self.flappy.blit(self.screen)  # entity.

                # drawing game environment
                self.obstical.toppipe.draw(self.screen)
                self.obstical.bottompipe.draw(self.screen)
                self.base_image.blit(self.screen)
                self.gameui.show_number(self.screen, str(self.obstical.score))

                # if allow update is True
                if self._allow_update:
                    # update all the entities.
                    self.background_day_image.move_image(self.screen, 50, delta_time, (-1, 0))
                    self.flappy.update(delta_time, **kw)
                    self.obstical.update(delta_time)
                    self.base_image.move_image(self.screen, 100, delta_time, (-1, 0))

                    # check collision of entity with the pipes
                    if self.obstical.collision(self.flappy.collision_rect):
                        self.hit.play()
                        self._allow_update = False
                        self._gameover = True

                    # check collision of the entity with the base
                    if self.base_image.collision(self.flappy.collision_rect):
                        self.hit.play()
                        self._allow_update = False
                        self._gameover = True

                    '''
                    play the sound when the entity flap it's wings.
                    '''
                    if kw["K_SPACE"]:
                        self.wing.play()

                    '''
                    play sound when the point get incresed
                    '''
                    if self.obstical.score > self.obstical.previous_score:
                        self.point.play()
                        self.obstical.previous_score = self.obstical.score
                else:
                    # message show when update is False
                    '''
                    This message is show during the game start, continuation of the game,
                    and also during the game get paused.
                    '''
                    self.gameui.start_message(self.screen)

                '''
                below code handles the functionality of the pause mechanism by
                manipulating :attr self._allow_update:
                '''
                if kw["K_p"] and self._allow_update:
                    self._allow_update = False
                elif kw["K_p"] and not self._allow_update:
                    self._allow_update = True
                elif kw["K_SPACE"] and not self._allow_update:
                    self._allow_update = True

                '''
                during the game is running, and the back button is pressed then the
                continuation data gets save, and continuation gets updated.
                '''
                if kw["K_x"]:
                    # store the entity data.
                    self._gamedata["entity"] = {
                                            "weight": self.flappy.weight,
                                            "fly_speed": self.flappy.fly_speed,
                                            "pos": self.flappy.rect.center}

                    # store the list of pipe position as a data of both top-pipes and bottom-pipes.
                    self._gamedata["pipes_pos"] = {
                    "toppipe_list": [pipe.rect.topleft for pipe in self.obstical.toppipe_list],
                    "bottompipe_list": [pipe.rect.topleft for pipe in self.obstical.bottompipe_list]}

                    # store the data of other entities i.e environment stuff.
                    self._gamedata["other_entity"] = {"base_pos": {
                                "img1": self.base_image.moving_images["img1"][1].topleft,
                                "img2": self.base_image.moving_images["img2"][1].topleft
                                },
                                "background_pos": {
                                "img1": self.background_day_image.moving_images["img1"][1].topleft,
                                "img2": self.background_day_image.moving_images["img2"][1].topleft}
                    }

                    # continuation get activate and score is preserved.
                    self._gamedata["continue"] = True
                    self._gamedata["score"] = self.obstical.score
                    self._gamedata["previous_score"] = self.obstical.previous_score

                    # back to the main menu
                    self._game_state = "Menu"
                    self.new_game()

            # called when the game gets over.
            elif self._gameover:
                # store high-score data if score is greater.
                if self.obstical.score > self._gamedata["highscore"]:
                    self._gamedata["highscore"] = self.obstical.score

                # if high-score is greater than '0' it gets displayed on screen.
                if self._gamedata["highscore"]:
                    self.gameui.show_highscore(self.screen, self._gamedata["highscore"])

                # finally game-over message would be shown.
                self.gameui.gameover_message(self.screen)

                if kw["K_x"]:
                    # back to the main menu
                    self._game_state = "Menu"
                    # reset the game over button
                    self.new_game()
                    self._gamedata["continue"] = False

            if kw["K_r"] and self._gameover:
                # resume the game and its state
                self.new_game()

    def new_game(self) -> None:
        ''':method: used to set-up new game.'''

        # reset all the values.
        self._allow_update = True
        self.obstical.generate_pipe()
        self.obstical.score = 0
        self.obstical.previous_score = self.obstical.score

        self.flappy.rect.topleft = (480 // 2, 368 // 2)
        self._gameover = False

    def run(self) -> None:
        ''':method: main-loop of the game.'''

        # load all the assert for the game.
        self.setup()

        # running main-loop of the game
        running = True
        while running:
            # shortcut keys responsible for controlling inputs in the whole game.
            self.ShortCuts = {"K_SPACE": False, "K_r": False, "K_x": False,
                              "K_p": False}

            # tracking the pygame events
            for event in pygame.event.get():
                if event.type == pygame.QUIT or \
                   (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                    running = False

                # check key presses for the game
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        self.ShortCuts["K_SPACE"] = True

                    if event.key == pygame.K_p:
                        self.ShortCuts["K_p"] = True

                    if event.key == pygame.K_r:
                        self.ShortCuts["K_r"] = True

                    if event.key == pygame.K_x:
                        self.ShortCuts["K_x"] = True

            # delta time of the entire game.
            delta_time = self.clock.tick(self._gamedata["fps"]) / 1000.0
            # update the whole game.
            self.update(delta_time, **self.ShortCuts)
            pygame.display.update()

        # quit the game
        save(os.path.join(ASSERT_PATH, DATA_FILENAME), self._gamedata)
        pygame.quit()
        exit()

def main():
    ''':function: entry point of the game.'''
    pygame.init()  # initializing pygame
    Game(SCREEN_SIZE, TITLE).run()

if __name__ == '__main__':
    main()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

##
# @file genCode.py
# @brief 根据json文件生成错误码头文件以及文档
#        头文件：./release/tuya_error_code.y
#        文档  ：./release/tuya_error_code.md
# @author huatuo
# @version 1.0.0
# @date 2021-09-27
# @note 支持参数1修改文件名，如："base"，使用默认命名则传递空：""
# @note 支持参数2传入指定模块列表，参数形式支持如下：
#       "compA compB compC"
#       "compA, compB, compC"

import json
import os
import sys
import shutil
import codecs
from datetime import date

# 为了兼容python2和python3
if sys.version_info < (3, 0):
    reload(sys)
    sys.setdefaultencoding('utf8')

file_head_template = """/*******************************************************************
*  File: tuya_###MODULE###_error_code.h
*  Author: auto generate by tuya code gen system
*  Date: ###DATE###
*  Description:this file defined the error code of tuya IOT
*  you can change it manully if needed
*  Copyright(C),2018-2020, tuya inc, www.tuya.comm
*******************************************************************/

#ifndef TUYA_###MODULE_UPPER###_ERROR_CODE_H
#define TUYA_###MODULE_UPPER###_ERROR_CODE_H

#ifdef __cplusplus
extern "C" {
#endif

"""

file_foot_template = """
#define ERRCODE2STRING(errcode) #errcode
#define TUYA_ERROR_STRING(errcode)  ("[ErrCode: " ERRCODE2STRING(errcode) "]")

#define TUYA_CHECK_NULL_RETURN(x, y)\\
do{\\
    if (NULL == (x)){\\
        TAL_PR_ERR("%s null", #x);\\
        return (y);\\
    }\\
}while(0)

#define TUYA_CHECK_NULL_GOTO(x, label)\\
do{\\
    if (NULL == (x)){\\
        TAL_PR_ERR("%s null", #x);\\
        goto label;\\
    }\\
}while(0)

#define TUYA_CALL_ERR_LOG(func)\\
do{\\
    rt = (func);\\
    if (OPRT_OK != (rt)){\\
        TAL_PR_ERR("ret:%d", rt);\\
    }\\
}while(0)

#define TUYA_CALL_ERR_GOTO(func, label)\\
do{\\
    rt = (func);\\
    if (OPRT_OK != (rt)){\\
        TAL_PR_ERR("ret:%d", rt);\\
        goto label;\\
    }\\
}while(0)

#define TUYA_CALL_ERR_RETURN(func)\\
do{\\
    rt = (func);\\
    if (OPRT_OK != (rt)){\\
       TAL_PR_ERR("ret:%d", rt);\\
       return (rt);\\
    }\\
}while(0)

#define TUYA_CALL_ERR_RETURN_VAL(func, y)\\
do{\\
    rt = (func);\\
    if (OPRT_OK != (rt)){\\
        TAL_PR_ERR("ret:%d", rt);\\
        return (y);\\
    }\\
}while(0)

#define TUYA_CALL_ERR_LOG_SEQ_RETURN_VAL(func, y, point)\\
do{\\
    rt = (func);\\
    if (OPRT_OK != (rt)){\\
        TAL_PR_ERR("ret:%d", rt);\\
        INSERT_ERROR_LOG_SEQ_DEC((point), rt);\\
        return (y);\\
    }\\
}while(0)

#define TUYA_CALL_ERR_LOG_SEQ_RETURN(func, point)\\
do{\\
    rt = (func);\\
    if (OPRT_OK != (rt)){\\
        TAL_PR_ERR("ret:%d", rt);\\
        INSERT_ERROR_LOG_SEQ_DEC((point), rt);\\
        return (rt);\\
    }\\
}while(0)

#define TUYA_CALL_ERR_LOG_SEQ_GOTO(func, label)\\
do{\\
    rt = (func);\\
    if (OPRT_OK != (rt)){\\
        TAL_PR_ERR("ret:%d", rt);\\
        INSERT_ERROR_LOG_SEQ_DEC((point), rt);\\
        goto label;\\
    }\\
}while(0)

#define TUYA_CALL_ERR_LOG_SEQ(func)\\
do{\\
    rt = (func);\\
    if (OPRT_OK != (rt)) {\\
        TAL_PR_ERR("ret:%d", rt);\\
        INSERT_ERROR_LOG_SEQ_DEC((point), rt);\\
    }\\
}while(0)

#define TUYA_CHECK_NULL_LOG_SEQ_RETURN(x, y, point)\\
do{\\
    if (NULL == (x)){\\
        TAL_PR_ERR("%s null", #x);\\
        INSERT_ERROR_LOG_SEQ_DEC((point), y);\\
        return (y);\\
    }\\
}while(0)

#define TUYA_CHECK_NULL_LOG_SEQ_GOTO(x, point, label)\\
do{\\
    if (NULL == (x)){\\
        TAL_PR_ERR("%s null", #x);\\
        INSERT_ERROR_LOG_SEQ_NULL((point));\\
        goto label;\\
    }\\
}while(0)

#ifdef __cplusplus
}
#endif
#endif
"""

marco_head_template = """
/****************************************************************************
            the error code marco define for module ###MODULE###
****************************************************************************/
"""

class codegen():
    def __init__(self, file_name="", enable_list=[]):
        self.output_path = "./release"
        self.modules = None  # json
        self.file_name = "_" + file_name if len(file_name) else ""
        self.enable_list = enable_list
        print("file_name: ", file_name)
        print("enable_list: ", enable_list)

    def load_modules(self):
        module_file = codecs.open("./module.json", "r", "utf-8")
        self.modules = json.load(module_file, encoding='utf-8')['TuyaEmbeddedErrcode']

    # 判断该组件错误码是否要被处理
    def _modules_is_ok(self, module):
        if (len(module['errcode']) == 0):
            #  print("module length is 0: ", module['name'])
            return False
        if (module['offset']>255) or (len(module['errcode'])>255):
            print("module over offset: ", module['name'])
            return False
        if self.enable_list == []:
            # 使能列表为空中则生成全部错误码
            return True
        if module['name'] not in self.enable_list:
            # 模块没有被使能
            return False
        return True

    def _gen_tbl_header(self, module_name, index, errcode_cnt):
        tbl_header = "\n## " + str(index) + ". module " + '`' + module_name + '`' + "\n\n"
        if errcode_cnt > 0:
            tbl_header = tbl_header + "   No. | Name  | Value | message" + "\n"
            tbl_header = tbl_header + "-------|-------|-------|--------" + "\n"
        return tbl_header

    def _gen_marco_item(self, module_name, errcode, offset, index):
        marco_item = ""
        marco_msg = ""
        marco_val = ""

        # prefix, global error code not have module_name
        marco_item_prefix = "OPRT"+ "_" + module_name.upper() + "_"
        marco_item_prefix_global = "OPRT" + "_"

        # only one key in error code
        for key in errcode:
            if module_name  == "global":
                marco_item = marco_item_prefix_global + key
            else:
                marco_item = marco_item_prefix + key
            error_val = "-%#06x" % ((offset<<8) + index)
            marco_val = "(%s)" % error_val
            marco_msg = str(int(error_val, 16)) + ", " + errcode[key]

        return marco_item, marco_val, marco_msg

    def gen_md(self):
        file_content = "# Tuya Embedded software error code define" + "\n"

        module_index = 0
        for module in self.modules:
            if not self._modules_is_ok(module):
                continue
            module_index += 1
            file_content = file_content + self._gen_tbl_header(module["name"].upper(), module_index, len(module['errcode']))
            index = 0
            for errcode in module["errcode"]:
                marco_item, marco_val, marco_msg = self._gen_marco_item(module["name"], errcode, module["offset"], index)
                marco_item, marco_val, marco_msg = '`'+marco_item+'`', '`'+marco_val+'`', '`'+marco_msg+'`'
                index += 1
                file_content = file_content + str(index) + "|" + marco_item + "|" + str(marco_val) + "|" + marco_msg
                file_content = file_content + "\n"

        # 生成.md文件
        file_name = self.output_path + "/tuya_###MODULE###_error_code.md".replace("_###MODULE###", self.file_name)
        fd = open(file_name, 'w')
        fd.write(file_content)
        fd.close()
        # print("OK!")

        return

    def gen_marco(self, module):
        define = "#define"
        marco_content_head = marco_head_template.replace("###MODULE###", module["name"].upper())
        marco_content_body = ""

        marco_item_prefix = "OPRT"+ "_" + module["name"].upper() + "_"
        index = 0

        for errcode in module["errcode"]:
            marco_item, marco_val, marco_msg = self._gen_marco_item(module["name"], errcode, module["offset"], index)
            index += 1

            # appened to the marco content
            marco_define = "%(d)s %(i)-50s %(v)+8s  //%(m)s" % \
                            {'d':define, 'i':marco_item, 'v':marco_val, 'm':marco_msg}
            marco_content_body = marco_content_body + marco_define + '\n'

        max_marco_cnt = define + " " + marco_item_prefix + "ERRCODE_MAX_CNT" + " " + str(index)

        marco_content_body = marco_content_body + max_marco_cnt + '\n\n'
        marco_content = marco_content_head + marco_content_body

        return marco_content

    def gen_file(self):
        file_name = self.output_path +"/tuya_###MODULE###_error_code.h".replace("_###MODULE###", self.file_name)
        fd = open(file_name, 'w')

        # head
        file_head = file_head_template.replace("_###MODULE###", self.file_name)
        file_head = file_head.replace("_###MODULE_UPPER###", self.file_name.upper())
        file_head = file_head.replace("###DATE###", str(date.today()))
        fd.write(file_head)

        # marco
        for module in self.modules:
            if not self._modules_is_ok(module):
                continue
            marco_str = self.gen_marco(module)
            fd.write(marco_str)

        fd.write(file_foot_template)
        fd.close()
        # print("OK!")

        return

    def dogen(self):
        # load all module description
        self.load_modules()

        # clean output path
        shutil.rmtree(self.output_path, ignore_errors=True)
        os.mkdir(self.output_path)

        # gen .h file
        # print("generate errcode .h file...")
        rt = self.gen_file()

        # gen .md file
        # print("generate errcode .md file...")
        self.gen_md()

        return

if __name__ == '__main__':
    file_name = ""
    if len(sys.argv) > 1:
        file_name = sys.argv[1]
    enable_list = []
    if len(sys.argv) > 2:
        enable_list_str = sys.argv[2]
        enable_list = enable_list_str.replace(',', ' ').split()
    gen = codegen(file_name, enable_list)
    gen.dogen()


import torch
import shutil

import torch.optim as optim
import numpy as np

from torch import nn
from torch.utils.data import DataLoader
from torchvision import transforms
from utils import AverageMeter, min_max_normalize, save_checkpoint
from dataset import DAEDataset
from model import ModelRec

transform = transforms.Compose([transforms.Resize((300, 400)),
                                transforms.ToTensor(),
                                transforms.Lambda(lambda tensor: min_max_normalize(tensor))])

#working directory
root = '/content'

train_dataset = DAEDataset(root, mode='train', transform=transform)
val_dataset = DAEDataset(root, mode='val', transform=transform)

train_loader = DataLoader(dataset=train_dataset, batch_size=16, shuffle=True)
val_loader = DataLoader(dataset=val_dataset, batch_size=2, shuffle=True)

def train(train_loader, val_loader, model, optimizer, scheduler, criterion, num_epochs):

  best_loss = 1

  for epoch in range(num_epochs):
    scheduler.step()

    train_loss = AverageMeter()
    val_loss = AverageMeter()

    model.train()
    for input, target in train_loader:
      input = input.cuda()
      target = target.cuda()

      optimizer.zero_grad()
      output = model(input)

      loss = criterion(output, target)
      train_loss.up_date(loss, input.size(0))

      loss.backward()
      optimizer.step()

    print('Epoch {} of {}, Train_loss: {:.3f}'.format(epoch + 1, num_epochs, train_loss.avg))

    model.eval()
    for input, target in val_loader:
      input = input.cuda()
      target = target.cuda()

      output = model(input)

      loss = criterion(output, target)
      val_loss.up_date(loss, input.size(0))

    is_best = val_loss.avg < best_loss
    best_loss = min(val_loss.avg, best_loss)
    save_checkpoint({
        'epoch': epoch + 1,
        'arch': experiment,
        'state_dict': model.state_dict(),
        'best_prec1': best_loss,
        'optimizer': optimizer.state_dict(),
    }, is_best)

    print('Epoch {} of {}, Val_loss: {:.3f}'.format(epoch + 1, num_epochs, val_loss.avg))

def main():
  torch.cuda.empty_cache()

  model = ModelRec().cuda()
  criterion = nn.BCELoss().cuda()
  optimizer = optim.Adam(model.parameters())
  scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size = 50,   gamma=0.1)
  experiment = "DAE_Conv"
  num_epochs = 200

  #checkpoint = torch.load('/content/checkpoint.pth.tar')
  #model.load_state_dict(checkpoint['state_dict'])

  train(train_loader, val_loader, model, optimizer, scheduler, criterion, num_epochs)

if __name__ == '__main__':
    main()


import matplotlib.pyplot as plt
import cv2

import time
start_time = time.time()

# Titik awal
x1 = 1
y1 = 7

# Titik Akhir
x2 = 7
y2 = 15

dy = y2-y1
dx = x2-x1

step = dx  if dx > dy  else dy

xInc = dx / step
yInc = dy / step

x=x1
y=y1

len=y2+x2

# x axis value list.
x_number_list = []

x_number_list.append(x1)

# y axis value list.
y_number_list = []

y_number_list.append(y1)

for i in range(1,len):

    x = x + xInc
    y = y + yInc

    xBulat=int(x)
    yBulat=int(y)

    x_number_list.append(xBulat)
    y_number_list.append(yBulat)

    if(x>=x2 and y>=y2):
        break

end_time = time.time()
delta_time = end_time-start_time
print("Execution Time : ",delta_time," ms")

from guppy import hpy

h = hpy()

print (h.heap())

# Draw point based on above x, y axis values.
plt.scatter(x_number_list, y_number_list, s=10)

# Set chart title.
plt.title("Algoritma DDA")

# Set x, y label text.
plt.xlabel("X")
plt.ylabel("Y")
plt.show()


import numpy as np
import cvxpy as cp

import matplotlib.pyplot as plt

# double integrator
# state is [x, vx, y, vy]

T = 0.1 # timestep in seconds
A = np.kron(np.eye(2),np.array([[1, T], [0, 1]]))
B = np.kron(np.eye(2), np.array([[0.5*T**2], [T]]))

class MPC:
  def __init__(self, prediction_horizon = 10, number_of_agents = 1, umax=100.0, obstacles=[]):

    self.N = prediction_horizon
    self.num_agents = number_of_agents
    self.obstacles = obstacles
    self.umax = umax

    self.solution_X = None
    self.solution_U = None # updated once solve is called

    return

  def plot(self):
    if self.solution_X is None:
      print("Please call solve first")
      return

    # plot the trajectories
    plt.figure()
    for i in range(self.num_agents):
      xs = [x[0] for x in self.solution_X[i]]
      ys = [x[2] for x in self.solution_X[i]]
      plt.plot(xs, ys, label=f"Agent {i}")
      plt.scatter([xs[0]], [ys[0]], marker="o", label=None)
      plt.scatter([xs[-1]], [ys[-1]], marker="x", label=None)

    plt.grid()
    plt.xlabel("x [m]")
    plt.ylabel("y [m]")
    plt.legend()

    # plt.show()
    plt.savefig("plot.png")

  def solve(self, x0, xT):

    # x0 is a list of initial conditions
    # xT is a list of target states

    ### constuct the MPC problem

    X = [[cp.Variable(4) for _ in range(self.N)]  for i in range(self.num_agents)]
    # X[i][k] is the i-th agents state at time k
    U = [[cp.Variable(2) for _ in range(self.N-1)] for i in range(self.num_agents)]

    ### create constraints
    constraints = []

    # initial and final conditions
    for i in range(self.num_agents):
      constraints.append(X[i][0] == x0[i])
      constraints.append(X[i][-1] == xT[i])

    # dynamics constraints
    for i in range(self.num_agents):
      for k in range(self.N-1): # at each timestep
        constraints.append(X[i][k+1] == A @ X[i][k] + B @ U[i][k])

    # input constraints
    for i in range(self.num_agents):
      for k in range(self.N-1):
        constraints.append(cp.norm(U[i][k], "inf") <= self.umax)

    ### construct the objective function

    objective = sum(sum(cp.sum_squares(uk) for uk in Ui) for Ui in U)

    ###  call a solver
    prob = cp.Problem(cp.Minimize(objective), constraints)
    prob.solve()

    ### save the trajectory
    self.solution_X = [[x.value for x in Xi] for Xi in X]
    self.solution_U = [[u.value for u in Ui] for Ui in U]

    ### return instantaneous control input
    return [u[0] for u in self.solution_U]

mpc = MPC(number_of_agents=2)

x0 = [np.array([0,0,0,0]), np.array([1,0,0,0])]
xT = [np.array([1,0,1,0]), np.array([0,0,1,0])]
mpc.solve(x0, xT)

mpc.plot()


import math
from SynRD.publication import Publication, Finding, VisualFinding, TAXONOMY

import numpy as np
import pandas as pd
import statsmodels as sm
import statsmodels.stats.weightstats

class Assari2019Baseline(Publication):
    DEFAULT_PAPER_ATTRIBUTES = {
        'id': 'assari2019baseline',
        'length_pages': 15,
        'authors': ['Shervin Assari', 'Mohsen Bazargan'],
        'journal': 'International Journal of Environmental Research and Public Health',
        'year': 2019,
        'current_citations': 9, #number of citations the paper has or how many people have cited it?
        'base_dataframe_pickle': 'assari2019ability_dataframe.pickle'
    }

    RACE_MAP = {
        1: "White",
        2: "Black"
    }

    GENDER_MAP = {
        1: "Man",
        2: "Woman"
    }

    FILENAME = 'assari2019baseline'

    COLUMN_MAP =  {"V2102": "Race", "V103": "Gender", "V2000": "Age", "V2007": "Education", "V2020": "Income", "V2637": "Smoking", "V2623": "BMI", "V2681": "HTN", "V13214": "Exercise", "V2203": "Depressive symptoms", "V915": "Health", "V1860": "Weight", "V15003": "Response pattern", "V836": "Stroke wave 1", "V4838": "Stroke wave 2", "V10225": "Stroke wave 3", "V12305": "Stroke wave 4", "V15944": "Stroke wave 5", "V12302": "Any stroke"}

    corr_df = None
    means = None
    dead = None

    def __init__(self, dataframe=None):
        super(Assari2019Baseline, self).__init__(dataframe=dataframe)

        self.FINDINGS = self.FINDINGS + [
            Finding(self.finding_5_1, description="finding_5_1",
                    text="""Blacks were younger, had higher number of
                    chronic medical conditions at baseline in comparison to Whites.""",
                            finding_type=TAXONOMY.MEAN_DIFFERENCE.value.BETWEEN_CLASS),
            Finding(self.finding_5_2, description="finding_5_2",
                    text="""Relative to White people, Black individuals had also
                    lower educational attainment (p < 0.05 for all).""",
                            finding_type=TAXONOMY.MEAN_DIFFERENCE.value.BETWEEN_CLASS),
            Finding(self.finding_5_3, description="finding_5_3",
                    text="""Blacks also reported worse self-rated health (SRH) than
                    Whites (Table 1).""",
                            finding_type=TAXONOMY.MEAN_DIFFERENCE.value.BETWEEN_CLASS),
            Finding(self.finding_5_6, description="finding_5_6",
                    text="""Similarly, overall, people had 12.53 years of schooling at
                    baseline (95%CI = 12.34-12.73).""",
                            finding_type=TAXONOMY.DESCRIPTIVE_STATISTICS),
            Finding(self.finding_5_7, description="finding_5_7",
                    text="""A comparison of racial groups showed higher educational
                    attainment in Whites (12.69, 95%CI=12.48-12.90) than Blacks (11.37,95%CI
                    = 10.90-11.84). Thus, on average, Whites had more than 1.3 years higher
                    years [sic] of schooling than Blacks...""",
                            finding_type=TAXONOMY.MEAN_DIFFERENCE.value.BETWEEN_CLASS),
            Finding(self.finding_5_8, description="finding_5_8",
                    text="""Of the 177 that died, 121 were White (68.36%) and 56 were
                    Black (31.64%).""",
                            finding_type=TAXONOMY.DESCRIPTIVE_STATISTICS),
            Finding(self.finding_5_9, description="finding_5_9",
                    text="""Of the 177 that died, 33 were obese (18.64%) and 144 were
                    not obese (81.36%) at baseline.""",
                            finding_type=TAXONOMY.DESCRIPTIVE_STATISTICS),
            Finding(self.finding_6_1, description="finding_6_1",
                    text="""In bivariate association, race was not associated with death
                    due to cerebrovascular (unadjusted HR for Blacks compared to
                    Whites = 0.78, 95% CI = 0.55-1.11), suggesting that Whites and
                    Blacks had similar risk of future cerebrovascular mortality over 25 years.""",
                            finding_type=TAXONOMY.CORRELATION.value.PEARSON_CORRELATION),
            Finding(self.finding_6_2, description="finding_6_2",
                    text="""In bivariate association, baseline obesity was not associated
                    with future risk of cerebrovascular mortality (Unadjusted HR for
                    Blacks compared to Whites = 0.84, 95% CI = 0.45-1.56), suggesting
                    that Whites and Blacks had a similar risk of future cerebrovascular
                    mortality over 25 years.""",
                            finding_type=TAXONOMY.CORRELATION.value.PEARSON_CORRELATION),
            Finding(self.finding_6_3, description="finding_6_3",
                    text="""Race (Black) was negatively associated with education and income""",
                            finding_type=TAXONOMY.CORRELATION.value.PEARSON_CORRELATION),
            Finding(self.finding_6_4, description="finding_6_4",
                    text="""[race (Black) was]... positively associated with depressive
                    symptoms, hypertension, and obesity.""",
                            finding_type=TAXONOMY.CORRELATION.value.PEARSON_CORRELATION),
            Finding(self.finding_6_5, description="finding_6_5",
                    text="""Blacks more frequently smoked and less frequently exercised.""",
                            finding_type=TAXONOMY.CORRELATION.value.PEARSON_CORRELATION),
            Finding(self.finding_6_6, description="finding_6_6",
                    text="""Race was not associated with cerebrovascular death.""",
                            finding_type=TAXONOMY.CORRELATION.value.PEARSON_CORRELATION),
            Finding(self.finding_6_7, description="finding_6_7",
                    text="""Baseline obesity was associated with female gender and less
                    education, income, smoking, and exercise.""",
                            finding_type=TAXONOMY.CORRELATION.value.PEARSON_CORRELATION),
            Finding(self.finding_6_8, description="finding_6_8",
                    text="""Obesity at baseline was associated with depressive symptoms and
                    hypertension at baseline.""",
                            finding_type=TAXONOMY.CORRELATION.value.PEARSON_CORRELATION),
            Finding(self.finding_6_9, description="finding_6_9",
                    text="""Obesity at baseline was not associated with cerebrovascular
                    death in the pooled sample (Table 2).""",
                            finding_type=TAXONOMY.CORRELATION.value.PEARSON_CORRELATION)
        ]

    def _get_any_stroke_if_died(self, x):
        response_pattern = str(x["Response pattern"])
        if "4" not in response_pattern:
            return 0 # patient did not die
        for i in range(5):
            if x[f"Stroke wave {i + 1}"] == 1:
                return 1
        return 0

    def _recreate_dataframe(self, filename='assari2019baseline_dataframe.pickle'):
        data = pd.read_csv('data/DS0001/04690-0001-Data.tsv', sep='\t')

        data = data[self.COLUMN_MAP.keys()]
        data.rename(columns=self.COLUMN_MAP, inplace=True)

        data = data[(data["Race"] == 1) | (data["Race"] == 2)] # 1 = white, 2 = Black
        data["Educational attainment"] = data.apply(lambda x: 1 if x["Education"] >= 12 else 0, axis=1)
        data["Obesity"] = data.apply(lambda x: 1 if x["BMI"] > 30 else 0, axis=1)
        data["Health binary"] = data.apply(lambda x: 1 if x["Health"] in [1, 2, 3] else 0, axis=1)
        data["Death to cerebrovascular disease"] = data.apply(lambda x: self._get_any_stroke_if_died(x), axis=1)
        data['Exercise'] = data['Exercise'].replace(-99.0, 0)
        data.drop(columns=['Stroke wave 1', 'Stroke wave 2', 'Stroke wave 3', 'Stroke wave 4', 'Stroke wave 5','Response pattern', 'Any stroke'], inplace=True)

        data.to_pickle(filename)
        return data

    def get_corr(self):
        if self.corr_df is None:
            corr_df = self.dataframe[['Race', 'Age', 'Gender', 'Education', 'Income', 'Smoking', 'Exercise', 'Depressive symptoms', 'HTN', 'Obesity', 'Death to cerebrovascular disease']]
            self.corr_df = corr_df.corr()
        return self.corr_df

    def get_race_pools_with_means(self):
        if self.means is None:
            black_pool = self.dataframe.loc[self.dataframe['Race'] == 2]
            white_pool = self.dataframe.loc[self.dataframe['Race'] == 1]

            black_pool_means, white_pool_means = self._get_adjusted_means(black_pool), self._get_adjusted_means(white_pool)
            means = pd.concat([black_pool_means, white_pool_means])
            means['Race'] = ['Black', 'White']
            means.set_index('Race', inplace=True)

            self.means = means
        return self.means

    def _get_adjusted_means(self, data_sample):
        temp_means = np.around(sm.stats.weightstats.DescrStatsW(data_sample, weights=data_sample['Weight']).mean, 4)
        return pd.DataFrame(data=[temp_means], columns=data_sample.columns)

    def get_dead(self):
        if self.dead is None:
            self.dead = self.dataframe.loc[self.dataframe['Death to cerebrovascular disease'] == 1]
        return self.dead

    def finding_5_1(self):
        """Blacks were younger, had higher number of chronic medical conditions at baseline in comparison to Whites."""
        means = self.get_race_pools_with_means()
        black_age = means['Age']['Black']
        white_age = means['Age']['White']
        black_htn = means['HTN']['Black']
        white_htn = means['HTN']['White']
        values = [black_age, white_age, black_htn, white_htn]
        soft_finding = black_age < white_age and black_htn > white_htn
        return (values, soft_finding, values)

    def finding_5_2(self):
        """Relative to White people, Black individuals had also lower educational attainment (p < 0.05 for all)."""
        means = self.get_race_pools_with_means()
        black_education = means['Education']['Black']
        white_education = means['Education']['White']
        values = [black_education, white_education]
        soft_finding =  black_education < white_education
        return (values, soft_finding, values)

    def finding_5_3(self):
        """Blacks also reported worse self-rated health (SRH) than Whites (Table 1)."""
        means = self.get_race_pools_with_means()
        black_health = means['Health']['Black']
        white_health = means['Health']['White']
        values = [black_health, white_health]
        soft_finding = black_health > white_health # note 1 = excellent, 5 = poor
        return (values, soft_finding, values)

    def finding_5_4(self):
        """The overall prevalence of DM was 5.73%, (95%CI = 4.80-6.82)."""
        pass

    def finding_5_5(self):
        """DM was more common in Blacks (9.22%, 95%CI = 7.75-10.95) than Whites (5.25%, 95%CI = 4.2.4-6.50)."""
        pass

    def finding_5_6(self):
        """Similarly, overall, people had 12.53 years of schooling at baseline (95%CI = 12.34-12.73)."""
        means = self._get_adjusted_means(self.dataframe)
        years_schooling = means['Education'][0]
        # soft_finding = round(years_schooling, 2) == 12.53
        soft_finding = np.allclose(float(round(years_schooling, 2)), 12.53, atol=0.2)
        return ([years_schooling], soft_finding, [years_schooling])

    def finding_5_7(self):
        """A comparison of racial groups showed higher educational attainment in Whites (12.69, 95%CI=12.48-12.90) than Blacks (11.37,95%CI = 10.90-11.84). Thus, on average, Whites had more than 1.3 years higher years [sic] of schooling than Blacks..."""
        means = self.get_race_pools_with_means()
        white_education = means['Education']['White']
        black_education = means['Education']['Black']
        values = [white_education, black_education]
        soft_finding = white_education > black_education + 1.2
        return (values, soft_finding, values)

    def finding_5_8(self):
        """Of the 177 that died, 121 were White (68.36%) and 56 were Black (31.64%). Note that we were unable to reproduce this result."""
        dead = self.get_dead()
        total = dead.shape[0]
        black_count = dead.loc[dead['Race'] == 2].shape[0]
        white_count = dead.loc[dead['Race'] == 1].shape[0]
        values = [total, white_count, black_count]
        # soft_finding = total == 177 and white_count == 121 and black_count == 56
        white_percentage = float(white_count) / float(total)
        soft_finding = np.allclose(white_percentage, 0.68, atol=0.05)
        return (values, soft_finding, values)

    def finding_5_9(self):
        """Of the 177 that died, 33 were obese (18.64%) and 144 were not obese (81.36%) at baseline. Note that we were unable to reproduce this result."""
        dead = self.get_dead()
        total = dead.shape[0]
        obese_count = dead.loc[dead['Obesity'] == 1].shape[0]
        not_obese_count = dead.loc[dead['Obesity'] == 0].shape[0]
        values = [total, obese_count, not_obese_count]
        # soft_finding = total == 177 and obese_count == 33 and not_obese_count == 144
        obese_percentage = float(obese_count) / float(total)
        soft_finding = np.allclose(obese_percentage, 0.18, atol=0.05)
        return (values, soft_finding, values)

    def finding_6_1(self):
        """In bivariate association, race was not associated with death due to cerebrovascular (unadjusted HR for Blacks compared to Whites = 0.78, 95% CI = 0.55-1.11), suggesting that Whites and Blacks had similar risk of future cerebrovascular mortality over 25 years."""
        corr_df = self.get_corr()
        corr_race_death = corr_df['Race'].loc['Death to cerebrovascular disease']
        soft_finding = abs(corr_race_death) < 0.03
        return ([corr_race_death], soft_finding, [corr_race_death])

    def finding_6_2(self):
        """In bivariate association, baseline obesity was not associated with future risk of cerebrovascular mortality (Unadjusted HR for Blacks compared to Whites = 0.84, 95% CI = 0.45-1.56), suggesting that Whites and Blacks had a similar risk of future cerebrovascular mortality over 25 years."""
        corr_df = self.get_corr()
        corr_obesity_death = corr_df['Obesity'].loc['Death to cerebrovascular disease']
        soft_finding = abs(corr_obesity_death) < 0.03
        return ([corr_obesity_death], soft_finding, [corr_obesity_death])

    # TODO: check that race correlation is for Black
    def finding_6_3(self):
        """Race (Black) was negatively associated with education and income"""
        corr_df = self.get_corr()
        values = [corr_df['Race'].loc['Education'], corr_df['Race'].loc['Income']]
        soft_finding = all(x < 0 for x in values)
        return (values, soft_finding, values)

    # TODO: check that race correlation is for Black
    def finding_6_4(self):
        """[race (Black) was]... positively associated with depressive symptoms, hypertension, and obesity. Note that we were unable to reproduce this result."""
        corr_df = self.get_corr()
        values = [corr_df['Race'].loc['Depressive symptoms'], corr_df['Race'].loc['HTN'], corr_df['Race'].loc['Obesity']]
        soft_finding =  all(x > 0 for x in values)
        return (values, soft_finding, values)

    # TODO: check that race correlation is for Black
    def finding_6_5(self):
        """Blacks more frequently smoked and less frequently exercised.""" # implies positive correlation with smoking and negative with exercise
        corr_df = self.get_corr()
        values = [corr_df['Race'].loc['Smoking'], corr_df['Race'].loc['Exercise']]
        soft_finding = values[0] > 0 and  values[1] < 0
        return (values, soft_finding, values)

    # TODO: check that race correlation is for Black
    def finding_6_6(self):
        """Race was not associated with cerebrovascular death.""" # same as finding_6_1?
        corr_df = self.get_corr()
        corr_race_death = corr_df['Race'].loc['Death to cerebrovascular disease']
        soft_finding = abs(corr_race_death) < 0.05
        return ([corr_race_death], soft_finding, [corr_race_death])

    # TODO: check that gender correlation is for female
    def finding_6_7(self):
        """Baseline obesity was associated with female gender and less education, income, smoking, and exercise."""
        corr_df = self.get_corr()
        values = [corr_df['Obesity'].loc['Gender'], corr_df['Obesity'].loc['Education'], corr_df['Obesity'].loc['Income'], corr_df['Obesity'].loc['Smoking'], corr_df['Obesity'].loc['Exercise']]
        soft_finding =  values[0] > 0 and all(x < 0 for x in values[1:])
        return (values, soft_finding, values)

    def finding_6_8(self):
        """Obesity at baseline was associated with depressive symptoms and hypertension at baseline. Note that we were unable to reproduce this result."""
        corr_df = self.get_corr()
        values = [corr_df['Obesity'].loc['Depressive symptoms'], corr_df['Obesity'].loc['HTN']]
        soft_finding = all(x > 0 for x in values)
        return (values, soft_finding, values)

    def finding_6_9(self):
        """Obesity at baseline was not associated with cerebrovascular death in the pooled sample (Table 2).""" # same as finding_6_2?
        corr_df = self.get_corr()
        corr_obesity_death = corr_df['Obesity'].loc['Death to cerebrovascular disease']
        soft_finding = abs(corr_obesity_death) < 0.05
        return ([corr_obesity_death], soft_finding, [corr_obesity_death])

    def finding_6_10(self):
        """According to Model 1 in the pooled sample, baseline obesity did not predict cerebrovascular mortality (HR = 0.86, 0.49-1.51), independent of demographic, socioeconomic, health behaviors, and health factors at baseline."""
        pass

    def finding_6_11(self):
        """According to Model 2, race interacted with baseline obesity on outcome (HR = 3.17, 1.09-9.21), suggesting a stronger association between baseline obesity and future risk for cerebrovascular deaths for Blacks, in comparison to Whites (Table 3)."""
        pass

    def finding_6_12(self):
        """As Model 3 shows, obesity did not predict the outcome in Whites (HR = 0.69, 0.31-1.53)."""
        pass

    def finding_6_13(self):
        """Model 4 shows that obesity predicts risk of cerebrovascular mortality for Blacks (HR = 2.51, 1.43-4.39) (Table 4)."""
        pass