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

st.title('Cicle Rides in NYC')

DATA_URL = ('citibike-tripdata.csv')
DATE_COLUMN = 'started_at'

@st.cache_data
def load_data(nrows):
    data = pd.read_csv(DATA_URL, nrows=nrows)
    lowercase = lambda x: str(x).lower()
    data.rename({'start_lat': 'lat', 'start_lng': 'lon'}, axis=1, inplace=True)
    data[DATE_COLUMN] = pd.to_datetime(data[DATE_COLUMN])
    return data

data_load_state = st.text('Loading data...')
data = load_data(500)
data_load_state.text('Done! (using cache...)')

#Side

sidebar = st.sidebar
sidebar.image('img.jpeg')
sidebar.header('Yahir Jesus Jacome Cogco')
sidebar.header('S20006732')
sidebar.header('zs20006732@estudiantes.uv.mx')

agree = sidebar.checkbox("Show raw data")
if agree:
    st.header("Raw data")
    st.dataframe(data)

#Hist

if st.sidebar.checkbox('Recorridos por hora'):
    st.subheader('Numero de recorridos por hora')

    hist_values = np.histogram(data[DATE_COLUMN].dt.hour, bins=24, range=(0,24))[0]
    st.bar_chart(hist_values)

#Map

hour_to_filter = st.sidebar.slider('hour', 0, 23, 17)
filtered_data = data[data[DATE_COLUMN].dt.hour == hour_to_filter]

st.subheader('Mapa de recorridos iniciados a las %s:00' % hour_to_filter)
st.map(filtered_data)


""" Gets all the information on the lichess4545 league """
import re
import ssl
import sys
import json
from bs4 import BeautifulSoup
from urllib import request, parse, error
from Utilities import Season, Tournament, Team, get_all_seasons

# Globals
LICHESS4545_URL = 'https://www.lichess4545.com'

# SSL Certificates
CTX = ssl.create_default_context()
CTX.check_hostname = False
CTX.verify_mode = ssl.CERT_NONE

# Functions
def fancy_fractions(str):
    """ Convert a fancy looking fraction to a float (only works for halfs)

    args:
        str (string): The string to Convert
    """
    if '½' in str:
        if str[:-1]:
            return float(str[:-1]) + 0.5
        else:
            return 0.5
    else:
        return float(str)

# Class for Tracking a 4545 league season
class Lichess:
    def set_season(self, season_number):
        """ Initializes the league

        args:
            season_number (int): The season number
        """
        self.season = Season('Chess', f'Season {season_number}', None, 7, 100)
        self.season_number = season_number

    def get_seasons(self):
        """ Returns a list of seasons that haven't been processed"""
        result = request.urlopen(
            f'{LICHESS4545_URL}/team4545/season/1/summary/',
            context=CTX)
        beautiful_result = BeautifulSoup(result, 'html.parser')
        seasons = [int(season.get_text().strip().split()[1])
                   for season in beautiful_result.find_all(
                   'ul', {'class': 'dropdown-menu'})[-1].find_all('li')[2:]]
        run_seasons = [int(season[0].split()[1]) for season in get_all_seasons()]
        return set(seasons).difference(set(run_seasons))

    def get_season(self):
        """ Get a season"""
        result = request.urlopen(
            f'{LICHESS4545_URL}/team4545/season/{self.season_number}/pairings',
            context=CTX)
        round_results = BeautifulSoup(result, 'html.parser')

        # Get all team names TODO: Fix round ordering
        round_results_ordered = sorted(
            [round_result.get('href', '')
             for round_result in round_results.find_all('a')
             if re.fullmatch('/team4545/season/[0-9]+/round/[0-9]+/pairings/',
                             round_result.get('href', ''))],
            key=lambda x: int(x.split('/')[5]))
        for team in round_results_ordered:
            # Get the round results
            opponents = BeautifulSoup(request.urlopen(
                f"{LICHESS4545_URL}{team}",
                context=CTX),
                'html.parser'
            )
            # Collect the round results
            tournament_name = f"Round {team.split('/')[5]}"
            if tournament_name in self.season.tournaments:
                continue
            self.season.create_tournament(tournament_name)
            team_names = [opponent.get_text().strip()
                          for opponent in opponents.find_all('a', {'class': 'team-link'}
                          )]
            results = [fancy_fractions(score.get_text().strip())
                       for score in opponents.find_all('th', {'class': 'cell-score'}
                       )]
            # Insert the round results into the season
            for i in range(int(len(team_names)/2)):
                self.season.create_round(
                    team_names[2*i],
                    team_names[2*i+1],
                    results[2*i],
                    results[2*i] + results[2*i+1],
                    tournament_name
                )
            self.season.calculate_elo(tournament_name)
            self.season.glicko()
        results = [(team_name, team.elo, team.history) for team_name, team in self.season.teams.items()]
        results = sorted(results, key=lambda x: x[1])[::-1]
        # json.dump(results, open('results.txt', 'w'), indent=4)

def main():
    # Get the season numbers
    chess = Lichess()
    seasons = chess.get_seasons()
    for season in seasons:
        chess.set_season(season)
        chess.get_season()

if __name__ == '__main__':
    main()


#!/usr/bin/env python
import sys
import json
import socket

def main():
    (_, host, ports, context) = sys.argv
    print("CONTEXT: {}".format(json.dumps(json.loads(context), indent=2)))
    print("HOST: {}".format(host))
    print("PORTS: {}".format(json.dumps(json.loads(ports), indent=2)))
    ports = json.loads(ports)
    context = json.loads(context)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, int(ports['8080/tcp'])))
    s.sendall('SAlut les connards'.encode('utf-8'))
    s.close()

if __name__ == "__main__":
    main()


#imports
import pygame
from pygame.locals import *
from pygame import mixer
import pickle
from os import path

#inicio do programa
pygame.mixer.pre_init(44100, -16, 2, 512)
mixer.init()
pygame.init()

temporizador = pygame.time.Clock()
fps = 60
largura = 720
altura = 720
tela = pygame.display.set_mode((largura, altura))

pygame.display.set_caption('Jumping Tile')

#Definir as fontes de textos
fonte_nome = pygame.font.SysFont('Raleway Black Italic', 30)
fonte = pygame.font.SysFont('Bauhaus 93', 70)
fonte_pontuacao = pygame.font.SysFont('Bauhaus 93', 30)

#Definir as variaveis do jogo
tamanho_do_ladrilho = 36
game_over = 0
main_menu = True
level = 1
pontuacao = 0

#Definir cores
branco = (255, 255, 255)
azul = (0, 0, 255)
vermelho = (255, 0, 0)

#CARREGAR IMAGENS:
logo_jogo = pygame.image.load('img/logotipo.png')
logo_escala = pygame.transform.scale(logo_jogo, (350, 350))
lua_img = pygame.image.load('img/lua.png')
lua_escala = pygame.transform.scale(lua_img, (80, 80))
bg_img = pygame.image.load('img/bg_noite.jpg')
reiniciar_imagem = pygame.image.load('img/restart_btn.png')
start_img = pygame.image.load('img/start_btn.png')
exit_img = pygame.image.load('img/exit_btn.png')

#Carregar sons
pygame.mixer.music.load('img/musica_fundo.wav')
pygame.mixer.music.set_volume(0.3)
pygame.mixer.music.play(-1, 0.0, 5000)
clique_som = pygame.mixer.Sound('img/clique_som.wav')
moeda_som = pygame.mixer.Sound('img/moeda_som.wav')
pular_som = pygame.mixer.Sound('img/pulo_som.wav')
game_over_som = pygame.mixer.Sound('img/game_over_som.wav')

#Função para escrever texto na tela
def escrever_texto(text, font, text_cor, x, y):
    img = font.render(text, True, text_cor)
    tela.blit(img, (x, y))

