#!/bin/env python
import os,sys
from datetime import datetime, timedelta
import numpy as np
from scipy import interpolate
from scipy.io import netcdf
import pygrib

def read_grib(fnl_path, ndays, u10, v10):
	lon_lat = np.genfromtxt('/fvcom-exec/input/nele_lon_lat.txt',dtype='f')

	file_list = [ fnl_path + "gfs.pgrb2.0p25.f"+ "{0:03d}".format(i) +".grib2" for i in range(0, ndays*24+6, 6 ) ]
	for i in range(len(file_list)):
		grb = pygrib.open(file_list[i])
		print("read " + file_list[i])
		U10 = grb.select(name='U component of wind')[0]  # (721, 1440)
		V10 = grb.select(name='V component of wind')[0]
		lat, lon = U10.latlons()
		#--------------------grid lat lon ------------point lat lon
		u10 = interpolate.interpn((lat[::-1,0], lon[0]), U10.values[::-1,:], lon_lat[:,::-1], method='linear')
		v10 = interpolate.interpn((lat[::-1,0], lon[0]), U10.values[::-1,:], lon_lat[:,::-1], method='linear')
		if i == 0:
			u10_r = u10
			v10_r = v10
		else:
			u10_r =  np.vstack((u10_r, u10))
			v10_r =  np.vstack((v10_r, v10))
	print(u10_r.shape)
	return u10_r, v10_r

# -- MAIN
if __name__ == '__main__':
	global nele_path,nnele,nnode
	nele_path = "/fvcom-exec/input/nele_lon_lat.txt"
	nnode = 2361
	nnele = 4448
	if len(sys.argv) < 4:
	  print('Usage: fnl2fvcom_uv.py <fnl_path> <ndays> <start_ymdh>')
	  sys.exit(0)
	fnl_path = sys.argv[1]
	ndays = int(sys.argv[2])
	ymdh  = sys.argv[3]

	starttime = datetime.strptime(ymdh,"%Y%m%d%H")
	timeref = datetime(1858,11,17)

	times = [ starttime + timedelta(hours=i) for i in range(0, ndays*24+6, 6 ) ]
	times = [ (i - timeref  ).total_seconds()/(60*60*24) for i in times ]

	time_org  = np.array(times, dtype='f4')
	Itime_org = np.array(times, dtype='i4')
	Itime2_org= np.round(( (time_org%1)*24*3600*1000)/(3600*1000))*(3600*1000)

	u10_r = np.zeros(time_org.shape[0],dtype='f')
	v10_r = np.zeros(time_org.shape[0],dtype='f')
	u10_r, v10_r = read_grib(fnl_path, ndays, u10_r, v10_r)

	f = netcdf.netcdf_file('uv_force.nc', 'w')
	f.source = "fvcom grid (unstructured) surface forcing"

	f.createDimension('time', None)
	f.createDimension('node', nnode )
	f.createDimension('nele', nnele )

	time = f.createVariable('time', 'f', ('time',))
	time[:] = time_org
	time.long_name = "time"
	time.units = 'days since 1858-11-17 00:00:00'
	time.format = "modified julian day (MJD)"
	time.time_zone = "UTC"
	Itime = f.createVariable('Itime', 'i', ('time',))
	Itime[:] = Itime_org
	Itime.units = 'days since 1858-11-17 00:00:00'

	Itime2 = f.createVariable('Itime2', 'i', ('time',))
	Itime2[:] = Itime2_org.astype('i4')
	Itime2.units = 'msec since 00:00:00'

	u10    = f.createVariable('U10', 'f', ('time','nele',))
	u10[:] = u10_r[:]
	u10.long_name = "Eastward 10-m Velocity"
	u10.units = "m/s"
	v10    = f.createVariable('V10', 'f', ('time','nele',))
	v10[:] = v10_r[:]
	v10.long_name = "Northward 10-m Velocity"
	v10.units = "m/s"

	f.close()


import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import process as pro

P = 4e-6;
A = 300; # cm2
dp = 20; # bar
alfa = 0.01;
F0 = 0.05; # L/min
V_loop = 0.05

try:
    R1 = float(input('Rejection of R compound: '))/100
    R2 = float(input('Rejection of S compound: '))/100
    ratio = float(input("Ratio of R solute in the feed (50 for racemic): "))/100
except ValueError:
    print("Invalid input. Please enter rejection values equal to or lower than 100%")
    exit(1)

if R1 > 1 or R2 > 1:
    print("Invalid input. Please enter rejection values equal to or lower than 100%")
    exit(2)

if ratio > 1 or ratio < 0:
    print("Invalid input. Please enter a ratio value between 0 and 100% (excluding 0 and 100%)")
    exit(3)

#R1 = 0.95
#R2 = 0.9

c0 = [2*ratio,2*(1-ratio)]

theta = np.linspace(0,1,100)
ee_Rr = np.array([float(0)]*100)
ee_Rp = np.array([float(0)]*100)
ee_Sr = np.array([float(0)]*100)
ee_Sp = np.array([float(0)]*100)
eta_Rr = np.array([float(0)]*100)
eta_Rp = np.array([float(0)]*100)
eta_Sr = np.array([float(0)]*100)
eta_Sp = np.array([float(0)]*100)

j = 0
for i in theta:
    if i == 1 and R1 == 1:
        ee_Rr[j] = 100
    else:
        cc_Rr = (c0[0]/c0[1])*(1-i*R2)/(1-i*R1) # problem: i = 1, R1 = 1
        ee_Rr[j] = 100*(cc_Rr-1)/(cc_Rr+1)

    if R2 == 1:
        ee_Rp[j] = -100
    else:
        cc_Rp = cc_Rr*(1-R1)/(1-R2) # problem: R2 = 1
        ee_Rp[j] = 100*(cc_Rp-1)/(cc_Rp+1)

    ee_Sr[j] = -ee_Rr[j]
    ee_Sp[j] = -ee_Rp[j]

    if i == 1 and R1 == 1:
        eta_Rr[j] = 100
        eta_Rp[j] = 0
    else:
        eta_Rr[j] = 100*(1-i)/(1-R1*i) # problem: i = 1, R1 = 1
        eta_Rp[j] = 100*i*(1-R1)/(1-i*R1) # problem: i = 1, R1 = 1

    if i == 1 and R2 == 1:
        eta_Sr[j] = 100
        eta_Sp[j] = 0
    else:
        eta_Sr[j] = 100*(1-i)/(1-R2*i) # problem: i = 1, R2 = 1
        eta_Sp[j] = 100*i*(1-R2)/(1-i*R2) # problem: i = 1, R2 = 1
    j += 1

R = [R1,R2]
tspan = np.linspace(0,10000,1000)
z = 0.99

cel = pro.cell(P)
system = pro.sys(cel,True)
system.ractype = 'srrz'
system.z = z

theta2 = np.linspace(0.01,1,99)
ee2R = np.array([float(0)]*99)
eta2R = np.array([float(0)]*99)
ee2S = np.array([float(0)]*99)
eta2S = np.array([float(0)]*99)

j = 0
for i in theta2:
    # system.set_flow(F0,alfa)
    system.set_flow_cut(F0,i)
    system.initial_cell.R = R
    system.initial_cell.c0 = c0
    system.initial_cell.V_loop = V_loop
    system.run_sys(tspan)
    ee2S[j] = 100*((system.res[-1,1]-system.res[-1,0])/(system.res[-1,0]+system.res[-1,1]))
    ee2R[j] = -ee2S[j]
    eta2S[j] = 100*(system.res[-1,1]*system.initial_cell.Fp/(F0*c0[1]))
    eta2R[j] = 100*(system.res[-1,0]*system.initial_cell.Fp/(F0*c0[1]))
    j += 1

initial_cel = pro.cell(P)
system_cas = pro.sys(initial_cel,False)
per_cel = pro.cell(P)
system_cas.per_cells.append(per_cel)

system_cas.initial_cell.R = R
system_cas.initial_cell.c0 = c0
system_cas.initial_cell.V_loop = V_loop

theta3 = np.linspace(0.01,1,99)
ee3Rr = np.array([float(0)]*99)
ee3Sr = np.array([float(0)]*99)
ee3Rp = np.array([float(0)]*99)
ee3Sp = np.array([float(0)]*99)
eta3Rr = np.array([float(0)]*99)
eta3Sr = np.array([float(0)]*99)
eta3Rp = np.array([float(0)]*99)
eta3Sp = np.array([float(0)]*99)

k = 0
for i in theta3:
    system_cas.initial_cell.F0 = F0
    system_cas.initial_cell.Fp = F0
    system_cas.initial_cell.Fr = F0*(1-i)

    system_cas.per_cells[0].Fp = F0*i
    system_cas.per_cells[0].Fr = F0*(1-i)
    system_cas.per_cells[0].R = R
    system_cas.run_sys(tspan)

    ee3Rr[k] = 100*((system_cas.res[-1,0]-system_cas.res[-1,4])/(system_cas.res[-1,0]+system_cas.res[-1,4]))
    ee3Sr[k] = -ee3Rr[k]
    ee3Sp[k] = 100*((system_cas.res[-1,7]-system_cas.res[-1,3])/(system_cas.res[-1,7]+system_cas.res[-1,3]))
    ee3Rp[k] = -ee3Sp[k]

    eta3Sp[k] = 100*(system_cas.res[-1,7]*system_cas.per_cells[0].Fp/(F0*c0[1]))
    eta3Sr[k] = 100-eta3Sp[k]
    eta3Rr[k] = 100*(system_cas.res[-1,0]*system_cas.initial_cell.Fr/(F0*c0[0]))
    eta3Rp[k] = 100-eta3Rr[k]
    k+=1

fig, axs = plt.subplots(2, 3, figsize=(15,7))
axs[0,0].plot(theta, ee_Rr, label='Retentate - R', color='blue')
axs[0,0].plot(theta, ee_Rp, label='Permeate - R', color='blue', linestyle='dashed')
axs[0,0].plot(theta, ee_Sr, label='Retentate - S', color='orange')
axs[0,0].plot(theta, ee_Sp, label='Permeate - S', color='orange', linestyle='dashed')
axs[0,0].legend(loc='upper left')
axs[0,0].set_title('Enantiomeric excess - single stage')
axs[1,0].plot(theta, eta_Rr, label='Retentate - R', color='blue')
axs[1,0].plot(theta, eta_Rp, label='Permeate - R', color='blue', linestyle='dashed')
axs[1,0].plot(theta, eta_Sr, label='Retentate - S', color='orange')
axs[1,0].plot(theta, eta_Sp, label='Permeate - S', color='orange', linestyle='dashed')
axs[1,0].legend(loc='upper left')
axs[1,0].set_title('Recovery - single stage')
axs[0,1].plot(theta2, ee2R, label='R', color='blue')
axs[0,1].plot(theta2, ee2S, label='S', color='orange')
axs[0,1].legend(loc='upper left')
axs[0,1].set_title('Enantiomeric excess - SRR')
axs[1,1].plot(theta2, eta2R, label='R', color='blue')
axs[1,1].plot(theta2, eta2S, label='S', color='orange')
axs[1,1].legend(loc='upper left')
axs[1,1].set_title('Recovery - SRR')
axs[0,2].plot(theta3, ee3Rr, label='Retentate - R', color='blue')
axs[0,2].plot(theta3, ee3Rp, label='Permeate - R', color='blue', linestyle='dashed')
axs[0,2].plot(theta3, ee3Sr, label='Retentate - S', color='orange')
axs[0,2].plot(theta3, ee3Sp, label='Permeate - S', color='orange', linestyle='dashed')
axs[0,2].legend(loc='upper left')
axs[0,2].set_title('Enantiomeric excess - 2-stage permeate cascade')
axs[1,2].plot(theta3, eta3Rr, label='Retentate - R', color='blue')
axs[1,2].plot(theta3, eta3Rp, label='Permeate - R', color='blue', linestyle='dashed')
axs[1,2].plot(theta3, eta3Sr, label='Retentate - S', color='orange')
axs[1,2].plot(theta3, eta3Sp, label='Permeate - S', color='orange', linestyle='dashed')
axs[1,2].legend(loc='upper left')
axs[1,2].set_title('Recovery - 2-stage permeate cascade')