#Função para redefinir o nível
def reset_level(level):
    jogador.reset(100, altura - 130)
    vilao_grupo.empty()
    moedas_grupo.empty()
    plataforma_grupo.empty()
    larva_grupo.empty()
    exit_grupo.empty()

    #carregar dados de nível e criar mundo
    if path.exists(f'level{level}_data'):
        pickle_in = open(f'level{level}_data', 'rb')
        dados_cenario = pickle.load(pickle_in)
    cenario = Mundo(dados_cenario)
    pontuacao_moeda = Moedas(tamanho_do_ladrilho//2, tamanho_do_ladrilho//2)
    moedas_grupo.add(pontuacao_moeda)
    return cenario

class Botoes():
    def __init__(self, x, y, imagem):
        self.imagem = imagem
        self.rect= self.imagem.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.clicked = False

    def Desenhar(self):
        acao = False
        # obtem a posição do mouse
        pos = pygame.mouse.get_pos()

        #verificar as condições do mouse e clicar
        if self.rect.collidepoint(pos):
            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                acao = True
                self.clicked = True
                clique_som.play()
        if pygame.mouse.get_pressed()[0] == 0:
            self.clicked = False
        #desenha o botao
        tela.blit(self.imagem, self.rect)

        return acao

def desenhar_grade():
    for linha in range(0, 6):
        pygame.draw.line(tela, (255, 255, 255), (0, linha * tamanho_do_ladrilho), (largura, linha * tamanho_do_ladrilho))
        pygame.draw.line(tela, (255, 255, 255), (linha * tamanho_do_ladrilho, 0), (linha * tamanho_do_ladrilho, altura))

class Jogador():
    def __init__(self, x, y):
        self.reset(x, y)

    #função para atualizar
    def update(self, game_over):
        dx = 0
        dy = 0
        tempo_caminhada = 5
        debulhar_colisao = 20

        if game_over == 0:
            #Pressionar as teclas:
            key = pygame.key.get_pressed()
            if key[pygame.K_UP] and self.pular == False and self.no_ar == False:
                pular_som.play()
                self.vel_y = - 15
                self.pular = True
            if key[pygame.K_UP] == False:
                self.pular = False
            if key[pygame.K_LEFT]:
                dx -= 5
                self.counter += 1
                self.direção = -1
            if key[pygame.K_RIGHT]:
                dx += 5
                self.counter += 1
                self.direção = 1
            if key[pygame.K_LEFT] == False and key[pygame.K_RIGHT] == False:
                self.counter = 0
                self.index = 0
                if self.direção == 1:
                    self.image = self.imagens_direita[self.index]
                if self.direção == -1:
                    self.image = self.imagens_esquerda[self.index]

            #Fazer a animação
            if self.counter > tempo_caminhada:
                self.counter = 0
                self.index +=1
                if self.index >= len(self.imagens_direita):
                    self.index = 0
                if self.direção == 1:
                    self.image = self.imagens_direita[self.index]
                if self.direção == -1:
                    self.image = self.imagens_esquerda[self.index]

            #Adicionar gravidade
            self.vel_y +=1
            if self.vel_y > 10:
                self.vel_y = 10
            dy += self.vel_y

            #Checar as colisões
            self.no_ar = True
            for ladrilho in cenario.ladrilho_lista:
                #Checar a colisão na direção x
                if ladrilho[1].colliderect(self.rect.x + dx, self.rect.y, self.largura, self.altura):
                    dx = 0

                #checar a colisao na direçao y
                if ladrilho[1].colliderect(self.rect.x, self.rect.y + dy, self.largura, self.altura):
                    #verifique se abaixo do solo e cair
                    if self.vel_y < 0:
                        dy = ladrilho[1].bottom - self.rect.top
                        self.vel_y = 0
                    #verifique se acima do solo e pulando
                    elif self.vel_y >= 0:
                        dy = ladrilho[1].top - self.rect.bottom
                        self.vel_y = 0
                        self.no_ar = False

            #checar colisões com o inimigo
            if pygame.sprite.spritecollide(self, vilao_grupo, False):
                game_over = -1
                game_over_som.play()
            #checar colisões com a larva
            if pygame.sprite.spritecollide(self, larva_grupo, False):
                game_over = -1
                game_over_som.play()

            #checar colisões com a saída
            if pygame.sprite.spritecollide(self, exit_grupo, False):
                game_over = 1

            #checar a colisão com as plataformas
            for plataform in plataforma_grupo:
                #colisão na direção x
                if plataform.rect.colliderect(self.rect.x + dx, self.rect.y, self.largura, self.altura):
                    dx = 0
                #colisão na direção x
                if plataform.rect.colliderect(self.rect.x, self.rect.y + dy, self.largura, self.altura):
                    #verificar abaixo da plataforma
                    if abs((self.rect.top + dy) - plataform.rect.bottom) < debulhar_colisao:
                        self.vel_y = 0
                        dy = plataform.rect.bottom - self.rect.top
                    #verificar acima da plataforma
                    elif abs((self.rect.bottom + dy) - plataform.rect.top) < debulhar_colisao:
                        self.rect.bottom = plataform.rect.top - 1
                        self.no_ar = False
                        dy = 0
                    #mover o jogador para o lado junto com a plataforma
                    if plataform.mover_x != 0:
                        self.rect.x += plataform.mover_direcao

            #atualizar as coordenadas do jogador
            self.rect.x += dx
            self.rect.y += dy

        elif game_over == -1:
            self.image = self.dead_image

            escrever_texto('GAME OVER!', fonte, vermelho, (largura// 2) - 170, altura// 2)
            if self.rect.y > 20:
                self.rect.y -= 5

        #desenhar o jogador na tela
        tela.blit(self.image, self.rect)

        return game_over

    def reset(self, x, y):
        self.imagens_direita = []
        self.imagens_esquerda = []
        self.index = 0
        self.counter = 0
        for num in range(1, 5):
            img_direita = pygame.image.load(rf'img/menina{num}.png') #movimentação do personagem
            img_direita = pygame.transform.scale(img_direita, (27, 54))
            img_esquerda = pygame.transform.flip(img_direita, True, False)
            self.imagens_direita.append(img_direita)
            self.imagens_esquerda.append(img_esquerda)
        self.dead_image = pygame.image.load('img/ghost.png')
        self.image = self.imagens_direita[self.index]
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.largura = self.image.get_width()
        self.altura = self.image.get_height()
        self.vel_y = 0
        self.pular = False
        self.direção = 0
        self.no_ar = True
class Mundo():
    def __init__(self, dados):
        self.ladrilho_lista = []

        #carregar imagens
        ladrilho_imagem = pygame.image.load('img/ladrilho.jpg')
        barra_imagem = pygame.image.load('img/barra.jpg')

        linha_count = 0
        for linha in dados:
            col_count = 0
            for ladrilho in linha:
                if ladrilho == 1:
                    img = pygame.transform.scale(ladrilho_imagem, (tamanho_do_ladrilho, tamanho_do_ladrilho))
                    img_rect = img.get_rect()
                    img_rect.x = col_count * tamanho_do_ladrilho
                    img_rect.y = linha_count * tamanho_do_ladrilho
                    ladrilho = (img, img_rect)
                    self.ladrilho_lista.append(ladrilho)
                if ladrilho == 2:
                    img = pygame.transform.scale(barra_imagem, (tamanho_do_ladrilho, tamanho_do_ladrilho))
                    img_rect = img.get_rect()
                    img_rect.x = col_count * tamanho_do_ladrilho
                    img_rect.y = linha_count * tamanho_do_ladrilho
                    ladrilho = (img, img_rect)
                    self.ladrilho_lista.append(ladrilho)
                if ladrilho == 3:
                    # 25 para que o inimigo não saia do bloco
                    vilao = Inimigo(col_count * tamanho_do_ladrilho - 25, linha_count * tamanho_do_ladrilho)
                    vilao_grupo.add(vilao)
                if ladrilho == 4:
                    plataforma = Plataforma(col_count * tamanho_do_ladrilho, linha_count * tamanho_do_ladrilho, 1, 0)
                    plataforma_grupo.add(plataforma)
                if ladrilho == 5:
                    plataforma = Plataforma(col_count * tamanho_do_ladrilho, linha_count * tamanho_do_ladrilho, 0, 1)
                    plataforma_grupo.add(plataforma)
                if ladrilho == 6:
                    larva = Larva(col_count * tamanho_do_ladrilho, linha_count * tamanho_do_ladrilho + (tamanho_do_ladrilho//2))
                    larva_grupo.add(larva)
                if ladrilho == 7:
                    moedas = Moedas(col_count * tamanho_do_ladrilho + (tamanho_do_ladrilho//2), linha_count * tamanho_do_ladrilho - (tamanho_do_ladrilho//2))
                    moedas_grupo.add(moedas)
                if ladrilho == 8:
                    exit = Exit(col_count * tamanho_do_ladrilho, linha_count * tamanho_do_ladrilho - (tamanho_do_ladrilho//2))
                    exit_grupo.add(exit)
                col_count += 1
            linha_count += 1
    def bloco(self):
        for ladrilho in self.ladrilho_lista:
            tela.blit(ladrilho[0], ladrilho[1])
            #pygame.draw.rect(tela, (255, 255, 255), ladrilho[1], 2)

class Inimigo(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('img/blob.png')
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.mover_direcao = 1
        self.movimento_contador = 0

    def update(self):
        self.rect.x += self.mover_direcao
        self.movimento_contador +=1
        if abs(self.movimento_contador) > 50:
            self.mover_direcao *= -1
            self.movimento_contador *= -1

class Plataforma(pygame.sprite.Sprite):
    def __init__(self, x, y, mover_x, mover_y):
        pygame.sprite.Sprite.__init__(self)
        img = pygame.image.load('img/plataforma_movimento.jpg')
        self.image = pygame.transform.scale(img, (tamanho_do_ladrilho, tamanho_do_ladrilho//2))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.movimento_contador = 0
        self.mover_direcao = 1
        self.mover_x = mover_x
        self.mover_y = mover_y

    def update(self):
        self.rect.x += self.mover_direcao * self.mover_x
        self.rect.y += self.mover_direcao * self.mover_y
        self.movimento_contador +=1
        if abs(self.movimento_contador) > 50:
            self.mover_direcao *= -1
            self.movimento_contador *= -1

class Larva(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        img = pygame.image.load('img/lava.png')
        self.image = pygame.transform.scale(img, (tamanho_do_ladrilho, tamanho_do_ladrilho//2))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

class Exit(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        img = pygame.image.load('img/exit.png')
        self.image = pygame.transform.scale(img, (tamanho_do_ladrilho, int(tamanho_do_ladrilho * 1.5)))
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

class Moedas(pygame.sprite.Sprite):
    def __init__(self, x, y):
        pygame.sprite.Sprite.__init__(self)
        img = pygame.image.load('img/coin.png')
        self.image = pygame.transform.scale(img, (tamanho_do_ladrilho//2, int(tamanho_do_ladrilho//2)))
        self.rect = self.image.get_rect()
        self.rect.center = (x, y)

jogador = Jogador(100, altura - 116)

vilao_grupo = pygame.sprite.Group()
plataforma_grupo = pygame.sprite.Group()
larva_grupo = pygame.sprite.Group()
moedas_grupo = pygame.sprite.Group()
exit_grupo = pygame.sprite.Group()

#Criar moeda fictícia para mostrar a pontuação
pontuacao_moeda = Moedas(tamanho_do_ladrilho // 2, tamanho_do_ladrilho//2)
moedas_grupo.add(pontuacao_moeda)

#carregar dados de nível e criar mundo
if path.exists(f'level{level}_data'):
    pickle_in = open(f'level{level}_data', 'rb')
    dados_cenario = pickle.load(pickle_in)
cenario = Mundo(dados_cenario)

#criar botoes:
reiniciar_botao = Botoes(largura // 2 - 50, altura // 2 + 100, reiniciar_imagem)
start_botao = Botoes(largura // 2 - 300, (altura//2) + 80, start_img)
exit_botao = Botoes(largura // 2 + 55, (altura//2) + 80, exit_img)

#main
#Criar variável para o jogo rodar:
run = True
while run:
    #Corrige a taxa de quadros para garantir consistência ao jogo (mesmo tempo em cada computador)
    temporizador.tick(fps)
    tela.blit(bg_img, (0, 0))
    tela.blit(lua_escala, (50, 60))

    #ativar os botões
    if main_menu == True:
        tela.blit(logo_escala, (180, 20))
        escrever_texto('Feito por: Evellyn Rodrigues', fonte_pontuacao, branco, 185, 650)

        if exit_botao.Desenhar() == True:
            run = False

        if start_botao.Desenhar():
            main_menu = False

    else:
        cenario.bloco()

        if game_over == 0:
            #para parar as animações
            vilao_grupo.update()
            plataforma_grupo.update()
            #atualizaçao de pontuação
            #verifique se a moeda foi coletada
            if pygame.sprite.spritecollide(jogador, moedas_grupo, True):
                pontuacao += 1
                moeda_som.play()
            escrever_texto('X' + str(pontuacao), fonte_pontuacao, branco, tamanho_do_ladrilho - 10, 5)

        vilao_grupo.draw(tela)
        plataforma_grupo.draw(tela)
        larva_grupo.draw(tela)
        moedas_grupo.draw(tela)
        exit_grupo.draw(tela)

        game_over = jogador.update(game_over)

        #se o jogador morrer
        if game_over == -1:
            if reiniciar_botao.Desenhar():
                dados_cenario = []
                jogador.reset(100, altura - 116)
                game_over = 0
                pontuacao -= 1
        try:

            #se o jogador completar o nivel
            if game_over == 1:
                #reiniciar o jogo e ir para o próximo nível
                level += 1
                dados_cenario = []
                cenario = reset_level(level)
                game_over = 0
            escrever_texto(f'NÍVEL: {level}', fonte_pontuacao, branco, tamanho_do_ladrilho + 550, 5)

        except UnboundLocalError:
            escrever_texto('VOCÊ GANHOU!', fonte, vermelho, (largura// 2) - 205, altura// 2)
            escrever_texto(f'Você conseguiu {pontuacao} moedas de um total de 70!', fonte_nome, branco, (largura// 2) - 200, (altura// 2) - 50)
            if reiniciar_botao.Desenhar():
                level = 1
                #reset level
                dados_cenario = []
                cenario = reset_level(level)
                game_over = 0
                pontuacao = 0

    # criar manipulador de eventos para fechar o jogo:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    pygame.display.update()

pygame.quit()


import json

MechanicsDict = {}
for path in ["dat_cla_0", "dat_cla_1", "dat_cla_2"]:
    with open("client/src/assets/extracted/{}.json".format(path), encoding="utf8") as file:
        Skills = json.loads(file.read())
        Mechanics = [s for s in Skills if s['TYPE'] == "mechanics" or s['TYPE'] == "mechanic"]
        for m in Mechanics:
            MechanicsDict[m['EN_NAME']] = {k:v for (k,v) in m.items() if v != "" and v != None}
with open("client/src/assets/data/mechanics.json", "w") as output:
    json.dump(MechanicsDict, output)

Stats = []
for path in ["dat_sta"]:
    with open("client/src/assets/extracted/{}.json".format(path), encoding="utf8") as file:
        StatsData = json.loads(file.read())
        for s in StatsData:
            stat = {}
            for (k, v) in s.items():
                key = k.lower() if k in [
                    "HELM",
                    "BELT",
                    "BRACER",
                    "GLOVE",
                    "SHOULDER",
                    "BOOT",
                    "RING",
                    "AMULET",
                    "CAPE",
                ] else k
                if k == "ARMOR":
                    key = "body"
                stat[key] = v
            Stats.append(stat)
with open("client/src/assets/data/item_stats.json", "w") as output:
    json.dump(Stats, output)


import cv2
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
from keras import Model
from keras.layers import BatchNormalization, Dense, GlobalAveragePooling2D, Input
from keras.optimizers import Adam
from tensorflow.keras.applications.efficientnet import (
    preprocess_input as preprocess_input_efficientnet,
)

def grad_cam(img, model):
    with tf.GradientTape() as tape:
        conv_outputs, predictions = model(preprocess_input_efficientnet(img[None, ...]))
        cls = np.argmax(predictions)
        loss = predictions[:, cls]

    output = conv_outputs[0]
    grads = tape.gradient(loss, conv_outputs)[0]

    gate_f = tf.cast(output > 0, "float32")
    gate_r = tf.cast(grads > 0, "float32")
    guided_grads = gate_f * gate_r * grads

    weights = tf.reduce_mean(guided_grads, axis=(0, 1))

    cam = np.zeros(output.shape[0:2], dtype=np.float32)

    for i, w in enumerate(weights):
        cam += w * output[:, :, i]

    cam = cv2.resize(cam.numpy(), (205, 650))
    cam = np.maximum(cam, 0)
    heatmap = (cam - cam.min()) / (cam.max() - cam.min())

    cam = cv2.applyColorMap(np.uint8(255 * heatmap), cv2.COLORMAP_JET)

    output_image = cv2.addWeighted(
        cv2.cvtColor(img.astype("uint8"), cv2.COLOR_RGB2BGR), 0.5, cam, 1, 0
    )

    plt.subplot(1, 2, 1), plt.imshow(img)
    plt.title("img"), plt.xticks([]), plt.yticks([])
    plt.subplot(1, 2, 2), plt.imshow(output_image)
    plt.title("heatmap"), plt.xticks([]), plt.yticks([])
    plt.show()

def main():
    # make a model
    # chage variables
    shape = (650, 205, 3)
    num_classes = 100

    input_tensor = Input(shape=shape)
    pretrained_model = tf.keras.applications.EfficientNetB0(
        input_tensor=input_tensor, include_top=False, weights="imagenet"
    )

    inputs = pretrained_model.input
    x = pretrained_model.output
    x = GlobalAveragePooling2D()(x)
    output = Dense(num_classes, activation="softmax")(x)

    LAYER_NAME = pretrained_model.layers[-1].name
    model = Model(
        inputs=inputs, outputs=[pretrained_model.get_layer(LAYER_NAME).output, output]
    )

    layer_names = [l.name for l in model.layers]
    # fine-tuning
    idx = layer_names.index("block7a_expand_conv")
    for layer in model.layers[:idx]:
        layer.trainable = False

    # train
    learning_rate = 0.001
    model.compile(
        optimizer=Adam(lr=learning_rate),
        loss="categorical_crossentropy",
        loss_weights=[0, 1],
        metrics=["accuracy"],
    )

    img_path = None
    img = cv2.imread(img_path)
    target_size = shape[:-1][::-1]
    if img.shape[:-1] != target_size:
        img = cv2.resize(img, target_size, interpolation=cv2.INTER_LINEAR)

    grad_cam(img, model)


from discord.ext import commands
import discord
from orjson import loads
import urllib.parse
import asyncio

from utils import Bot

class MyNews(commands.Cog):

    def __init__(self, bot: Bot):
        self.bot = bot

    @commands.group(description="みんなのニュース機能")
    async def mynews(self, ctx: commands.Context):
        if ctx.invoked_subcommand is None:
            return await ctx.send("使用方法が違います。")

    async def input(self, ctx: commands.Context, q: str):
        def check(m):
            return m.author == ctx.author and m.channel == ctx.channel
        await ctx.send(q)
        while True:
            try:
                message = await self.bot.wait_for('message', timeout=180.0, check=check)
            except asyncio.TimeoutError:
                await ctx.channel.send('入力を待機中です。キャンセルする場合は「キャンセルする」と送ってください')
            else:
                if message.content == "キャンセルする":
                    raise TimeoutError()
                await ctx.channel.send("入力を受け付けました。確定する場合は「ok」と送って下さい。やり直す場合は「修正」と送ってください")
                while True:
                    try:
                        message1 = await self.bot.wait_for('message', timeout=180.0, check=check)
                    except asyncio.TimeoutError:
                        await ctx.channel.send('タイムアウトしました。入力をやりなおしてください')
                        break
                    else:
                        if message1.content == "ok":
                            return message
                        elif message1.content == "修正":
                            break

    @mynews.command(description="ニュースを投稿します")
    async def post(self, ctx: commands.Context):
        await ctx.send("投稿を開始します")
        req = {"did": str(ctx.author.id), "diname": str(ctx.author)}
        try:
            req["ti"] = (await self.input(ctx, "ニュースのタイトルを入力してください")).content
            req["val"] = (await self.input(ctx, "ニュースの本文を入力してください")).content
            await ctx.send("送信しています")
            async with self.bot.session.post(
                "http://ysmsrv.wjg.jp/news/sendbydiscord.php", data=req
            ) as resp:
                rpt = await resp.text()
                await ctx.send(rpt)
        except TimeoutError:
            await ctx.send("投稿をキャンセルしました")

    @mynews.command(description="ニュースを検索します")
    async def day(self, ctx: commands.Context, day: str):
        async with self.bot.session.get(
            "https://ysmsrv.wjg.jp/news/timebydiscord.php?input_date=",
            query=urllib.parse.quote_plus(day, encoding='utf-8')
        ) as resp:
            rpt = await resp.json()
        if rpt == []:
            await ctx.reply("すみません。何も見つかりませんでした。日付を確認してみてください。例:2022/07/10")
        else:
            gj = rpt
            vie = discord.ui.View()
            if len(gj) >= 25:
                tmp = []
                for g in gj:
                    if len(tmp) == 24:
                        vie.add_item(SearchList(tmp, self.bot))
                        tmp = []
                    tmp.append(g)
                vie.add_item(SearchList(tmp, self.bot))
            else:
                vie.add_item(SearchList(gj, self.bot))
            await ctx.send("見たい記事を選択してください", view=vie)

    @mynews.command(description="今日のニュースを表示します")
    async def today(self, ctx: commands.Context):
        async with self.bot.session.get("https://ysmsrv.wjg.jp/news/apitoday.php") as resp:
            rpt = await resp.text()
        if rpt == "[]":
            await ctx.reply("すみません。何も見つかりませんでした。もし投稿したいnewsがある場合はnews postコマンドで投稿できます")
        else:
            gj = loads(rpt)
            vie = discord.ui.View()
            if len(gj) >= 25:
                tmp = []
                for g in gj:
                    if len(tmp) == 24:
                        vie.add_item(SearchList(tmp, self.bot))
                        tmp = []
                    tmp.append(g)
                if tmp:
                    vie.add_item(SearchList(tmp, self.bot))
            else:
                vie.add_item(SearchList(gj, self.bot))
            await ctx.send("見たい記事を選択してください", view=vie)

async def getusername(userid: str, bot: Bot):
    async with bot.session.get("https://ysmsrv.wjg.jp/news/" + userid) as resp:
        rpt = await resp.text()
        return rpt

class SearchList(discord.ui.Select):
    def __init__(self, args: list[dict[str, str]], bot: Bot):
        self.its = args
        self.bot = bot
        options = []
        for item in args:
            item["title"] = item["title"] or "No title"
            options.append(discord.SelectOption(label=item["title"], description=''))

        super().__init__(placeholder='', min_values=1, max_values=1, options=options)

    async def callback(self, interaction: discord.Interaction):
        for item in self.its:
            if item["title"] == self.values[0]:
                ebd = discord.Embed(
                    title=item["title"], description=item["text"], color=self.bot.Color
                ).add_field(name="投稿者", value=(await getusername(item["user"], self.bot)))
                await interaction.response.edit_message(embed=ebd)

async def setup(bot: Bot):
    await bot.add_cog(MyNews(bot))


# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup

urlout = 'https://www.youtube.com/'
urlout1 = 'https://www.tumblr.com/'
urlin = 'https://www.zhihu.com/'
urliour = 'http://iour.co/category/jav-uncensored/'
urliourpage = 'http://iour.co/category/jav-uncensored/page/'
proxies = {
        'http': 'http://127.0.0.1:8087',
        'https': 'http://127.0.0.1:8087',
}

"""
r = requests.get(urliour, proxies=proxies, verify=False)
pagefile = open('iour.html', 'w')
pagefile.write(r.text)
"""

pagefile = open('iour.html', 'r')
page = pagefile.read()
soup = BeautifulSoup(page, 'html.parser')
divs = soup.find_all('div', class_='thumb-img')
for div in divs:
	#print div
	a = div.find('a')
	title = a['title']
	pagelink = a['href']
	img = a.find('img')
	imglink = img['src']

	#print title
	#print pagelink
	#print imglink
	#print

last = soup.find('a', class_='last')
maxpage = last['href'].split('/')[-1]#取最后一个
maxpage = int(maxpage)

for i in range(maxpage+1):
	r = requests.get(urliourpage+'%d'%i, proxies=proxies, verify=False)
	pagefile = open('iour.html%d'%i, 'w')
	pagefile.write(r.text)


'''
@Author: Mr Bean
@Date: 2019-05-12 00:44:18
@LastEditors: Mr Bean
@LastEditTime: 2019-05-13 17:06:58
@Description: 自定义静态工具类
'''

import re
from pypinyin import lazy_pinyin, Style

class KTools(object):
    """ 自定义工具类 """

    @staticmethod
    def cnToPinYin(hanZi):
        '''
        汉字转拼音首字母

        Params:
          hanZi - 需要转换的汉字

        Return:
          返回汉字拼音首字母字符串

        '''
        pattern = r"[\(\)\?\*？（） +]"
        tmp_str = ''
        pinyin = lazy_pinyin(hanZi, style=Style.FIRST_LETTER, strict=False)
        for item in pinyin:
            tmp_str += item

        result_str = re.sub(pattern, '', tmp_str)

        return result_str

    @staticmethod
    def dbToDict(val):
        """
        把查询返回的数据处理成列表

        Parameters:
            val - 查询返回的数据

        Returns:
            返回列表(list)

        """
        result_json = []
        for item in val:
            tmp_dict = {"id": item.id, "name": item.name}
            result_json.append(tmp_dict)
        return result_json

if __name__ == '__main__':
    s = '你好(是)?**天*（王）加？ sss+++'
    r = KTools.cnToPinYin(s)
    print(r)


from django.urls import reverse_lazy
from django.views.generic import CreateView, DeleteView, UpdateView, ListView, DetailView
from album.models import Selection, Player
from django.db.models import Value
from django.db.models.functions import Concat

# Create your views here.

## Selection

class SelectionListView(ListView):
    model = Selection

    def get_queryset(self):
        queryset = super().get_queryset()

        # Get the value of the 'query' query parameter
        query = self.request.GET.get('query')

        # Filter the queryset based on the 'query' parameter if provided
        if query:
            queryset = queryset.filter(name__icontains=query)

        return queryset

class SelectionDetailView(DetailView):
    model = Selection

class SelectionCreate(CreateView):
    model = Selection
    fields = '__all__'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # Add additional data to the context dictionary
        additional_data = {
            'type': 'create',
        }

        context.update(additional_data)
        return context

class SelectionUpdate(UpdateView):
    model = Selection
    fields = '__all__'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # Add additional data to the context dictionary
        additional_data = {
            'type': 'update',
        }

        context.update(additional_data)
        return context

class SelectionDelete(DeleteView):
    model = Selection
    success_url = reverse_lazy('selection-list')

## Player

class PlayerListView(ListView):
    model = Player

    def get_queryset(self):
        queryset = super().get_queryset()

        # Get the value of the 'query' query parameter
        query = self.request.GET.get('query')

        # Filter the queryset based on the 'query' parameter if provided
        if query:
            queryset = queryset.annotate(
                full_name=Concat('first_name', Value(' '), 'last_name')
                ).filter(full_name__icontains=query)

        return queryset

class PlayerDetailView(DetailView):
    model = Player

class PlayerUpdate(UpdateView):
    model = Player
    fields = '__all__'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # Add additional data to the context dictionary
        additional_data = {
            'type': 'update',
        }

        context.update(additional_data)
        return context

class PlayerCreate(CreateView):
    model = Player
    fields = '__all__'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        # Add additional data to the context dictionary
        additional_data = {
            'type': 'create',
        }

        context.update(additional_data)
        return context

class PlayerDelete(DeleteView):
    model = Player
    success_url = reverse_lazy('player-list')


#!/usr/bin/env python3
import json
import urllib.request
import argparse

def create_argument_paser():
    parser = argparse.ArgumentParser(description='Send hipchat room notification.')
    parser.add_argument('--token', dest='token', required=True, type=str, help='room notification token')
    parser.add_argument('--url', dest='url', required=True, type=str, help='room notification url')
    parser.add_argument('--from', dest='from_name', required=True, type=str, help='from name')
    parser.add_argument('--color', dest='color', type=str, default='yellow', help='color')
    parser.add_argument('--notify', dest='notify', type=str, default='true', help='enable notify')
    parser.add_argument('--message', dest='message', type=str, help='message')
    parser.add_argument('--message-file', dest='message_file', type=str, help='message file path')
    return parser

def send_room_notification(args):
    url = args.url
    body = {
        'from': args.from_name,
        'message_format': 'text',
        'color': args.color,
        'notify': args.notify,
        'message': args.message
    }
    if not args.message and args.message_file:
        with open(args.message_file, 'r', encoding='utf-8', errors='ignore') as msg_file:
            body['message'] = msg_file.read()
    req = urllib.request.Request(url, json.dumps(body).encode('utf-8'))
    req.add_header('Authorization', 'Bearer ' + args.token)
    req.add_header('Content-Type', 'application/json')
    urllib.request.urlopen(req)

def main():
    parser = create_argument_paser()
    args = parser.parse_args()
    send_room_notification(args)

if __name__ == '__main__':
    main()


#!/usr/bin/python3
"""Driving a simple game framework with
   a dictionary object | Alta3 Research"""

# imports
import pyfiglet
import threading
import os
from rooms import roominfo

title = pyfiglet.figlet_format("Ishindu's fate" ,font = "slant")

def decision():
    print("You took too long! you have suffocated!!")
    os._exit(os.EX_OK)

def showInstructions():
    """Show the game instructions when called"""
    #print a main menu and the commands

    print(title)

    print('''
    ======================================================================
    This is the story of the gods
    Location: SouthEast Nigeria, pre-colonial Alaigbo(igboland).
    ======================================================================
    Commands:
    go [direction]
    get [item]

    # directions[north, south, east, west]
    ''')

def showStatus():
    """determine the current status of the player"""
    #print description
    print(roominfo[currentRoom]['desc'])
    #print the current inventory
    print('Inventory : ' + str(inventory))

#an inventory, which is initially empty
inventory = []
#start the player in the Hall
currentRoom = 'Hall'

showInstructions()

#loop forever
while True:
    showStatus()

    move = ''
    while move == '':
        move = input('>')

    move = move.lower().split(" ", 1)
    os.system('clear')  # clear the screen

    #get moves: player is in the hall and gets key
    #if move == 'get' 'key'
    if move[0] == 'get' and move[1] == 'key':
        #if the room contains key, and the key is the one they want to get
        if "item" in roominfo[currentRoom] and move[1] in roominfo[currentRoom]['item']:
            #add key to their inventory
            inventory += [move[1]]
            #display a helpful message
            print('you have collected a ' + move[1])

            #delete key from the room
            del roominfo[currentRoom]['item']

            print(f"inventory : {inventory}")
            continue
        else:
            print('You cant get ' + move[1] + '!')
            #otherwise, if key isn't there to get

    #if player is in the South_wing and gets map or lantern
    if move[0] == 'get' and move[1] == 'map':
         #if the room contains an item, and the item is the one they want to get
        if "item" in roominfo[currentRoom] and move[1] in roominfo[currentRoom]['item']:
            #add the item to their inventory
            inventory += [move[1]]
            #display a helpful message
            print('you have just acquired a ' + move[1] + '. You glance through and theres directions around the shrine.\n'
            '===================\n'
            '|   MAP oF MBARI  |\n'
            '===================\n'
            'You are in the south wing \n'
            'To the north of the south wing is the Hall \n'
            'To the east of the hall is the east wing \n'
            'To the west of the hall, you will find a secret doorway \n'
            'Find ekwensu before he finds you \n'
            'and pray to your Alusi that you have the means to trap his essence forever \n'
            'to complete this quest is to find your way to the mouth of the sacred grove. \n'
            'BEWARE of TRAPS!!!'
            )
            #delete the item from the room
            del roominfo[currentRoom]['item'][0]

    elif move[0] == 'get' and move[1] == 'lantern':
        if "item" in roominfo[currentRoom] and move[1] in roominfo[currentRoom]['item']:
            #add the item to their inventory
            inventory += [move[1]]
            #display a helpful message
            print('you have collected a ' + move[1])

            #delete the item from the room
            del roominfo[currentRoom]['item'][1]

            print(f"inventory : {inventory}")
        else:
            print('You cant get ' + move[1] + '!')
            #otherwise, if the item isn't there to get
            continue

    ## player go moves
    if move[0] == 'go' :
        if move[1] in roominfo[currentRoom]:
            currentRoom = roominfo[currentRoom][move[1]]
            print(currentRoom)
            if currentRoom == "South_wing" :
                print('the Hall is north of the South_wing')

            elif currentRoom == "Secret_doorway" :
                if 'key' in inventory:
                    print(
                    "================================================================================================================================================================= \n"
                    "You have suddenly found yourself in a crypt and the door quickly snaps shut behind you.It is pitch dark and drafty. \n"
                    "================================================================================================================================================================= " )
                    if 'lantern' in inventory:
                        S = threading.Timer(15.0, decision)
                        print(
                        "================================================================================================================================================================= \n"
                        "luckily you snagged a lantern from the south wing. you turn your latern on and as the light brightens the room, you notice 3 distinctly marked statues. \n "
                        '3 figures are arranged carefully against the crypt\'s interior wall. They are marked boldly with the numbers 6 7 2 respectively. You now have 15 seconds to \n'
                        'figure out the combinations and escape before you suffocate \n'
                        "================================================================================================================================================================= \n")
                        S.start()
                        move = input('>')
                        if move == '276':
                            S.cancel()
                            inventory += ['golden_orb']
                            del roominfo[currentRoom]['item']
                            print("THE GODS ARE WITH YOU! They have bestowed on you the golden_orb with which to banish Ekwensu. You live to fight another day warrior")

                        else:
                            decision()
                        # os._exit will FORCE the program to end!
                    else:
                        print( "================================================================================================================================================================= \n"
                            'You have entered the crypt with no lantern to see around. You could not find the statues that would give you th ecode to the booby trap. You are crushed. GAME OVER!!! \n'
                            "=================================================================================================================================================================")
                        os._exit(os.EX_OK)
                else:
                    print('You cannot go that way. You need a key')
                continue
            elif currentRoom == "East_wing" :
                if 'Ekwensu' in roominfo[currentRoom]['item'] and "golden_orb" in inventory:
                    print('You entered the room Ekwensu dwells in. You have the golden orb in your possession. Ala has granted you the power to seal Ekwensu away in her womb forever... \n'
                    'Thank you for your service Warrior, YOU WIN!')
                    os._exit(os.EX_OK)
                elif 'Ekwensu' in roominfo[currentRoom]['item'] and "golden_orb" not in inventory:
                    print('You entered the room Ekwensu dwells in. You do not have the golden orb with you. You cannot defeat the tricky Ekwensu without the power of Ala. You have failed this \n'
                    'time Warrior. GAME OVER!!')
                    os._exit(os.EX_OK)
            else:
                print("You cannot go " + move[1] + '!')

    ## Define how a player can win
    if currentRoom == 'Grove_mouth' and 'key' in inventory:
        print('You have succeeded in vanquising the evil mascqurade Ekwensu and discovered the ULTRA RARE telepotion... YOU WIN!')
        break


import pyglet
from things import pick_thing, Jar
from background import Background
from cursor import Cursor
import random

class Engine(object):
    state = {'jar_capacity': 10}

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

        self.sprites = pyglet.graphics.Batch()
        self.full_jars = pyglet.graphics.Batch()
        self.background_group = pyglet.graphics.OrderedGroup(0)
        self.things_group = pyglet.graphics.OrderedGroup(1)
        self.cursor_group = pyglet.graphics.OrderedGroup(2)
        self.interface_group = pyglet.graphics.OrderedGroup(3)

        self.score_sprite = pyglet.sprite.Sprite(pyglet.resource.image(
                'jar_full.png'), batch=self.sprites, group=self.interface_group)
        self.score_sprite.x = 20
        self.score_sprite.y = window.height - 20 - self.score_sprite.height

        pyglet.resource.add_font('FredokaOne-Regular.ttf')
        fredoka_one = pyglet.font.load('Fredoka One')

        self.score_label = pyglet.text.Label('0', x=80,
                y=self.score_sprite.y + self.score_sprite.height/2,
                anchor_y='center', font_name='Fredoka One', font_size=16,
                batch=self.sprites, group=self.interface_group)

        self.final_score_label = pyglet.text.Label('0', x=window.width/2,
                y=window.height/2, anchor_x='center', anchor_y='center',
                font_size=32)

        heart_image = pyglet.resource.image('heart.png')
        self.hearts = []
        for i in range(3):
            x = i * 35 + 20
            sprite = pyglet.sprite.Sprite(heart_image, batch=self.sprites,
                    group=self.interface_group)
            sprite.x = x
            sprite.y = 20
            self.hearts.append(sprite)

        self.start_label = pyglet.text.Label('Click to Start', x=window.width/2,
                y=window.height/2 - 40, anchor_x='center', anchor_y='top',
                font_name='Fredoka One', font_size=20)

        self.title = pyglet.resource.image('title.png')
        self.title.anchor_x = self.title.width/2

        splat_image = pyglet.resource.image('splat.png')
        self.splat = pyglet.sprite.Sprite(splat_image)

        self.bg = Background(self)
        self.cursor = Cursor(self)

        @window.event
        def on_draw():
            self.window.clear()
            if self.state['mode'] == 'title':
                self.bg.draw()
                self.start_label.draw()
                self.title.blit(window.width/2, window.height/2)
            elif self.state['mode'] == 'game':
                self.bg.draw()
                self.sprites.draw()
            elif self.state['mode'] == 'lose':
                self.bg.draw()
                self.full_jars.draw()
                self.final_score_label.draw()
                if self.splat.opacity:
                    self.splat.draw()

        @window.event
        def on_mouse_press(x, y, button, modifiers):
            if self.state['mode'] == 'lose':
                self.change_mode('title')
            elif self.state['mode'] == 'title':
                self.change_mode('game')

        @window.event
        def on_mouse_motion(x, y, dx, dy):
            if self.state['mode'] == 'game':
                self.cursor.set_position(dx)

        @window.event
        def on_key_press(symbol, modifiers):
            if symbol == pyglet.window.key.P:
                self.toggle_pause()

        self.change_mode('title')

    def init_game(self):
        pyglet.clock.unschedule(self.update)
        pyglet.clock.unschedule(self.speed_up)
        self.state['things'] = []
        self.state['explode'] = []
        self.state['score'] = 0
        self.state['lives'] = 3
        self.state['add_thing_interval'] = 1.0
        self.state['pickle_probability'] = 1
        self.cursor.set_position(self.window.width/2)
        self.add_thing()
        pyglet.clock.schedule_interval(self.update, 1/60.0)
        pyglet.clock.schedule_interval(self.speed_up, 10)

    def change_mode(self, mode):
        self.state['mode'] = mode
        if mode == 'title':
            self.window.set_mouse_visible(True)
            self.window.set_exclusive_mouse(False)
        elif mode == 'game':
            self.window.set_mouse_visible(False)
            self.window.set_exclusive_mouse(True)
            self.init_game()
        elif mode == 'lose':
            pyglet.clock.unschedule(self.add_thing)
            self.bg.mode = 'normal'
            self.splat.y = 0
            self.splat.opacity = 255
            self.final_score_label.text = 'You filled {0} jar{1}!'.format(
                    self.state['score']/10, 's' if self.state['score']/10 > 1
                    else '')
            self.window.set_mouse_visible(True)
            self.window.set_exclusive_mouse(False)
            self.state['things'] = [Jar(self, batch=self.full_jars) for i in
                    range(self.state['score']/10)]

    def toggle_pause(self):
        self.state['paused'] = True

    def add_thing(self, dt=None):
        self.state['things'].append(pick_thing(self))
        pyglet.clock.schedule_once(self.add_thing,
                random.random() * self.state['add_thing_interval'] * 1.5 +
                self.state['add_thing_interval'])

    def speed_up(self, dt):
        self.state['add_thing_interval'] *= 0.95
        self.state['pickle_probability'] = max(self.state['pickle_probability']
                * 0.9, 0.2)

    def update(self, dt):
        if self.state['mode'] == 'game':
            for thing in self.state['things']:
                thing.update(dt)
            for i in range(len(self.hearts)):
                if self.state['lives'] > i:
                    self.hearts[i].opacity = 255
                else:
                    self.hearts[i].opacity = 0
            self.bg.update(dt)
            self.cursor.update(dt)
            self.score_label.text = str(self.state['score']/10)
        elif self.state['mode'] == 'lose':
            for thing in self.state['things']:
                thing.update(dt)
            if self.splat.opacity > 0:
                self.splat.y -= 100 * dt
                self.splat.opacity = max(0, self.splat.opacity - 255 * dt)


import time

from TeslaVehicleAPI import getVehicleData, wakeVehicle, setScheduledCharging, stopChargeVehicle
from GoogleAPI import getGoogleSheetService
from SendEmail import sendEmail
from SmartClimate import setM3Precondition, setMXPrecondition
from Utilities import isVehicleAtPrimary, isVehicleAtSecondary, getTomorrowTime,getConfig
from Logger import logError
from datetime import timedelta
from collections import namedtuple

config = getConfig()
M3_VIN = config['vehicle']['m3_vin']
MX_VIN = config['vehicle']['mx_vin']
EV_SPREADSHEET_ID = config['google']['ev_spreadsheet_id']
EMAIL_1 = config['notification']['email_1']
EMAIL_2 = config['notification']['email_2']

MX_FULL_CHARGE_RATE_AT_PRIMARY = 25  # (mi/hr)
M3_FULL_CHARGE_RATE_AT_PRIMARY = 37  # (mi/hr)
MX_FULL_CHARGE_RATE_AT_SECONDARY = 20  # (mi/hr)
M3_FULL_CHARGE_RATE_AT_SECONDARY = 30  # (mi/hr)
WAIT_TIME = 30

##
# Called by a crontab to read vehicle range and expected charge
# finish time from a Google Sheet, then call the API to set a time
# for scheduled charging in the vehicle.
#
# author: mjhwa@yahoo.com
##
def scheduleM3Charging(m3_data, mx_data, m3_target_finish_time, mx_target_finish_time):
  try:
    if (m3_data['response']['charge_state']['charging_state'] != 'Complete'):
      # get calculated start time depending on location of cars
      if ((isVehicleAtPrimary(m3_data) == True) and
          (isVehicleAtPrimary(mx_data) == True)):
        start_time = calculateScheduledCharging('m3_primary_shared_charging',
                                                m3_data,
                                                mx_data,
                                                m3_target_finish_time,
                                                mx_target_finish_time)
      elif ((isVehicleAtPrimary(m3_data) == True) and
            (isVehicleAtPrimary(mx_data) == False)):
        start_time = calculateScheduledCharging('m3_primary_full_rate',
                                                m3_data,
                                                mx_data,
                                                m3_target_finish_time,
                                                mx_target_finish_time)
      elif (isVehicleAtSecondary(m3_data)):
        start_time = calculateScheduledCharging('m3_secondary_full_rate',
                                                m3_data,
                                                mx_data,
                                                m3_target_finish_time,
                                                mx_target_finish_time)
      else:
        return

      total_minutes = (start_time.hour * 60) + start_time.minute

      setScheduledCharging(M3_VIN, total_minutes)
      stopChargeVehicle(M3_VIN) # for some reason charging starts sometimes after scheduled charging API is called

      # send email notification
      message = ('The Model 3 is set to charge at '
                 + str(start_time)
                 + '.')
      sendEmail(EMAIL_1, 'Model 3 Set to Charge', message, '', '')
  except Exception as e:
    logError('scheduleM3Charging(): ' + str(e))

def scheduleMXCharging(m3_data, mx_data, m3_target_finish_time, mx_target_finish_time):
  try:
    if (mx_data['response']['charge_state']['charging_state'] != 'Complete'):
      # get calculated start time depending on location of cars
      if ((isVehicleAtPrimary(mx_data) == True) and
          (isVehicleAtPrimary(m3_data) == True)):
        start_time = calculateScheduledCharging('mx_primary_shared_charging',
                                                mx_data,
                                                m3_target_finish_time,
                                                mx_target_finish_time)
      elif ((isVehicleAtPrimary(mx_data) == True) and
            (isVehicleAtPrimary(m3_data) == False)):
        start_time = calculateScheduledCharging('mx_primary_full_rate',
                                                m3_data,
                                                mx_data,
                                                m3_target_finish_time,
                                                mx_target_finish_time)
      elif (isVehicleAtSecondary(mx_data)):
        start_time = calculateScheduledCharging('mx_secondary_full_rate',
                                                m3_data,
                                                mx_data,
                                                m3_target_finish_time,
                                                mx_target_finish_time)
      else:
        return

      total_minutes = (start_time.hour * 60) + start_time.minute

      setScheduledCharging(MX_VIN, total_minutes)
      stopChargeVehicle(MX_VIN) # for some reason charging starts sometimes after scheduled charging API is called

      # send email notification
      message = ('The Model X is set to charge at '
                 + str(start_time)
                 + '.')
      sendEmail(EMAIL_1, 'Model X Set to Charge', message, '', '')
  except Exception as e:
    logError('scheduleMXCharging(): ' + str(e))

##
# Calculates the scheduled charging time for 2 vehicles depending
# on their location, charge state, and finish time.
#
# author: mjhwa@yahoo.com
##
def calculateScheduledCharging(scenario, m3_data, mx_data, m3_target_finish_time, mx_target_finish_time):
  try:
    # Calculate how many miles are needed for charging based on
    # current range and charging % target
    mx_current_range = mx_data['response']['charge_state']['battery_range']
    m3_current_range = m3_data['response']['charge_state']['battery_range']

    mx_max_range = (   mx_data['response']['charge_state']['battery_range']
                    / (mx_data['response']['charge_state']['battery_level'] / 100.0))
    m3_max_range = (   m3_data['response']['charge_state']['battery_range']
                    / (m3_data['response']['charge_state']['battery_level'] / 100.0))

    mx_charge_limit = mx_data['response']['charge_state']['charge_limit_soc'] / 100.0
    m3_charge_limit = m3_data['response']['charge_state']['charge_limit_soc'] / 100.0

    mx_target_range = mx_max_range * mx_charge_limit
    m3_target_range = m3_max_range * m3_charge_limit

    mx_miles_needed = 0
    if (mx_target_range - mx_current_range) > 0: mx_miles_needed = mx_target_range - mx_current_range
    m3_miles_needed = 0
    if (m3_target_range - m3_current_range) > 0: m3_miles_needed = m3_target_range - m3_current_range

    # Calculate scheduled charging time based on location of cars
    if ((scenario == 'mx_primary_shared_charging') or (scenario == 'm3_primary_shared_charging')):
      mx_charging_time_at_full_rate = mx_miles_needed / MX_FULL_CHARGE_RATE_AT_PRIMARY  # hours
      m3_charging_time_at_full_rate = m3_miles_needed / M3_FULL_CHARGE_RATE_AT_PRIMARY  # hours

      mx_start_time_at_full_rate = mx_target_finish_time - timedelta(hours = mx_charging_time_at_full_rate)
      m3_start_time_at_full_rate = m3_target_finish_time - timedelta(hours = m3_charging_time_at_full_rate)

      # Determine if there is a charging time overlap
      Range = namedtuple('Range', ['start', 'end'])
      r1 = Range(start = mx_start_time_at_full_rate, end = mx_target_finish_time)
      r2 = Range(start = m3_start_time_at_full_rate, end = m3_target_finish_time)
      latest_start = max(r1.start, r2.start)
      earliest_end = min(r1.end, r2.end)
      delta = (earliest_end - latest_start).total_seconds()
      overlap = max(0, delta)

      # 1.  Charging times don't overlap
      #
      #                                     Charging at full rate   | 10:00
      # Car 1                           |===========================|
      # Car 2 |======================|
      #        Charging at full rate | 7:00
      if (overlap <= 0):
        if (scenario == 'm3_primary_shared_charging'):
          return m3_start_time_at_full_rate

        if (scenario == 'mx_primary_shared_charging'):
          return mx_start_time_at_full_rate

      else:
      # 2a.  Charging times overlap, fully with different finish times
      #
      #       Charging at
      #       full rate                        Charging at full rate | 10:00
      # Car 1 |============|==============|==========================|
      # Car 2              |==============|
      #             Charging at half rate | 7:00
        if ((mx_target_finish_time != m3_target_finish_time) and (
                  ((mx_start_time_at_full_rate < m3_start_time_at_full_rate) and (mx_target_finish_time > m3_target_finish_time)) or
                  ((m3_start_time_at_full_rate < mx_start_time_at_full_rate) and (m3_target_finish_time > mx_target_finish_time))
                )
           ):
          # Find the longer session
          if (mx_target_finish_time - mx_start_time_at_full_rate).total_seconds() > (m3_target_finish_time - m3_start_time_at_full_rate).total_seconds():
            # Car 2
            m3_charging_time_at_half_rate = m3_miles_needed / (M3_FULL_CHARGE_RATE_AT_PRIMARY / 2)
            m3_start_time = m3_target_finish_time - timedelta(hours = m3_charging_time_at_half_rate)

            # Car 1
            mx_miles_added_at_full_rate = (mx_target_finish_time - m3_target_finish_time).total_seconds() / 60 / 60 * MX_FULL_CHARGE_RATE_AT_PRIMARY
            mx_miles_added_at_half_rate = m3_charging_time_at_half_rate * (MX_FULL_CHARGE_RATE_AT_PRIMARY / 2)
            mx_miles_remaining = mx_miles_needed - mx_miles_added_at_full_rate - mx_miles_added_at_half_rate
            mx_start_time = (mx_target_finish_time
                             - timedelta(hours = mx_miles_added_at_full_rate / MX_FULL_CHARGE_RATE_AT_PRIMARY)
                             - timedelta(hours = mx_miles_added_at_half_rate / (MX_FULL_CHARGE_RATE_AT_PRIMARY / 2))
                             - timedelta(hours = mx_miles_remaining / MX_FULL_CHARGE_RATE_AT_PRIMARY)
                            )

          else:
            # Car 2
            mx_charging_time_at_half_rate = mx_miles_needed / (MX_FULL_CHARGE_RATE_AT_PRIMARY / 2)
            mx_start_time = mx_target_finish_time - timedelta(hours = mx_charging_time_at_half_rate)

            # Car 1
            m3_miles_added_at_full_rate = (m3_target_finish_time - mx_target_finish_time).total_seconds() / 60 / 60 * M3_FULL_CHARGE_RATE_AT_PRIMARY
            m3_miles_added_at_half_rate = mx_charging_time_at_half_rate * (M3_FULL_CHARGE_RATE_AT_PRIMARY / 2)
            m3_miles_remaining = m3_miles_needed - m3_miles_added_at_full_rate - m3_miles_added_at_half_rate
            m3_start_time = (m3_target_finish_time
                             - timedelta(hours = m3_miles_added_at_full_rate / M3_FULL_CHARGE_RATE_AT_PRIMARY)
                             - timedelta(hours = m3_miles_added_at_half_rate / (M3_FULL_CHARGE_RATE_AT_PRIMARY / 2))
                             - timedelta(hours = m3_miles_remaining / M3_FULL_CHARGE_RATE_AT_PRIMARY)
                            )

      # 2b.  Charging times overlap, partially
      #
      #                                        Charging at full rate | 10:00
      # Car 1                      |=======|=========================|
      # Car 2 |====================|=======|
      #        Charging at full            | 7:00
      #        rate                Charging at
      #                            half rate
        elif (mx_target_finish_time > m3_target_finish_time):
          # Car 1
          mx_miles_added_at_full_rate = ((mx_target_finish_time - m3_target_finish_time).total_seconds()
                                          / 60 / 60
                                          * MX_FULL_CHARGE_RATE_AT_PRIMARY)
          mx_miles_remaining = mx_miles_needed - mx_miles_added_at_full_rate
          mx_charging_time_at_half_rate = mx_miles_remaining / (MX_FULL_CHARGE_RATE_AT_PRIMARY / 2)  # hours
          mx_start_time = m3_target_finish_time - timedelta(hours = mx_charging_time_at_half_rate)

          # Car 2
          m3_miles_added_at_half_rate = ((m3_target_finish_time - mx_start_time).total_seconds()
                                          / 60 / 60
                                          * (M3_FULL_CHARGE_RATE_AT_PRIMARY / 2))
          m3_miles_remaining = m3_miles_needed - m3_miles_added_at_half_rate
          m3_charging_time_at_full_rate = m3_miles_remaining / M3_FULL_CHARGE_RATE_AT_PRIMARY  # hours
          m3_start_time = mx_start_time - timedelta(hours = m3_charging_time_at_full_rate)

        elif (mx_target_finish_time < m3_target_finish_time):
          # Car 1
          m3_miles_added_at_full_rate = ((m3_target_finish_time - mx_target_finish_time).total_seconds()
                                          / 60 / 60
                                          * M3_FULL_CHARGE_RATE_AT_PRIMARY)
          m3_miles_remaining = m3_miles_needed - m3_miles_added_at_full_rate
          m3_charging_time_at_half_rate = m3_miles_remaining / (M3_FULL_CHARGE_RATE_AT_PRIMARY / 2)  # hours
          m3_start_time = mx_target_finish_time - timedelta(hours = m3_charging_time_at_half_rate)

          # Car 2
          mx_miles_added_at_half_rate = ((mx_target_finish_time - m3_start_time).total_seconds()
                                          / 60 / 60
                                          * (MX_FULL_CHARGE_RATE_AT_PRIMARY / 2))
          mx_miles_remaining = mx_miles_needed - mx_miles_added_at_half_rate
          mx_charging_time_at_full_rate = mx_miles_remaining / MX_FULL_CHARGE_RATE_AT_PRIMARY  # hours
          mx_start_time = m3_start_time - timedelta(hours = mx_charging_time_at_full_rate)

      # 2c.  Charging times overlap, fully with the same finish times
      #
      # For the longer/earlier start time, calculate the start time based on a part of
      # the charging session being at half rate and another part at full rate.  The session
      # will charge at half rate when the other car begins charging but the difference in
      # miles/charge that starts before the other car will be at full rate.
      #
      #                                  Charging at half rate   | 07:00
      # Car 1                        |===========================|
      # Car 2 |======================|===========================|
      #        Charging at full rate
        elif (mx_target_finish_time == m3_target_finish_time):
          mx_charging_time_at_half_rate = mx_miles_needed / (MX_FULL_CHARGE_RATE_AT_PRIMARY / 2)  # hours
          m3_charging_time_at_half_rate = m3_miles_needed / (M3_FULL_CHARGE_RATE_AT_PRIMARY / 2)  # hours

          mx_start_time_at_half_rate = mx_target_finish_time - timedelta(hours = mx_charging_time_at_half_rate)
          m3_start_time_at_half_rate = m3_target_finish_time - timedelta(hours = m3_charging_time_at_half_rate)

          if (mx_start_time_at_half_rate < m3_start_time_at_half_rate):
            # Car 1 (The shorter/later start time will charge at half rate the entire session)
            m3_start_time = m3_start_time_at_half_rate

            # Car 2
            mx_miles_added_at_half_rate = ((mx_target_finish_time - m3_start_time_at_half_rate).total_seconds()
                                            / 60 / 60
                                            * (MX_FULL_CHARGE_RATE_AT_PRIMARY / 2))
            mx_miles_remaining = mx_miles_needed - mx_miles_added_at_half_rate
            mx_miles_remaining_charging_time_at_full_rate = mx_miles_remaining / MX_FULL_CHARGE_RATE_AT_PRIMARY
            mx_start_time = m3_start_time_at_half_rate - timedelta(hours = mx_miles_remaining_charging_time_at_full_rate)
          else:
            # Car 1 (The shorter/later start time will charge at half rate the entire session)
            mx_start_time = mx_start_time_at_half_rate

            # Car 2
            m3_miles_added_at_half_rate = ((m3_target_finish_time - mx_start_time_at_half_rate).total_seconds()
                                            / 60 / 60
                                            * (M3_FULL_CHARGE_RATE_AT_PRIMARY / 2))
            m3_miles_remaining = m3_miles_needed - m3_miles_added_at_half_rate
            m3_miles_remaining_charging_time_at_full_rate = m3_miles_remaining / M3_FULL_CHARGE_RATE_AT_PRIMARY
            m3_start_time = mx_start_time_at_half_rate - timedelta(hours = m3_miles_remaining_charging_time_at_full_rate)

        if (scenario == 'm3_primary_shared_charging'):
          return m3_start_time

        if (scenario == 'mx_primary_shared_charging'):
          return mx_start_time
    elif (scenario == 'mx_primary_full_rate'):
      mx_start_time = mx_target_finish_time - timedelta(hours = (mx_miles_needed / MX_FULL_CHARGE_RATE_AT_PRIMARY))

      return mx_start_time
    elif (scenario == 'm3_primary_full_rate'):
      m3_start_time = m3_target_finish_time - timedelta(hours = (m3_miles_needed / M3_FULL_CHARGE_RATE_AT_PRIMARY))

      return m3_start_time
    elif (scenario == 'mx_secondary_full_rate'):
      mx_start_time = mx_target_finish_time - timedelta(hours = (mx_miles_needed / MX_FULL_CHARGE_RATE_AT_SECONDARY))

      return mx_start_time
    elif (scenario == 'm3_secondary_full_rate'):
      m3_start_time = m3_target_finish_time - timedelta(hours = (m3_miles_needed / M3_FULL_CHARGE_RATE_AT_SECONDARY))

      return m3_start_time
  except Exception as e:
    print('calcuateScheduledCharging(' + scenario + '): ' + str(e))

##
# Checks to see if the vehicles are plugged in, inferred from the charge
# port door status, and sends an email to notify if it's not.  Also sets
# scheduled charging time to start charging at the calculated date and time.
# Skips if it's not within 0.25 miles from the primary location.
#
# If one of the other cars is in the secondary location, set time charge
# start time based on the secondary charge rate and set the charge start
# time for the one at the primary location to charge at full charge rate.
#
# author: mjhwa@yahoo.com
##
def notifyIsTeslaPluggedIn():
  try:
    # get all vehicle data to avoid repeat API calls
    m3_data = getVehicleData(M3_VIN)
    mx_data = getVehicleData(MX_VIN)

    # get car info
    charge_port_door_open = m3_data['response']['charge_state']['charge_port_door_open']
    battery_level = m3_data['response']['charge_state']['battery_level']
    battery_range = m3_data['response']['charge_state']['battery_range']

    # get charging configuration info
    service = getGoogleSheetService()
    charge_config = service.spreadsheets().values().get(
      spreadsheetId=EV_SPREADSHEET_ID,
      range='Smart Charger!B3:B7'
    ).execute().get('values', [])

    # get climate configuration info
    climate_config = service.spreadsheets().values().get(
      spreadsheetId=EV_SPREADSHEET_ID,
      range='Smart Climate!B20:I24'
    ).execute().get('values', [])
    service.close()

    # check if email notification is set to "on" first
    if (charge_config[1][0] == 'on'):
      # send an email if the charge port door is not open, i.e. not plugged in
      if (charge_port_door_open == False):
        message = ('Your car is not plugged in.  \n\nCurrent battery level is '
                   + str(battery_level)
                   + '%, '
                   + str(battery_range)
                   + ' estimated miles.  \n\n-Your Model 3')
        sendEmail(EMAIL_1, 'Please Plug In Your Model 3', message, '', '')
        #print('send email: ' + message)

    charge_port_door_open = mx_data['response']['charge_state']['charge_port_door_open']
    battery_level = mx_data['response']['charge_state']['battery_level']
    battery_range = mx_data['response']['charge_state']['battery_range']

    # check if email notification is set to "on" first
    if (charge_config[0][0] == 'on'):
      # send an email if the charge port door is not open, i.e. not plugged in
      if (charge_port_door_open == False):
        message = ('Your car is not plugged in.  \n\nCurrent battery level is '
                   + str(battery_level)
                   + '%, '
                   + str(battery_range)
                   + ' estimated miles.  \n\n-Your Model X')
        sendEmail(EMAIL_2,
                  'Please Plug In Your Model X',
                  message, EMAIL_1, '')
        #print('send email: ' + message)

    # set cars for scheduled charging
    m3_target_finish_time = getTomorrowTime(charge_config[4][0])
    mx_target_finish_time = getTomorrowTime(charge_config[3][0])

    scheduleM3Charging(m3_data, mx_data, m3_target_finish_time, mx_target_finish_time)
    scheduleMXCharging(m3_data, mx_data, m3_target_finish_time, mx_target_finish_time)

    # set cabin preconditioning the next morning
    setM3Precondition(m3_data, climate_config)
    setMXPrecondition(mx_data, climate_config)
  except Exception as e:
    logError('notifyIsTeslaPluggedIn(): ' + str(e))
    wakeVehicle(M3_VIN)
    wakeVehicle(MX_VIN)
    time.sleep(WAIT_TIME)
    notifyIsTeslaPluggedIn()

def main():
  notifyIsTeslaPluggedIn()

if __name__ == "__main__":
  main()


import numpy as np
import pandas as pd
from sklearn import linear_model, preprocessing, tree, model_selection
from sklearn.ensemble import RandomForestClassifier

train = pd.read_csv("train.csv", delimiter=",")
test_X = pd.read_csv("test.csv", delimiter=",")
check_y = pd.read_csv("submission3.csv", delimiter=",")
check_y = check_y["Survived"].values
# test = pd.merge(test_y, test_X, on="PassengerId")

def data_cleaner(df):
    df["Age"] = df["Age"].fillna(df["Age"].dropna().median())
    df["Fare"] = df["Fare"].fillna(df["Fare"].dropna().mean())

    df.loc[df["Sex"] == "male", "Sex"] = 0
    df.loc[df["Sex"] == "female", "Sex"] = 1

    df["Embarked"] = df["Embarked"].fillna(df["Embarked"].dropna().mode()[0])
    df.loc[df["Embarked"] == "S", "Embarked"] = 0
    df.loc[df["Embarked"] == "C", "Embarked"] = 1
    df.loc[df["Embarked"] == "Q", "Embarked"] = 2

data_cleaner(train)
data_cleaner(test_X)
# print(train.count(), test_X.count())

train_X = train[["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]].values
train_y = train["Survived"].values
poly = preprocessing.PolynomialFeatures(degree=2)
poly_train_X = poly.fit_transform(train_X)
test_X = test_X[["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]].values
poly_test_X = poly.fit_transform(test_X)

def log_reg(train_X, poly_train_X, train_y, test_X, poly_test_X):
    clf1 = linear_model.LogisticRegression(max_iter=4000)
    fitted_clf1 = clf1.fit(train_X, train_y)

    clf2 = linear_model.LogisticRegression(max_iter=4000)
    fitted_clf2 = clf2.fit(poly_train_X, train_y)

    print(f"[Linear]\nTrain acc: {fitted_clf1.score(train_X, train_y)}")
    print(f"[2nd Order Poly]\nTrain acc: {fitted_clf2.score(poly_train_X, train_y)}")

def tree_clf(train_X, train_y, test_X):
    tree_clf = tree.DecisionTreeClassifier(random_state=1, criterion="entropy", splitter="random",
                                                max_depth=5, min_samples_split=3)
    fitted_tree_clf = tree_clf.fit(train_X, train_y)
    cross_val = model_selection.cross_val_score(fitted_tree_clf, train_X, train_y, cv=10)

    print(f"[Tree Classifier]\nTrain acc: {tree_clf.score(train_X, train_y)}")
    print(f"Cross validation: {cross_val}\nMean: {cross_val.mean()}")
    print(f"Similarity to last submission: {tree_clf.score(test_X, check_y)}")

    prediction = tree_clf.predict(test_X)
    return prediction

def gridsearch_tree(train_X, train_y):
    treeclf_para_grid = {"criterion": list(("gini", "entropy")), "splitter": list(("best", "random")),
                         "max_depth": list((3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)),
                         "min_samples_split": list((2, 3, 4, 5, 6, 7))}
    grid = model_selection.GridSearchCV(tree.DecisionTreeClassifier(random_state=1),
                                        param_grid=treeclf_para_grid, cv=10)
    grid.fit(train_X, train_y)
    print(f"[Grid Search Decision Tree]\n{grid.best_params_}\nBest acc: {grid.best_score_}")

def rand_forest(train_X, train_y, test_X):
    rf_clf = RandomForestClassifier(random_state=1, criterion="entropy",
                                    max_depth=5, min_samples_split=3)
    fitted_rf_clf = rf_clf.fit(train_X, train_y)
    cross_val = model_selection.cross_val_score(fitted_rf_clf, train_X, train_y, cv=10)

    print(f"[Random Forest Classifier]\nTrain acc: {rf_clf.score(train_X, train_y)}")
    print(f"Cross validation: {cross_val}\nMean: {cross_val.mean()}")
    print(f"Similarity to last submission: {rf_clf.score(test_X, check_y)}")

    prediction = rf_clf.predict(test_X)
    return prediction

def gridsearch_rf(train_X, train_y):
    rfclf_para_grid = {"criterion": list(("gini", "entropy")),
                         "max_depth": list((3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)),
                         "min_samples_split": list((2, 3, 4, 5, 6, 7))}
    grid = model_selection.GridSearchCV(RandomForestClassifier(random_state=1),
                                        param_grid=rfclf_para_grid, cv=10)
    grid.fit(train_X, train_y)
    print(f"[Grid Search Random Forest]\n{grid.best_params_}\nBest acc: {grid.best_score_}")

# log_reg(train_X, poly_train_X, train_y, test_X, poly_test_X)
# result = tree_clf(train_X, train_y, test_X)
# gridsearch_tree(train_X, train_y)
result = rand_forest(train_X, train_y, test_X)
# gridsearch_rf(train_X, train_y)
#
# with open("submission5.csv", "w") as fp:
#     fp.write("PassengerId,Survived\n")
#     for i, guess in enumerate(result):
#         fp.write(f"{892+i},{guess}\n")


"""Test the env cli."""

from os import path

from click.testing import CliRunner

from blowhole.cli.env import df, env

CURR_DIR = path.dirname(__file__)
ENV_VALID = path.join(CURR_DIR, "files", "env.yaml")

runner = CliRunner()

def test_env_endpoint() -> None:
    """Test that the env CLI endpoint does something."""
    result = runner.invoke(env)
    assert result.exit_code == 0

def test_env_df() -> None:
    """Test that the Dockerfile endpoint returns the right dockerfile."""
    result = runner.invoke(df, args=str(ENV_VALID))
    print(result.output)
    assert result.exit_code == 0
    assert result.output == "FROM ubuntu\n" \
        "RUN apt update && apt install zsh\n" \
        "CMD zsh\n\n"


import os
from PIL import ImageTk, Image
import imghdr
from natsort import natsorted

class ImagesClass:
    def __init__(self, master, images_group_path: str, image_dims: int):
        self.master=master
        self.images_list = []
        self.images_locs_list = []

        self.image_group_path = images_group_path

        self.images_label_grid_kwargs = {
            "row": 0, "column": 1, "columnspan": 1
        }
        self.file_path = "file_path"
        self.image_label = None
        self.images_number_label = None

        self.total_number_images = 0
        self.current_image_number = 0

        self.current_image_path = ""

        self.current_image = None
        self.current_image_name = ""
        self.image_dim = image_dims

    def order_images(self):
        self.images_locs_list = natsorted(self.images_locs_list)

    def pull_image_files(self):
        self.images_locs_list = [
            os.path.join(self.image_group_path, img)
            for img in os.listdir(self.image_group_path)
            if imghdr.what(os.path.join(self.image_group_path, img))
        ]

        if len(self.images_locs_list) == 0:
            return False

        self.total_number_images = len(self.images_locs_list)
        self.order_images()

    def create_image_list(self):
        for image_loc in self.images_locs_list:
            try:
                image = ImageTk.PhotoImage(Image.open(image_loc).resize((self.image_dim, self.image_dim)))
                self.images_list.append(image)
            except OSError as err:
                if "truncated" in err:
                    os.remove(image_loc)

    def get_starting_image_data(self):
        if len(self.images_locs_list) == 0:
            return False
        self.current_image_number = len(self.images_locs_list) - (len(self.images_locs_list) // 3)
        self.current_image_path = self.images_locs_list[self.current_image_number]
        self.current_image = self.images_list[self.current_image_number]
        self.current_image_name = os.path.split(self.current_image_path)[-1]
        return True

    def get_image_data(self):
        self.pull_image_files()
        self.create_image_list()

        if self.get_starting_image_data():
            return (self.current_image_name, self.current_image_path, self.current_image, self.current_image_number,
                    self.images_list, self.images_locs_list, self.total_number_images)
        return False

    def get(self):
        return self


# from douban_client import DoubanClient
import time
import requests
import pprint

from sqlalchemy import text
from model import db, Movie

# 根据电影名字获取相关的电影信息
# 只需要调用get_movie_detail（）即可

BASE_API_URL = 'https://api.douban.com'
QUERY_MOVIE_URL = BASE_API_URL + '/v2/movie/search?'
GET_MOVIE_DETAIL_URL = BASE_API_URL + '/v2/movie/subject/'
GET_MOVIE_IN_THEATHER_URL = BASE_API_URL + '/v2/movie/in_theaters'
MAX_DESCRIPTION_LENGTH = 256

def get_movie_id(movieName):
    """ 获取电影在豆瓣上的ID, 同时
    Args
        str : movieName
    Retruns
        -1 : 没有这个名字的电影
        ID : 该电影在豆瓣上的ID，用于其他函数
    """
    query_params = {"q": movieName}
    tmpRes = requests.get(QUERY_MOVIE_URL, params=query_params)
    if tmpRes.status_code == 200:
        queryRes = tmpRes.json()
        # pprint.pprint(queryRes)
        if int(queryRes['total']) > 0 and queryRes['subjects'][0]['title'] == movieName:
            return str(queryRes['subjects'][0]['id'])
    return -1

def get_cast_name(cast_arr, director_arr):
    """ 处理主演演员格式
    Args
        array : cast_arr, director_arr
    Retruns
        string:
    """
    namesArr = []
    for actor in cast_arr:
        namesArr.append(actor['name'])
    for director in director_arr:
        namesArr.insert(0, str(director["name"] + "（导演）"))
    return "|".join(namesArr)

def handle_movie_record(tmpRes):
    """
    将豆瓣的返回的电影信息，提取出本地服务器需要的信息
    :param subject:
    :return: db_movie_record
    """
    finRes = {}
    finRes.update({'movieType': '|'.join(tmpRes['genres'])})
    finRes.update({'movieName': tmpRes['title']})
    # poster_url
    finRes.update({'poster': tmpRes['images']['small']})
    # finRes.update({'duration': '|'.join(tmpRes['duration'])})
    finRes.update({'primaryActors': get_cast_name(tmpRes['casts'], tmpRes['directors'])})
    finRes.update({'rating': tmpRes['rating']['average']})
    finRes.update({'description': tmpRes['summary'][: MAX_DESCRIPTION_LENGTH]})
    # finRes.update({'description': tmpRes['summary']})
    return finRes

def get_movie_detail(movieName):
    """根据电影名字返回相应的详细信息
    Args:
        电影名字
    Returns:
        dict 类型：
            如果没有该电影：空dict
            电影存在：返回电影信息,
            example:
            {
                "name": "超时空同居",
                "rating": 5,
                "duration": 101,  // 豆瓣上文档上有，但是返回的结果上没看到
                "poster": "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2520331478.webp",
                "movieType": "喜剧|爱情|奇幻",
                "primaryActors": "苏伦(导演)/雷佳音/佟丽娅/张衣",
                "description": "来自2018年谷小焦（佟丽娅 饰）与1999年陆鸣（雷佳音 饰），两人时空重叠意外住在同一个。。。
                "showtime": "2018-05-18", // 跟时长一样
              }
    """
    finRes = {}
    tarMovieId = get_movie_id(movieName)
    if tarMovieId != -1 :
        tmpRes = requests.get(GET_MOVIE_DETAIL_URL + str(tarMovieId)).json()
        if len(tmpRes) != 0 :
            finRes = handle_movie_record(tmpRes)
        # pprint.pprint(tmpRes)
    return finRes

def check_movie_conflict(movieName):
    """
    检查该电影是否已经在数据库中
    :param movieName:
    :return: True -> 已经存在, False -> 不存在
    """
    pass

def init_movie_table():
    """
    从豆瓣网站查询部分电影信息，存储进本地数据库中
    :return: True -> 初始化成功
    """
    # in_theaters_list = []
    tmpRes = requests.get(GET_MOVIE_IN_THEATHER_URL)
    if tmpRes.status_code == 200:
        time.sleep(1)
        queryRes = tmpRes.json()
        # pprint.pprint(queryRes)
        # 电影数目
        n = int(queryRes['total'])
        movies = queryRes['subjects']
        print(movies)
        for movie in movies:
            # in_theaters_list.append(queryRes['subjects']['title'])
            movieName = movie['title']
            movieInfo = get_movie_detail(movieName)
            movieRecord = Movie(**movieInfo)
            isExists = Movie.query.filter_by(movieName=movieName).first() != None
            if isExists:
                print("{0} Alread in database".format(movieName))
                continue
            try:
                db.session.add(movieRecord)
                db.session.commit()
                print(movieRecord.movieName + " " + str(movieRecord.movieID))
            except:
                print(movieRecord.movieName + " Error Occurs !! " )
        return True
    print("fail to get in-theater movies")
    return False

if __name__ == "__main__":
    # test the moudule function
    init_movie_table()
    # fuzzy_search("阿飞")
    # pprint.pprint(getMovieDetail("超时空同居"))


from . import utils
from bpy.props import *
from bpy.types import (Panel,Menu,Operator,PropertyGroup,AddonPreferences)
from pathlib import Path
import bpy
import json
import os
import random

def pose_file_path():
    path = "~/daz_pos_files.json"
    filepath = os.path.expanduser(path).replace("\\", "/")
    return filepath.rstrip("/ ")

class DiffHelperPreferences(AddonPreferences):
    bl_idname = __name__

    def draw(self, context):
        layout = self.layout
        layout.label(text="Diffeomorphic Helper Preferences")
        layout.prop(self, "pose_files_path")

class DiffHelperRandomPose(Operator):
    bl_idname = "vsw.random_pose"
    bl_label = "Diff Helper"
    bl_description = "Diff Helper"
    bl_options = { "REGISTER", "UNDO" }

    def execute(self, context):

        with open(pose_file_path()) as f:
            files = json.load(f)
            index = random.randint(0, len(files) - 1)
            print(files[index])

            bpy.ops.daz.import_pose(daz_pose_file=files[index])
        return{'FINISHED'}
class DiffHelperResetRigifyControls(Operator):
    bl_idname = "vsw.reset_rigify_controls"
    bl_label = "Diff Helper"
    bl_description = "Diff Helper"
    bl_options = { "REGISTER", "UNDO" }

    fingers: BoolProperty()

    def execute(self, context):
        rigid = context.active_object.data['rig_id']
        def fk2ik():
                getattr(bpy.ops.pose, "rigify_limb_ik2fk_" + rigid)(
                'INVOKE_DEFAULT',
                prop_bone=prop_bone,
                fk_bones=fk_bones,
                ik_bones=ik_bones,
                ctrl_bones=ctrl_bones,
                extra_ctrls=extra_ctrls)
        pose_bones = context.active_object.pose.bones

        if not self.fingers:
            # footR
            prop_bone = 'thigh_parent.R'
            fk_bones = '["thigh_fk.R", "shin_fk.R", "foot_fk.R"]'
            ik_bones = '["thigh_ik.R", "MCH-shin_ik.R", "MCH-thigh_ik_target.R"]'
            ctrl_bones = '["thigh_ik.R", "thigh_ik_target.R", "foot_ik.R"]'
            extra_ctrls = '["foot_heel_ik.R", "foot_spin_ik.R"]'
            fk2ik()

            # footL
            prop_bone = 'thigh_parent.L'
            fk_bones = '["thigh_fk.L", "shin_fk.L", "foot_fk.L"]'
            ik_bones = '["thigh_ik.L", "MCH-shin_ik.L", "MCH-thigh_ik_target.L"]'
            ctrl_bones = '["thigh_ik.L", "thigh_ik_target.L", "foot_ik.L"]'
            extra_ctrls = '["foot_heel_ik.L", "foot_spin_ik.L"]'
            fk2ik()

            # handR
            prop_bone = 'upper_arm_parent.R'
            fk_bones = '["upper_arm_fk.R", "forearm_fk.R", "hand_fk.R"]'
            ik_bones = '["upper_arm_ik.R", "MCH-forearm_ik.R", "MCH-upper_arm_ik_target.R"]'
            ctrl_bones = '["upper_arm_ik.R", "upper_arm_ik_target.R", "hand_ik.R"]'
            extra_ctrls = '[]'
            fk2ik()

            # handL
            prop_bone = 'upper_arm_parent.L'
            fk_bones = '["upper_arm_fk.L", "forearm_fk.L", "hand_fk.L"]'
            ik_bones = '["upper_arm_ik.L", "MCH-forearm_ik.L", "MCH-upper_arm_ik_target.L"]'
            ctrl_bones = '["upper_arm_ik.L", "upper_arm_ik_target.L", "hand_ik.L"]'
            extra_ctrls = '[]'
            fk2ik()

            pose_bones['upper_arm_parent.L']['IK_FK'] = 0
            pose_bones['upper_arm_parent.R']['IK_FK'] = 0
            pose_bones['thigh_parent.L']['IK_FK'] = 0
            pose_bones['thigh_parent.R']['IK_FK'] = 0
        else:
            for lr in ('R', 'L'):
                for finger in ('thumb', 'f_index', 'f_middle', 'f_ring', 'f_pinky'):
                    output_bones = '["' + finger + '.01_ik.' + lr + '"]'
                    input_bones = '["' +finger + '.01.' + lr + '.001"]'
                    ctrl_bones = '["' + finger + '.01_master.' + lr + '", "' + finger + '.01.' + lr + '", "' + finger + '.02.' + lr + '", "' + finger + '.03.' + lr + '", "' + finger + '.01.' + lr + '.001"]'
                    locks = (False, True, True)
                    tooltip = 'IK to FK'
                    print(ctrl_bones)

                    getattr(bpy.ops.pose, "rigify_generic_snap_" + rigid)(
                        'INVOKE_DEFAULT',
                        output_bones=output_bones,
                        input_bones=input_bones,
                        ctrl_bones=ctrl_bones,
                        locks=locks,
                        tooltip=tooltip)
                    pose_bones[finger + '.01_ik.' + lr]['FK_IK'] = 1

        return{'FINISHED'}

class DiffHelperSetRandomPosePath(Operator):
    bl_idname = "vsw.random_pose_path"
    bl_label = "Diff Helper"
    bl_description = "Diff Helper"
    bl_options = { "REGISTER", "UNDO" }

    directory: StringProperty(subtype="DIR_PATH")

    def invoke(self, context, event):
        print("invoked!")
        context.window_manager.fileselect_add(self)

        return{'FINISHED'}

    def execute(self, context):
        pose_files = list(Path(self.directory).rglob("*.duf"))
        pose_files = [ str(x) for x in pose_files ]
        with open(pose_file_path(), 'w+') as f:
            f.write(json.dumps(pose_files))
        return{'FINISHED'}

class DiffHelperSoloLayers(Operator):
    bl_idname = "vsw.solo_pose_layers"
    bl_label = "Diff Helper"
    bl_description = "Diff Helper"
    bl_options = { "REGISTER", "UNDO" }
    layer_indices: StringProperty()
    def execute(self, context):
        indices_str = self.layer_indices.split(',')
        indices = set([ int(s) for s in indices_str if s])
        view_layers = context.active_object.data.layers
        for i in range(0, 31):
            view_layers[i] = i in indices
        return{'FINISHED'}

class DiffHelperResetPose(Operator):
    bl_idname = "vsw.reset_pose"
    bl_label = "Diff Helper"
    bl_description = "Diff Helper"
    bl_options = { "REGISTER", "UNDO" }
    layer_indices: StringProperty()
    def execute(self, context):
        bones = context.active_object.pose.bones

        for bone in bones:
            layer = 0
            for i in range(0, 31):
                if context.active_object.data.bones[bone.name].layers[i]:
                    layer = i
                    break

            if layer < 31 - 4:
                bone.location = (0, 0, 0)
                bone.rotation_euler = (0, 0, 0)
                bone.scale = (1, 1, 1)

        bones['upper_arm_parent.L']['IK_FK'] = 0
        bones['upper_arm_parent.R']['IK_FK'] = 0
        bones['thigh_parent.L']['IK_FK'] = 0
        bones['thigh_parent.R']['IK_FK'] = 0
        for lr in ('R', 'L'):
            for finger in ('thumb', 'f_index', 'f_middle', 'f_ring', 'f_pinky'):
                bones[finger + '.01_ik.' + lr]['FK_IK'] = 0
        return{'FINISHED'}

class DiffHelperToggleShading(Operator):
    bl_idname = "vsw.toggle_shading"
    bl_label = "Diff Helper"
    bl_description = "Diff Helper"
    bl_options = { "REGISTER", "UNDO" }
    layer_indices: StringProperty()
    def execute(self, context):
        amat = context.active_object
        meshes = [ c for c in amat.children if c.type == 'MESH']
        for mesh in meshes:
            materials = mesh.data.materials
            for i in range(len(materials)):
                m = materials[i]
                if m.name.endswith('.Flat'):
                    materials[i] = bpy.data.materials[m.name.replace('.Flat', '.Shaded')]
                if m.name.endswith('.Shaded'):
                    materials[i] = bpy.data.materials[m.name.replace('.Shaded', '.Flat')]

        return{'FINISHED'}

class DiffHelperToggleModifierVisbility(Operator):
    bl_idname = "vsw.toggle_modifier_visbility"
    bl_label = "Diff Helper"
    bl_description = "Diff Helper"
    bl_options = { "REGISTER", "UNDO" }
    modifier_names: StringProperty()
    def execute(self, context):
        obj = context.active_object
        meshes = [ c for c in obj.children if c.type == 'MESH']
        modifiers = self.modifier_names.split(',')
        for mesh in meshes:
            for modifier in mesh.modifiers:
                if modifier.name in modifiers:
                    modifier.show_viewport = not modifier.show_viewport
        return{'FINISHED'}

class DiffHelperPanel_PT_PANEL(Panel):
    bl_idname = "DiffHelper_PT_SidePanel"
    bl_label = "Diff Helper"
    bl_category = "Item"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"

    @classmethod
    def poll(self, context):
        try:
            return not not context.active_object.data.get("rig_id")
        except (AttributeError, KeyError, TypeError):
            return False

    pose_files_path: StringProperty(
        name="Pose Files Path",
        subtype="DIR_PATH"
    )

    def draw(self, context):
        layout = self.layout

        col = layout.column()

        col.label(text="Settings")
        box = col.box()
        row = box.row()
        row.operator("vsw.random_pose_path", icon = "FILE_FOLDER", text = "Select Pose Directory")

        col.label(text="Toggle View Layers")
        box = col.box()
        row = box.row()
        props = row.operator("vsw.solo_pose_layers", text="Hide All")
        props.layer_indices = '0'
        row = box.row()
        props = row.operator("vsw.solo_pose_layers", text="Show All")
        props.layer_indices = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19'
        row = box.row()
        props = row.operator("vsw.solo_pose_layers", text="Primay with Fingers")
        props.layer_indices = '3,4,7,10,13,16,5,6,19'
        row = box.row()
        props = row.operator("vsw.solo_pose_layers", text="Primary Bones")
        props.layer_indices = '3,4,7,10,13,16'
        row = box.row()
        props = row.operator("vsw.solo_pose_layers", text="Tweek Bones")
        props.layer_indices = '4,5,9,12,15,18'
        row = box.row()
        props = row.operator("vsw.solo_pose_layers", text="Fingers")
        props.layer_indices = '5'
        row = box.row()
        props = row.operator("vsw.solo_pose_layers", text="Fingers Details")
        props.layer_indices = '6,19'

        col.label(text="Toggle Mesh Visibilities")
        box = col.box()
        row = box.row()
        props = row.operator("vsw.toggle_modifier_visbility", text="Head")
        props.modifier_names = 'vis_mask_head'
        row = box.row()
        props = row.operator("vsw.toggle_modifier_visbility", text="Arms")
        props.modifier_names = 'vis_mask_arms'
        row = box.row()
        props = row.operator("vsw.toggle_modifier_visbility", text="Legs")
        props.modifier_names = 'vis_mask_legs'
        row = box.row()
        props = row.operator("vsw.toggle_modifier_visbility", text="Hands and Feet")
        props.modifier_names = 'vis_mask_hands'
        row = box.row()

        col.label(text="Shading")
        box = col.box()
        row = box.row()
        row.operator("vsw.toggle_shading", icon = "SHADING_RENDERED", text = "Toggle Shading")

        col.label(text="Load Pose")
        box = col.box()
        row = box.row()
        props = row.operator("vsw.reset_rigify_controls", icon = "SNAP_ON", text = "Arms IK to FK")
        props.fingers = False
        row = box.row()
        props = row.operator("vsw.reset_rigify_controls", icon = "SNAP_ON", text = "Fingers IK to FK")
        props.fingers = True
        row = box.row()
        row.operator("vsw.random_pose", icon = "ARMATURE_DATA", text = "Load Random Pose")
        row = box.row()
        row.operator("vsw.reset_pose", icon = "FILE_REFRESH", text = "Reset Pose")

def register():
    utils.register_quietly(DiffHelperPreferences)
    utils.register_quietly(DiffHelperRandomPose)
    utils.register_quietly(DiffHelperSetRandomPosePath)
    utils.register_quietly(DiffHelperResetRigifyControls)
    utils.register_quietly(DiffHelperPanel_PT_PANEL)
    utils.register_quietly(DiffHelperSoloLayers)
    utils.register_quietly(DiffHelperResetPose)
    utils.register_quietly(DiffHelperToggleShading)
    utils.register_quietly(DiffHelperToggleModifierVisbility)

def unregister():
    utils.unregister_quietly(DiffHelperPreferences)
    utils.unregister_quietly(DiffHelperRandomPose)
    utils.unregister_quietly(DiffHelperSetRandomPosePath)
    utils.unregister_quietly(DiffHelperResetRigifyControls)
    utils.unregister_quietly(DiffHelperPanel_PT_PANEL)
    utils.unregister_quietly(DiffHelperSoloLayers)
    utils.unregister_quietly(DiffHelperResetPose)
    utils.unregister_quietly(DiffHelperToggleShading)
    utils.unregister_quietly(DiffHelperToggleModifierVisbility)