axs[0,0].set(xlabel='', ylabel='ee (%)')
axs[1,0].set(xlabel='Stage cut (-)', ylabel='Recovery of major product (%)')
axs[0,1].set(xlabel='', ylabel='ee (%)')
axs[1,1].set(xlabel='Stage cut (-)', ylabel='Recovery of major product (%)')
axs[0,2].set(xlabel='', ylabel='ee (%)')
axs[1,2].set(xlabel='Stage cut (-)', ylabel='Recovery of major product (%)')

axs[0,0].set_xlim([0, 1])
axs[1,0].set_xlim([0, 1])
axs[0,0].set_ylim([0, 100])
axs[1,0].set_ylim([0, 100])

axs[0,1].set_xlim([0, 1])
axs[1,1].set_xlim([0, 1])
axs[0,1].set_ylim([0, 100])
axs[1,1].set_ylim([0, 200])

axs[0,2].set_xlim([0, 1])
axs[1,2].set_xlim([0, 1])
axs[0,2].set_ylim([0, 100])
axs[1,2].set_ylim([0, 100])

#for ax in axs.flat:
#    ax.label_outer()

# export data
# notes and information
# 3 process diagram
# changes in article (based on Gergo's article) Highlights, abstract, methods, res., concl.

# export data
RES = np.transpose(np.concatenate([[theta2], [ee_Rr[1:]],[ee_Rp[1:]],[ee_Sr[1:]],[ee_Sp[1:]],
    [eta_Rr[1:]],[eta_Rp[1:]],[eta_Sr[1:]],[eta_Sp[1:]],[ee2R],[ee2S],[eta2R],[eta2S],[ee3Rr],[ee3Rp],[ee3Sr],[ee3Sp],
    [eta3Rr],[eta3Rp],[eta3Sr],[eta3Sp]]))

headers = ['stage_cut','ss_ee_Rr','ss_ee_Rp','ss_ee_Sr','ss_ee_Sp','ss_rec_Rr','ss_rec_Rp','ss_rec_Sr','ss_rec_Sp',
    'srr_ee_R','srr_ee_S','srr_rec_R','srr_rec_S','c01_ee_Rr','c01_ee_Rp','c01_ee_Sr','c01_ee_Sp',
    'c01_rec_Rr','c01_rec_Rp','c01_rec_Sr','c01_rec_Sp']

#df = pd.DataFrame(RES)
#df.columns = headers
#df.to_csv('results.csv', index=False)

plt.show()


#!/usr/bin/env python
import pygame
from pygame import * #a retirer

class Projectile(pygame.sprite.Sprite):
    def __init__(self, player):
        super().__init__()
        self.player = player
        self.speed = 5
        self.image = pygame.image.load('assets/projectile.png')
        self.image = pygame.transform.scale(self.image, (50, 50))
        self.rect = self.image.get_rect()
        self.rect.x = player.rect.x + 120
        self.rect.y = player.rect.y + 80
        self.origin_image = self.image
        self.angle = 0
        self.max_attack_pos_x = self.rect.x + 500

    def rotate(self):
        self.angle += 6
        self.image = pygame.transform.rotozoom(self.origin_image, self.angle, 1) # tourner le projectile
        self.rect = self.image.get_rect(center = self.rect.center)

    def remove(self):
        self.player.all_projectiles.remove(self) # supprimer le projectile

    def move(self):
        self.rect.x += self.speed # deplacement du projectile
        self.rotate()
        if self.rect.x > self.max_attack_pos_x:# le projectile disparait lorsque la pos max est dépassé
            self.remove()
        for monster in self.player.game.check_collision(self, self.player.game.all_monsters): # verifier si le projectile entre en collision avec un monstre
            self.remove()
            monster.get_damage(self.player.attack) # infliger des dégats aux monstres
        if self.rect.x > self.player.game.screen.get_width():# verifier si notre projectile n'est plus présent sur l'ecran
            self.remove()


from typing import Tuple

import numpy as np
import pytest
from sklearn.datasets import fetch_california_housing, load_breast_cancer
from sklearn.model_selection import train_test_split

Tuple4Array = Tuple[np.array, np.array, np.array, np.array]
Tuple5Array = Tuple[np.array, np.array, np.array, np.array, np.array]

def pytest_addoption(parser):
    parser.addoption("--slow", action="store_true", help="run slow tests")

def pytest_runtest_setup(item):
    if "slow" in item.keywords and not item.config.getvalue("slow"):
        pytest.skip("need --slow option to run")

def pytest_configure(config):
    config.addinivalue_line("markers", "slow: ")

@pytest.fixture(scope="session")
def california_housing_data() -> Tuple4Array:
    X, Y = fetch_california_housing(return_X_y=True)
    return train_test_split(X, Y, test_size=0.2, random_state=23)

@pytest.fixture(scope="session")
def california_housing_survival_data() -> Tuple5Array:
    X, Y = fetch_california_housing(return_X_y=True)
    X_surv_train, X_surv_test, Y_surv_train, Y_surv_test = train_test_split(
        X, Y, test_size=0.2, random_state=14
    )

    # calculate threshold for censoring data
    censor_threshold = np.quantile(Y_surv_train, 0.75)
    # introduce administrative censoring to simulate survival data
    T_surv_train = np.minimum(
        Y_surv_train, censor_threshold
    )  # time of an event or censoring
    E_surv_train = (
        Y_surv_train > censor_threshold
    )  # 1 if T[i] is the time of an event, 0 if it's a time of censoring
    return X_surv_train, X_surv_test, T_surv_train, E_surv_train, Y_surv_test

@pytest.fixture(scope="session")
def breast_cancer_data() -> Tuple4Array:
    X, Y = load_breast_cancer(return_X_y=True)
    return train_test_split(X, Y, test_size=0.2, random_state=12)


# Check how often pairs in train appear in val

import json
from tqdm import tqdm
from os.path import join as jp
import os
import torch

path_introspect = '/home/sergio814/Documents/PhD/code/data/lxmert/data/introspect_nodup'
path_exp = '/home/sergio814/Documents/PhD/code/logs/lxmert/snap/vqa/config_113_hpc'

if not os.path.exists(jp(path_exp, 'id2inc.pt')):
    raise FileNotFoundError

# read train
with open(jp(path_introspect, 'train.json'), 'r') as f:
    t = json.load(f)

# read val
with open(jp(path_introspect, 'val.json'), 'r') as f:
    v = json.load(f)

# build pairs for train
all_sub_train = [e for e in t if e['role'] == 'sub']
id2question_train = {e['question_id']: e['sent'] for e in t}
pairs_train = [(id2question_train[sub['parent']].lower(), sub['sent'].lower()) for sub in all_sub_train]
main_train = [e[0] for e in pairs_train]
sub_train = [e[1] for e in pairs_train]

# build pairs for val
all_sub_val = [e for e in v if e['role'] == 'sub']
id2question_val = {e['question_id']: e['sent'] for e in v}
pairs_val = [(id2question_val[sub['parent']].lower(), sub['sent'].lower()) for sub in all_sub_val]
rels_val = [sub['rel'] for sub in all_sub_val]
ids_val = [sub['question_id'] for sub in all_sub_val]

cnt = 0
ids_overlap = []
for p_val, rel, id_  in tqdm(zip(pairs_val, rels_val, ids_val), total=len(rels_val)):
    if p_val[0] in main_train:
        if p_val[1] in sub_train:
            if rel in ['<--', '-->']:
                cnt += 1
                ids_overlap.append(id_)

print('total pairs from val which are also in train:', cnt, 'out of', len(pairs_val), '({:.2f} %)'.format(100*cnt/len(pairs_val)))

# now check how many of these ids are consistent for a given experiment
id2inc = torch.load(jp(path_exp, 'id2inc.pt'))
accu = 0 # number of inconsistencies among the val pairs that overlap with train for valid rels (<-- or -->)
for id_ in ids_overlap:
    accu += id2inc[id_]

print('Out of', cnt, 'pairs,', accu, 'are inconsistent for current exp. That is', '{:.2f}%'.format(100*accu/cnt))


from typing import List, Union

from torch import Tensor
from torch.nn import (
    AvgPool2d,
    BatchNorm2d,
    Conv2d,
    Dropout,
    Linear,
    Module,
    Sequential,
    Sigmoid,
    Softmax,
    init,
)

from sparseml.pytorch.models.registry import ModelRegistry
from sparseml.pytorch.nn import ReLU

__all__ = ["MobileNetSectionSettings", "MobileNet", "mobilenet", "han_mobilenet"]

def _init_conv(conv: Conv2d):
    init.kaiming_normal_(conv.weight, mode="fan_out", nonlinearity="relu")

def _init_batch_norm(norm: BatchNorm2d, weight_const: float = 1.0):
    init.constant_(norm.weight, weight_const)
    init.constant_(norm.bias, 0.0)

def _init_linear(linear: Linear):
    init.normal_(linear.weight, 0, 0.01)
    init.constant_(linear.bias, 0)

class _Input(Module):
    IN_CHANNELS = 3
    OUT_CHANNELS = 64

    def __init__(self):
        super().__init__()
        self.conv = Conv2d(
            in_channels=3,
            out_channels=32,
            kernel_size=3,
            stride=2,
            padding=1,
            bias=False,
        )
        self.bn = BatchNorm2d(32)
        self.act = ReLU(num_channels=32, inplace=True)

        self.initialize()

    def forward(self, inp: Tensor):
        out = self.conv(inp)
        out = self.bn(out)
        out = self.act(out)

        return out

    def initialize(self):
        _init_conv(self.conv)
        _init_batch_norm(self.bn)

class _ConvBNRelu(Module):
    def __init__(
        self,
        in_channels: int,
        out_channels: int,
        kernel_size: int,
        stride: int,
        padding: int,
        groups: int,
    ):
        super().__init__()
        self.conv = Conv2d(
            in_channels,
            out_channels,
            kernel_size,
            stride,
            padding,
            groups=groups,
            bias=False,
        )
        self.bn = BatchNorm2d(out_channels)
        self.act = ReLU(num_channels=out_channels, inplace=True)

        self.initialize()

    def forward(self, inp: Tensor):
        out = self.conv(inp)
        out = self.bn(out)
        out = self.act(out)

        return out

    def initialize(self):
        _init_conv(self.conv)
        _init_batch_norm(self.bn)

class _Block(Module):
    def __init__(self, in_channels: int, out_channels: int, stride: int):
        super().__init__()
        self.depth = _ConvBNRelu(
            in_channels,
            in_channels,
            kernel_size=3,
            stride=stride,
            padding=1,
            groups=in_channels,
        )
        self.point = _ConvBNRelu(
            in_channels, out_channels, kernel_size=1, stride=1, padding=0, groups=1
        )

    def forward(self, inp: Tensor):
        out = self.depth(inp)
        out = self.point(out)

        return out

class _Classifier(Module):
    def __init__(
        self,
        in_channels: int,
        num_classes: int,
        class_type: str = "single",
        dropout: Union[float, None] = None,
    ):
        super().__init__()
        self.avgpool = AvgPool2d(7)
        self.fc = Linear(in_channels, num_classes)

        if dropout is not None:  # add dropout layer before fc
            self.fc = Sequential(Dropout(dropout), self.fc)

        if class_type == "single":
            self.softmax = Softmax(dim=1)
        elif class_type == "multi":
            self.softmax = Sigmoid()
        else:
            raise ValueError("unknown class_type given of {}".format(class_type))

        self.initialize()

    def forward(self, inp: Tensor):
        out = self.avgpool(inp)
        out = out.view(out.size(0), -1)
        logits = self.fc(out)
        classes = self.softmax(logits)

        return logits, classes

    def initialize(self):
        fc = self.fc if not isinstance(self.fc, Sequential) else self.fc[1]
        _init_linear(fc)

class MobileNetSectionSettings(object):
    """
    Settings to describe how to put together a MobileNet architecture
    using user supplied configurations.

    :param num_blocks: the number of depthwise separable blocks to put in the section
    :param in_channels: the number of input channels to the section
    :param out_channels: the number of output channels from the section
    :param downsample: True to apply stride 2 for down sampling of the input,
        False otherwise
    """

    def __init__(
        self, num_blocks: int, in_channels: int, out_channels: int, downsample: bool
    ):
        self.num_blocks = num_blocks
        self.in_channels = in_channels
        self.out_channels = out_channels
        self.downsample = downsample

class MobileNet(Module):
    """
    MobileNet implementation

    :param sec_settings: the settings for each section in the MobileNet model
    :param num_classes: the number of classes to classify
    :param class_type: one of [single, multi] to support multi class training;
        default single
    :param dropout: dropout level for input to FC layer; setting to None performs
        no dropout; default is None
    """

    def __init__(
        self,
        sec_settings: List[MobileNetSectionSettings],
        num_classes: int,
        class_type: str,
        dropout: Union[float, None] = None,
    ):
        super().__init__()
        self.input = _Input()
        self.sections = Sequential(
            *[MobileNet.create_section(settings) for settings in sec_settings]
        )
        self.classifier = _Classifier(
            sec_settings[-1].out_channels, num_classes, class_type, dropout
        )

    def forward(self, inp: Tensor):
        out = self.input(inp)
        out = self.sections(out)
        logits, classes = self.classifier(out)

        return logits, classes

    @staticmethod
    def create_section(settings: MobileNetSectionSettings) -> Sequential:
        blocks = []

        in_channels = settings.in_channels
        stride = 2 if settings.downsample else 1

        for _ in range(settings.num_blocks):
            blocks.append(_Block(in_channels, settings.out_channels, stride))
            in_channels = settings.out_channels
            stride = 1

        return Sequential(*blocks)

def _mobilenet_base_section_settings():
    return [
        MobileNetSectionSettings(
            num_blocks=1, in_channels=32, out_channels=64, downsample=False
        ),
        MobileNetSectionSettings(
            num_blocks=2, in_channels=64, out_channels=128, downsample=True
        ),
        MobileNetSectionSettings(
            num_blocks=2, in_channels=128, out_channels=256, downsample=True
        ),
        MobileNetSectionSettings(
            num_blocks=6, in_channels=256, out_channels=512, downsample=True
        ),
        MobileNetSectionSettings(
            num_blocks=2, in_channels=512, out_channels=1024, downsample=True
        ),
    ]

@ModelRegistry.register(
    key=[
        "mobilenet",
        "mobilenet_100",
        "mobilenet-v1",
        "mobilenet-v1-100",
        "mobilenet_v1",
        "mobilenet_v1_100",
        "mobilenetv1_1.0",
    ],
    input_shape=(3, 224, 224),
    domain="cv",
    sub_domain="classification",
    architecture="mobilenet_v1",
    sub_architecture="1.0",
    default_dataset="imagenet",
    default_desc="base",
    def_ignore_error_tensors=["classifier.fc.weight", "classifier.fc.bias"],
)
def mobilenet(num_classes: int = 1000, class_type: str = "single") -> MobileNet:
    """
    Standard MobileNet implementation with width=1.0;
    expected input shape is (B, 3, 224, 224)

    :param num_classes: the number of classes to classify
    :param class_type: one of [single, multi] to support multi class training;
        default single
    :return: The created MobileNet Module
    """
    sec_settings = _mobilenet_base_section_settings()
    return MobileNet(sec_settings, num_classes, class_type)

@ModelRegistry.register(
    key=[
        "han-mobilenet",
        "han_mobilenet",
        "mobilenet-han",
        "mobilenet_han",
    ],
    input_shape=(3, 224, 224),
    domain="cv",
    sub_domain="classification",
    architecture="mobilenet_v1",
    sub_architecture="han",
    default_dataset="imagenet",
    default_desc="base",
    def_ignore_error_tensors=["classifier.fc[1].weight", "classifier.fc[1].bias"],
)
def han_mobilenet(num_classes: int = 1000, class_type: str = "single") -> MobileNet:
    """
    Standard MobileNet implementation with width=1.0;
    expected input shape is (B, 3, 224, 224)

    :param num_classes: the number of classes to classify
    :param class_type: one of [single, multi] to support multi class training;
        default single
    :return: The created MobileNet Module
    """
    sec_settings = _mobilenet_base_section_settings()
    return MobileNet(sec_settings, num_classes, class_type, dropout=0.2)


# -*- coding:utf-8 -*-
from sites.naver import Naver
import time
from bs4 import BeautifulSoup as bs

if __name__ == "__main__":
    naver = Naver('', '')
    clubid = ""
    #네이버 로그인
    try:
        naver.clipboard_login("", "")
    finally:
        time.sleep(1)

    line = []
    title = []
    price = []
    content = []
    page = 1001
    n = 0

    path = 'C:/Users/CSE6P28/Desktop/dataset/여성신발.txt'
    # with open(path, 'r', encoding='utf-8') as f:
    #     n = len(f.readlines())/3
    #     print(n)
    # f.close()

    #페이지마다 크롤링
    start_time = time.time()
    while(page > 0):
        if n == 10000:
            break
        data = []
        page = page - 1
        print(page)
        #페이지 이동
        start_time = time.time()
        naver.driver.get("https://cafe.naver.com/ArticleList.nhn?search.clubid=" + clubid + "&search.menuid=356&search.boardtype=L&search.totalCount=151&search.page=" + str(page))
        #중고나라 프레임 변환
        naver.driver.switch_to_frame('cafe_main')
        html = naver.driver.page_source
        soup = bs(html, 'html.parser')  # html의 관점에서 이해해라!
        #게시글 번호 크롤링
        id = soup.select(
            'div[class=inner_number]'  # class가 inner_number인 div 태그 수집
        )

        #게시글 번호 저장
        for i in id:
            data.append(i.text)

        # mobile
        temp = []

        #한 페이지의 15개 게시물 크롤링
        f = open("C:/Users/CSE6P28/Desktop/dataset/여성신발.txt", 'a', encoding='UTF8') #이어붙이기
        #f = open("C:/학교/3-2/캡스톤 디자인/여성상의.txt", 'w', encoding='UTF8') #처음부터 쓰기
        for i in range(len(data)):
            if n == 10000:
                continue
            val = 0
            #게시글 번호로 접근
            naver.driver.get('https://m.cafe.naver.com/ArticleRead.nhn?clubid=' + clubid + '&articleid=' + data[i])
            html = naver.driver.page_source
            soup = bs(html, 'html.parser')

            #제목 크롤링
            t = soup.select(
                'li[class=now]' # class가 now인 li 태그 수집
            )

            #가격 크롤링
            p = soup.select(
                'span[class=price]'  # class가 price인 span 태그 수집
            )

            #본문 크롤링
            c = soup.select(
                'div[id=postContent]'  # id가 postContent인 div 태그 수집
            )

            #본문내용 저장
            for j in c:
                p_elements = j.find_all("p")
                result = ""
                for k in p_elements:
                    result += k.text
                #예외처리
                result = result.replace("\n", "")
                result = result.replace("\xa0", "")
                result = result.replace("\t", "")
                content.append(result)
                if result == "" or result == " ":
                    val = 1
                    break
            if val == 1:
                continue

            #제목 임시저장
            for j in t:
                temp.append(j.text)

            for j in temp:
                ti = j.split('\n')[5]

            #가격 저장
            for j in p:
                price.append(j.text)

            f.write(ti + "\n")
            f.write(result + "\n")
            f.write(ti + "\n")
            n += 1

    print("--- %s seconds ---" % (time.time() - start_time))
    f.close()

    with open(path, 'r', encoding='utf-8') as f:
        n = len(f.readlines())/3
        print(n)
    f.close()

    naver.driver.quit()


import streamlit as st
from load_movies import load_movies
from movies_list import movies_list

def movies_page(user_id):
    df_filtered_movies = load_movies(user_id)
    if not df_filtered_movies is None:
        if not df_filtered_movies.empty :
            tab1, tab2 = st.tabs(["Statistiques", "Données"])
            with tab1:
                st.header('Répartition des films par année', divider='blue')
                pivot_table = df_filtered_movies.pivot_table(index='annee', columns='cinema', values='id', aggfunc='count', fill_value=0)
                result = pivot_table.reset_index()
                result = result.rename(columns={0: 'Tv', 1: 'Cinéma'})
                st.bar_chart(pivot_table);
                col1, col2 = st.columns(2)

                director_counts = df_filtered_movies['director'].value_counts()
                top_10_directors = director_counts.head(10).sort_values(ascending=False)
                top_10_directors = top_10_directors.sort_values(ascending=False)
                with col1 :
                    st.header("Les plus vus", divider='blue')
                    st.dataframe(top_10_directors, column_config={
                        "director": "Réalisateur",
                        "count": "Nombre"
                    }, hide_index=True, width=400)

                author_counts = df_filtered_movies['director'].value_counts()
                df_filtered_books_rating = df_filtered_movies[df_filtered_movies['director'].isin(author_counts[author_counts >= 3].index)]
                director_ratings = df_filtered_books_rating.groupby('director')['rating'].mean()
                director_ratings = director_ratings.round(2)
                top_10_directors = director_ratings.nlargest(10)
                with col2 :
                    st.header("Les mieux notés", divider='blue')
                    st.dataframe(top_10_directors, column_config={
                        "director": "Réalisateur",
                        "rating": "Note"
                    }, hide_index=True, width=400)

                recent_movies = df_filtered_movies.sort_values(by='date', ascending=False)
                top_10_recent_movies = recent_movies.head(10)
                selected_columns = top_10_recent_movies[['director', 'title','cinema']]
                st.header("Les 10 derniers films vus", divider='blue')
                st.dataframe(selected_columns,
                    column_config={
                        "director": "Réalisateur",
                        "title": "Titre",
                        "cinema": st.column_config.CheckboxColumn(
                            "Cinéma ?",
                            help="Vu au cinéma ou à la télévision",
                            default=False,
                            )
                    },
                hide_index=True, width=800)
            with tab2:
                movies_list(df_filtered_movies)
        else:
            st.write('Aucun film trouvé pour cet utilisateur.')


import json
import matplotlib.pyplot as plt
import numpy as np

# Load the JSON data
with open('src/data/feature_engineered.json') as json_file:
    data = json.load(json_file)

# Prompt for the item number
item_number = int(input("Enter the item number: "))

# Check if the item number is valid
if item_number < 1 or item_number > len(data):
    print("Invalid item number!")
else:
    # Get the nth item from the data
    item_data = data[item_number - 1]
    eval = item_data['eval_white_perspective']
    moves = item_data['moves_san']

    # Create lists for x and y values
    x_values = [i * 0.5 for i in range(len(eval))]
    y_values = eval

    # Create the plot
    plt.figure(figsize=(10, 6))
    plt.plot(x_values, y_values, marker='o', linestyle='-', linewidth=2, markersize=4, color='green')
    plt.xlabel("Moves")
    plt.ylabel("Evaluation")
    plt.title(f"Evaluation of Game {item_number}")
    plt.grid(True)
    plt.yticks(range(round(min(y_values)-1), round(max(y_values)+1)))
    plt.tight_layout()

    # Add margin line at y=0
    plt.axhline(0, color='black', linestyle='--', linewidth=1)

    # Calculate area under the curve above zero and below zero
    area_above_zero = np.trapz(np.maximum(y_values, 0), x_values)
    area_below_zero = np.trapz(np.minimum(y_values, 0), x_values)
    relative_area_above_zero = area_above_zero/len(eval)*0.5
    relative_area_below_zero = area_below_zero/len(eval)*0.5

    print(f"Area above zero: {area_above_zero:.2f}")
    print(f"Area below zero: {area_below_zero:.2f}")
    print(f"Relative Area above zero: {relative_area_above_zero:.2f}")
    print(f"Relative Area below zero: {relative_area_below_zero:.2f}")

    # Fill region below y=0 with grey color
    plt.fill_between(x_values, min(y_values), y2=0, where=None, color='lightgrey')

    plt.show()
    plt.close()


#from crypt import methods
from pydoc import render_doc
from flask import Flask
from flask_mysqldb import MySQL
from flask import Flask, request, render_template, redirect, url_for,flash

#mysql connection
app = Flask(__name__)
app.config['MySQL_HOST'] = 'localhost'
app.config['MySQL_USER'] = 'root'
app.config['MySQL_PASSWORD'] = ''
app.config['MySQL_DB'] = 'flaskcontacts'

#settings
app.secret_key = 'mysecretkey'

mysql = MySQL(app)

@app.route('/')
def Index():
    return render_template('index.html')

@app.route('/add_contact', methods=['POST'])
def add_contact():
    if(request.method == 'POST'):
        fullname = request.form['fullname']
        phone = request.form['phone']
        email = request.form['email']

        cur = mysql.connection.cursor()
        cur.execute('INSERT INTO contacts (fullname,phone,email) VALUES (%s, %s, %s)',
        (fullname, phone, email))

        mysql.connection.commit()

        flash('Contact added successfully')
        return redirect(url_for('index'))

@app.route('/edit')
def edit_contac():
    return 'edit contac'

@app.route('/delete')
def delete_contact():
    return 'delete contact'

if __name__ == '__main__':
    app.run(port = 3000, debug=True)


import os
from pathlib import Path
import re
import sys

import click
from ruamel.yaml import YAML
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import tkinter as tk

from kit_dl import core
from kit_dl.assistant import Assistant
from kit_dl.dao import Dao
import kit_dl.misc.utils as utils

gecko_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "geckodriver.exe")
user_yml_path = os.path.join(click.get_app_dir("kit_dl"), "user.yml")
config_yml_path = os.path.join(Path(__file__).parents[0], "config.yml")

yaml = YAML(typ="rt")
yaml.indent(mapping=2, sequence=4, offset=2)
yaml.compact(seq_seq=False, seq_map=False)

# Create data access object and load data on startup.
dao = Dao(gecko_path, user_yml_path, config_yml_path, yaml)

def print_info(ctx, param, value):

    if not value or ctx.resilient_parsing:
        return

    dao.load_data(suppress_access_errors=True)
    click.echo("Current user: {}".format(dao.user_data["user_name"]))
    click.echo("Root path: {}\n".format(dao.user_data["destination"]["root_path"]))
    added_courses = dao.added_courses()
    click.echo("Added courses:")
    for course in added_courses:
        click.echo("{}: {}".format(course.upper(), utils.reformat(dao.config_data[course]["path"])))
    available_courses = ", ".join(course.upper() for course in dao.config_data if course not in added_courses)
    click.echo("\nAvailable courses: {}".format(available_courses))
    ctx.exit()

@click.group(context_settings=dict(help_option_names=["-h", "--help"]))
@click.version_option(message="%(prog)s version %(version)s")
@click.option(
    "--info",
    "-i",
    is_flag=True,
    callback=print_info,
    expose_value=False,
    help="Show information about the current user and courses and exit.",
)
@click.pass_context
def cli(ctx):
    """Thank you for using the KIT Assignments Downloader!

    In order to download assignments make sure the setup was successful
    (otherwise run 'kit-dl setup' again).\n
    To get started, just use the 'kit-dl update la' command
    where 'la' is one of your courses.\n
    If you only want to download a specific assignment, use
    'kit-dl get la 9' where '9' is the assignment number.\n
    In case the download isn't working or you encounter any
    bugs/crashes please visit github.com/jonasstr/kit-assignments-downloader
    and create an issue or contact me via email: uzxhf@student.kit.edu.
    """
    if str(ctx.invoked_subcommand) != "setup":
        # Make sure user.py has been created and config.yml exists.
        if setup_incorrectly("user.yml", user_yml_path) or setup_incorrectly("config.yml", config_yml_path):
            sys.exit(1)
        else:
            dao.load_data(suppress_access_errors=True)

def setup_incorrectly(file_name, path):
    if not os.path.isfile(path):
        click.echo(
            "\nKit-dl has not been configured correctly ({} not found)."
            "\nUse 'kit-dl setup' before downloading assignments.".format(file_name)
        )
        return True

@cli.command()
@click.option("--config", "-cf", is_flag=True, help="Change the download locations for the courses.")
@click.option("--user", "-u", is_flag=True, help="Change the current user and the root path for downloads.")
def setup(config, user):
    """Start the command line based setup assistant or change previous settings."""

    root = tk.Tk()
    root.withdraw()
    root.wm_attributes("-topmost", True)
    assistant = Assistant(yaml, dao)
    # Setup user.yml if either the --user option has been provided or no options at all.
    if user or user == config:
        if not assistant.setup_user():
            click.echo("Setup cancelled.")
            return
    # Setup config.yml if either the --config option has been provided or no options at all.
    if config or user == config:
        if not assistant.setup_config():
            click.echo("Setup cancelled.")
            return
    click.echo("\nSetup successful. Type 'kit-dl --help' for details.")

def get_config_data():
    if dao.config_data is None:
        if dao.try_load_file(config_yml_path) is None:
            return []
        dao.load_data(suppress_access_errors=True)
    return dao.config_data

@cli.command()
@click.argument("course_names", nargs=-1, required=True, type=click.Choice(get_config_data()))
@click.argument("assignment_num")
@click.option(
    "--move/--keep",
    "-mv/-kp",
    default=True,
    help="Move the downloaded assignments to their course directory"
    " (same as 'kit-dl update') or keep them in the browser's download directory (default: move).",
)
@click.option("--all", "-a", is_flag=True, help="Download assignments from all specified courses.")
@click.option(
    "--headless/--show", "-hl/-s", default=True, help="Start the browser in headless mode (no visible UI)."
)
@click.option(
    "--verbose", "-v", is_flag=True, help="Print additional information during the download process."
)
def get(course_names, assignment_num, move, all, headless, verbose):
    """Download one or more assignments from the specified course(s) and move them into the correct folders."""
    assignments = get_assignments(assignment_num)
    if assignments is None:
        print("Assignment number must be an integer or in the correct format!")
        return

    scraper = create_scraper(headless, verbose)
    try:
        for name in courses_to_iterate(course_names, all):
            course = dao.config_data[name]
            scraper.get(course, name, assignments, move)
    finally:
        scraper.driver.quit()

def get_assignments(input):
    assignments = None
    if is_positive_int(input):
        assignments = [input]
    # Alternative range for assignment nums instead of int. Example: 5-10
    elif is_range(input):
        assignment_nums = input.split("-")
        assignments = range(int(assignment_nums[0]), int(assignment_nums[1]) + 1)
    # Alternative int sequence for input instead of int. Example: 5,10,11
    elif is_sequence(input):
        assignments = list(map(int, input.split(",")))
    return assignments

@cli.command()
@click.argument("course_names", nargs=-1, required=False, type=click.Choice(get_config_data()))
@click.option("--all", "-a", is_flag=True, help="Update assignment directories for all specified courses.")
@click.option(
    "--headless/--show", "-hl/-s", default=True, help="Start the browser in headless mode (no visible UI)."
)
@click.option(
    "--verbose", "-v", is_flag=True, help="Print additional information during the download process."
)
def update(course_names, all, headless, verbose):
    """Update one or more courses by downloading the latest assignments."""
    scraper = create_scraper(headless, verbose)
    try:
        for name in courses_to_iterate(course_names, all):
            course = dao.config_data[name]
            scraper.update_directory(course, name)
    finally:
        scraper.driver.quit()

def courses_to_iterate(course_names, all):
    if not course_names:
        all = True
    return dao.config_data if all else course_names

def create_scraper(headless, verbose):
    driver = webdriver.Firefox(
        firefox_profile=create_profile(),
        executable_path=gecko_path,
        options=get_options() if headless else None,
    )
    return core.Scraper(driver, dao, verbose)

def get_options():
    """Creates Firefox options for running kit-dl in headless mode."""
    options = Options()
    options.headless = True
    return options

def is_positive_int(value):
    return re.search(r"^\d+$", value)

def is_range(value):
    return re.search(r"^\d+-\d+$", value)

def is_sequence(value):
    return re.search(r"^\d+(?:,\d+)*$", value)

def create_profile():
    """Create a Firefox profile required for navigating on a webpage.

    Set the preferences allowing PDFs to be downloaded immediately as well as
    navigating between tabs using keyboard shortcuts.

    :returns: The Firefox profile.
    """
    profile = webdriver.FirefoxProfile()
    # Set download location
    profile.set_preference("browser.download.folderList", 2)
    profile.set_preference("browser.download.dir", dao.user_data["destination"]["root_path"])
    # Close download window immediately
    profile.set_preference("browser.download.manager.showWhenStarting", False)
    profile.set_preference("browser.download.manager.closeWhenDone", True)
    # Download PDF files without asking the user
    profile.set_preference("pdfjs.disabled", True)
    profile.set_preference("plugin.disable_full_page_plugin_for_types", "application/pdf")
    profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf")
    # Don't switch between recently visited tabs
    profile.set_preference("browser.ctrlTab.recentlyUsedOrder", False)
    # Move directly to newly opened tab
    profile.set_preference("browser.tabs.loadInBackground", False)
    return profile

if __name__ == "__main__":
    cli()