import os
import math
import pandas as pd
from random import shuffle
from src.common.path_resolvers import resolve_dataset_pickle_dataframe
from src.common.constants import SPLIT_INDEX, \
    COL_SPEAKER, COL_VOKEN_ID, COL_SET_TYPE

def get_speaker_df_token_voken(dataset_name, speaker_name):
    # /home/stav/Data/Vokenization/Datasets/Oliver_V1/df_token_voken_pkl.csv
    data_path = resolve_dataset_pickle_dataframe(dataset_name)
    df_speaker = pd.read_pickle(data_path)
    df_speaker[COL_SPEAKER] = speaker_name
    # mark_train_test_split(df_speaker, dataset_name)
    return df_speaker

def get_full_df_token_voken(dataset_oliver, dataset_noah):
    df_oliver = get_speaker_df_token_voken(dataset_oliver, 'Oliver')
    df_noah   = get_speaker_df_token_voken(dataset_noah, 'Noah')
    df_all    = pd.concat([df_oliver, df_noah])
    return df_all

def split_dataframe(df, chunk_size):
    chunks = list()
    num_chunks = math.ceil(len(df) / chunk_size)
    for i in range(num_chunks):
        chunks.append(df[i*chunk_size:(i+1)*chunk_size])
    return chunks

def shuffle_blocks(df_all, block_size):
    lst_df_blocks = split_dataframe(df_all, block_size)
    assert len(df_all) == sum(list(map(len, lst_df_blocks)))
    lst_df_blocks_full, lst_df_blocks_reminder = lst_df_blocks[:-1], lst_df_blocks[-1]
    assert len(df_all) == (sum(list(map(len, lst_df_blocks_full))) + len(lst_df_blocks_reminder))
    indices = list(range(len(lst_df_blocks_full)))
    shuffle(indices)
    lst_df_blocks_full_shuffled = [lst_df_blocks_full[i] for i in indices]
    lst_df_blocks_shuffled = lst_df_blocks_full_shuffled + [lst_df_blocks_reminder]
    df_all_shuffled = pd.concat(lst_df_blocks_shuffled)
    assert len(df_all) == len(df_all_shuffled)
    first_idx = indices[0]
    assert df_all[first_idx * block_size: first_idx * block_size + 10].equals(df_all_shuffled[:10])
    return df_all_shuffled, indices

def mark_train_test_split(df_speaker, dataset_name):
    split_index = SPLIT_INDEX[dataset_name]
    df_speaker[COL_SET_TYPE] = None
    df_speaker.iloc[:split_index+1, df_speaker.columns.get_loc(COL_SET_TYPE)] = 'train'
    df_speaker.iloc[split_index:, df_speaker.columns.get_loc(COL_SET_TYPE)]   = 'test'

def get_df_all_train_test(dataset_oliver, dataset_noah):
    df_all = get_full_df_token_voken(dataset_oliver, dataset_noah)
    df_train = df_all[df_all[COL_SET_TYPE] == 'train']
    df_test  = df_all[df_all[COL_SET_TYPE] == 'test']
    return df_all, df_train, df_test

def shuffle_train_test(df_train, df_test, block_size):
    df_train_shuffled, train_indices = shuffle_blocks(df_train, block_size)
    print('Train:')
    print(df_train_shuffled[COL_SPEAKER].value_counts().astype('float32'))
    # noah     162,625
    # oliver    81,712
    print('Test:')
    df_test_shuffled, test_indices = shuffle_blocks(df_test, block_size)
    print(df_test_shuffled[COL_SPEAKER].value_counts().astype('float32'))
    return df_train_shuffled, train_indices, df_test_shuffled, test_indices


import numpy as np
import tensorflow as tf
import h5py
import sys
from scatternet.utils.data_processing import format_galaxies, check_data_processing
from sklearn.preprocessing import LabelBinarizer
from sklearn.utils import class_weight
import random
if sys.version_info[0] == 2:
    import cPickle as pickle
else:
    import pickle

def shuffle(x,y):
    temp = list(zip(x, y))
    random.shuffle(temp)
    x,y = zip(*temp)
    x = np.array(x)
    y = np.array(y)
    return x,y

class DataSet():
    def __init__(self, add_channel = False):

        self.modified = False
        self.load_data()
        self.keys, self._unique_indices = np.unique(self.y_train, return_index = True)
        if add_channel:
            self.add_channel()
        else:
            (self._n_train, self._dim_x, self._dim_y), self.n_classes = self.x_train.shape, self.keys.size
        self._x_test_rot = np.rot90(self.x_test,axes=(1, 2))
        self._encoder = LabelBinarizer()
        self._encoder.fit(self.y_train)

    def write(self,outname):
        with open(outname, 'wb') as f:
            np.save(f, self.x_train)
            np.save(f, self.y_train)
            np.save(f, self.x_val)
            np.save(f, self.y_val)
            np.save(f, self.x_test)
            np.save(f, self.y_test)
            np.save(f,self.label_list)

    def save_original(self):
        self.__x_train    = np.copy(self._x_train)
        self.__x_test     = np.copy(self._x_test)
        self.__x_test_rot = np.copy(self._x_test_rot)
        self.__x_val      = np.copy(self._x_val)

    def restore_original(self):
        self._x_train    = self.__x_train
        self._x_test     = self.__x_test
        self._x_test_rot = self.__x_test_rot
        self._x_val      = self.__x_val

    def add_channel(self):
        self._x_train = self._x_train.reshape(*self._x_train.shape,1)
        self._x_test  = self._x_test.reshape( *self._x_test.shape,1)
        self._x_val   = self._x_val.reshape(  *self._x_val.shape,1)

        (self._n_train, self._dim_x, self._dim_y,__), self.n_classes = self.x_train.shape, self.keys.size

    def load_data(self):
        raise NotImplementedError

    def preprocess(self,f):
        self._x_train    = f(self._x_train)
        self._x_test     = f(self._x_test)
        self._x_test_rot = f(self._x_test_rot)
        self._x_val      = f(self._x_val)

    def info(self):

        for i, k in enumerate(self.keys):
            n_train = len(np.where(self.y_train == i)[0])
            n_test = len(np.where(self.y_test == i)[0])
            n_val = len(np.where(self.y_val == i)[0])
            print(self.label_list[i], "n_train =", n_train, "n_val =", n_val, "n_test =", n_test)

    def truncate_train(self,n, balance = False, randomize = False):

        if randomize:
            self._x_train, self._y_train = shuffle(self._x_train, self._y_train)

        if balance:
            n_per_class = int(n / self.n_classes)
            indices = []
            for i, k in enumerate(self.keys):
                class_indices = np.where(self.y_train == i)[0][:n_per_class]
                indices = np.append(indices,class_indices)
            indices = indices.astype(np.intc)
            self._x_train = self._x_train[indices]
            self._y_train = self._y_train[indices]

        else:
            self._x_train = self._x_train[:n]
            self._y_train = self._y_train[:n]

    def get_example_classes(self,n=1):
        indices = []
        for i, k in enumerate(self.keys):
            class_indices = np.where(self.y_train == i)[0][:n]
            indices = np.append(indices,class_indices)
        indices = indices.astype(np.intc)
        return (self._x_train[indices], self._y_train[indices])

    def augment(self):

        print('Augment',self._x_train.shape)

        x_train_flip = np.flip(self.x_train,axis=1)
        x_train = np.vstack( [self._x_train, x_train_flip])
        y_train = np.append(self._y_train,self._y_train)

        for k in range(1,4):
            x_train_rotated         = np.rot90(self._x_train,axes=(1, 2),k=k)
            x_train_rotated_flipped = np.rot90(x_train_flip,axes=(1, 2),k=k)

            x_train = np.vstack( [x_train, x_train_rotated])
            x_train = np.vstack( [x_train, x_train_rotated_flipped])
            y_train = np.append(y_train,self._y_train)
            y_train = np.append(y_train,self._y_train)

        self._x_train, self._y_train = shuffle(x_train, y_train)

        print(self._x_train.shape)

    @property
    def data_shape(self):
        return self._x_test_rot.shape[1:]

    def encode(self, y):
        return self._encoder.transform(y)

    def decode(self, y):
        return self._encoder.inverse_transform(y)

    @property
    def class_weights(self):
        return class_weight.compute_class_weight(class_weight='balanced',
                                                 classes = np.unique(self.y_train),
                                                 y=self.y_train)

    @property
    def sample_weights(self):
        return class_weight.compute_sample_weight('balanced',self.y_train)

    @property
    def label_list(self):
        raise NotImplementedError

    @property
    def unique_indices(self):
        return self._unique_indices

    @property
    def dim_x(self):
        return self._dim_x

    @property
    def dim_y(self):
        return self._dim_y

    @property
    def x_train(self):
        return self._x_train

    @property
    def y_train(self):
        return self._y_train

    @property
    def n_train(self):
        return self._n_train

    @property
    def x_val(self):
        return self._x_val

    @property
    def y_val(self):
        return self._y_val

    @property
    def x_test(self):
        return self._x_test

    @property
    def x_test_rot(self):
        return self._x_test_rot

    @property
    def y_test(self):
        return self._y_test

class DataFromFile(DataSet):
    def __init__(self, infilename, add_channel = False):
        self.infilename = infilename
    def load_data(self):
        with open(self.infilename, 'rb') as f:
            self.x_train = np.load(f)
            self.y_train = np.load(f)
            self.x_val   = np.load(f)
            self.y_val   = np.load(f)
            self.x_test  = np.load(f)
            self.y_test  = np.load(f)
            self._label_list= np.load(f)
    @property
    def label_list(self):
        return self._label_list

class RadioGalaxies(DataSet):
    '''
    This Radio Galaxy Dataset is a collection and combination of several catalogues
    using the FIRST radio galaxy survey [[1]](https://ui.adsabs.harvard.edu/abs/1995ApJ...450..559B/abstract).
    https://www.sciencedirect.com/science/article/pii/S2352340923000926
    '''

    def load_set(self,F, key, x,y):
        data_entry = F[key + "/Img"]
        label_entry = F[key + "/Label_literature"]
        d = np.array(data_entry)
        y.append(np.array(label_entry))
        x.append(d)

    def format(self,x,y, trimby = 120):

        x,y = shuffle(x,y)
        x = x.astype(np.intc)
        y = y.astype(np.intc)
        x = x[:,trimby:-trimby,trimby:-trimby]/255.

        return x,y

    def load_data(self):
        self._x_train, self._y_train, self._x_val,  self._y_val, self._x_test,  self._y_test  = [], [], [], [], [], []
        with h5py.File('data/galaxy_data_h5.h5', 'r') as F:
            for key in F.keys():
                split_entry = F[key + "/Split_literature"].asstr()[()]

                if split_entry == "train":
                    self.load_set(F,key,self._x_train, self._y_train)
                elif split_entry == "test":
                    self.load_set(F,key,self._x_test, self._y_test)
                elif split_entry == "valid":
                    self.load_set(F,key,self._x_val, self._y_val)

        self._x_train, self._y_train = self.format(self._x_train, self._y_train)
        self._x_test,  self._y_test  = self.format(self._x_test,  self._y_test)
        self._x_val,   self._y_val   = self.format(self._x_val,   self._y_val)

    @property
    def label_list(self):
        return ["FRI", "FRII", "Compact", "Bent"]

class Galaxy10(DataSet):
    '''
    Galaxy morphology classification on the Galaxy10 DECals Dataset:
    https://astronn.readthedocs.io/en/latest/galaxy10.html
    Follow the instructions at the link above to download Galaxy10.h5
    '''

    def load_data(self):

        with h5py.File('data/Galaxy10.h5', 'r') as F:
            images = np.array(F['images'])
            labels = np.array(F['ans'])
        labels = labels.astype(np.intc)
        images = images.astype(np.intc)

        split1 = 1000#int(len(labels)*9/10.)
        split2 = split1+200#-1
        split3 = split2+200

        self._x_train, self._y_train = images[0:split1,:,:], labels[0:split1]
        self._x_test,  self._y_test = images[split1:split2,:,:], labels[split1:split2]
        self._x_val,  self._y_val = images[split2:split3,:,:], labels[split2:split3]

        self._x_train = format_galaxies(self._x_train, threshold = 0.1, min_size = 100, margin = 2)
        self._x_test  = format_galaxies(self._x_test,  threshold = 0.1, min_size = 100, margin = 2)
        self._x_val   = format_galaxies(self._x_val,   threshold = 0.1, min_size = 100, margin = 2)

    @property
    def label_list(self):
        return ['Disk, Face-on, No Spiral', 'Smooth, Completely round', 'Smooth, in-between round', 'Smooth, Cigar shaped', 'Disk, Edge-on, Rounded Bulge', 'Disk, Edge-on, Boxy Bulge',
                'Disk, Edge-on, No Bulge','Disk, Face-on, Tight Spiral', 'Disk, Face-on, Medium Spiral', 'Disk, Face-on, Loose Spiral']

class MINST(DataSet):
    '''
    Classic MINST letters dataset
    '''

    def load_data(self):

        (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
        x_train, x_test = x_train / 255., x_test / 255.

        self._x_train = x_train[0:10000]
        self._y_train = y_train[0:10000]

        self._x_test = x_test[0:1000]
        self._y_test = y_test[0:1000]

        self._x_val = x_test[1000:2000]
        self._y_val = y_test[1000:2000]

    @property
    def label_list(self):
        return [0,1,2,3,4,5,6,7,8,9]

class Mirabest(DataSet):
    '''
    Classic MINST letters dataset
    '''

    def load_data(self):

        filepath = './data/Mirabest/batches/'

        with open(filepath + 'batches.meta', 'rb') as infile:
            if sys.version_info[0] == 2:
                data = pickle.load(infile)
            else:
                data = pickle.load(infile, encoding='latin1')
            self.classes = data['label_names']
        self.class_to_idx = {_class: i for i, _class in enumerate(self.classes)}
        self.idx_to_class = {i: _class for i, _class in enumerate(self.classes)}
        self._x_test,  self._y_test = self.load_file(filepath,['test_batch'])
        self._x_val,   self._y_val = self.load_file(filepath,['data_batch_1'])
        self._x_train, self._y_train = self.load_file(filepath,["data_batch_{0}".format(i) for i in range(2,8)])

    def load_file(self,file_dir, file_list):
        data = []
        targets = []
        for file_path in file_list:
            with open(file_dir+ file_path, 'rb') as f:
                if sys.version_info[0] == 2:
                    entry = pickle.load(f)
                else:
                    entry = pickle.load(f, encoding='latin1')

                data.append(entry['data'])
                if 'labels' in entry:
                    targets.extend(entry['labels'])
                else:
                    targets.extend(entry['fine_labels'])
        data = np.vstack(data).reshape(-1, 150, 150)
        targets = np.array(targets)
        #data = data.transpose((0, 2, 3, 1))
        return data,targets

    def remove_uncertain_classes(self):
        uncertain_classes = [3,4,7,9]
        certain_classes = [0, 1,2,5,6,8]

        def remove_entries(exclude_list, x, y):
            targets = np.array(y)
            exclude = np.array(exclude_list).reshape(1, -1)
            exclude_mask = ~(targets.reshape(-1, 1) == exclude).any(axis=1)
            #h1 = np.array(h1_list).reshape(1, -1)
            #h2 = np.array(h2_list).reshape(1, -1)
            #h1_mask = (targets.reshape(-1, 1) == h1).any(axis=1)
            #h2_mask = (targets.reshape(-1, 1) == h2).any(axis=1)
            #targets[h1_mask] = 0 # set all FRI to Class~0
            #targets[h2_mask] = 1 # set all FRII to Class~1
            x = x[exclude_mask]
            y = targets[exclude_mask]
            return x,y

        self._x_test, self._y_test  = remove_entries(uncertain_classes,self._x_test, self._y_test)
        self._x_train,self._y_train = remove_entries(uncertain_classes,self._x_train,self._y_train)
        self._x_val,  self._y_val   = remove_entries(uncertain_classes,self._x_val,self._y_val)

        self.keys, self._unique_indices = np.unique(self.y_train, return_index = True)
        self.n_classes = self.keys.size
        self._encoder.fit(self.y_train)

    @property
    def label_list(self):
        return [self.idx_to_class[i] for i in self.keys]

class MirabestBinary(Mirabest):
    def load_data(self):
        super().load_data()

        def merge(x, y):
            targets = np.array(y)
            fr1_classes = [0,1,2]
            fr2_classes=[5,6]
            exclude_list=[3,4,7,8,9]
            exclude = np.array(exclude_list).reshape(1, -1)
            exclude_mask = ~(targets.reshape(-1, 1) == exclude).any(axis=1)
            h1 = np.array(fr1_classes).reshape(1, -1)
            h2 = np.array(fr2_classes).reshape(1, -1)
            h1_mask = (y.reshape(-1, 1) == h1).any(axis=1)
            h2_mask = (y.reshape(-1, 1) == h2).any(axis=1)

            targets[h1_mask] = 0 # set all FRI to Class~0
            targets[h2_mask] = 1 # set all FRII to Class~1
            x = x[exclude_mask]
            y = targets[exclude_mask]
            return x,y
        self._x_test, self._y_test  = merge(self._x_test, self._y_test)
        self._x_train,self._y_train = merge(self._x_train,self._y_train)
        self._x_val,  self._y_val   = merge(self._x_val,self._y_val)

        #self.keys, self._unique_indices = np.unique(self.y_train, return_index = True)
        #self.n_classes = self.keys.size
        #self._encoder.fit(self.y_train)
    @property
    def label_list(self):
        return ["FRI","FRII"]


import mysql.connector

def main():
    db = mysql.connector.connect(
        host="localhost",
        port=3306,
        username="root",
        password=""
    )
    cursor = db.cursor()
    print("Cursor Column Names: ", cursor.column_names)
    cursor.execute("USE world")
    cursor.execute("SELECT * FROM city")
    print("City Column Names:", cursor.column_names)
    print("City Row Count:", cursor.rowcount)
    allRows = cursor.fetchall()
    print("All Entries\n", allRows)
    for row in allRows:
        print(row)
    cursor.close()
    db.close()

if __name__ == "__main__":
    main()


import simian
from mock import call
from simian.test.example_2 import my_module

@simian.patch(my_module, external=['time.sleep'], internal=['my_logger'])
def test_my_sleep(master_mock):
    my_module.my_sleep(99)
    master_mock.assert_has_calls(
        calls=[
            call.my_logger('Starting 99-second sleep'),
            call.sleep(99),
            call.my_logger('Finished 99-second sleep')],
        any_order=False)


import pandas as pd
import plotly.graph_objects as go
import plotly.express as px

def line_scatter():
    df = pd.read_csv('lab3-datasets/college-salaries/salaries-by-college-type.csv')
    df = df.sample(frac=0.5, axis=0, random_state=123)
    df.reset_index(inplace=True, drop=True)
    a = df[
        ["Mid-Career 10th Percentile Salary", "Mid-Career 25th Percentile Salary", "Mid-Career 75th Percentile Salary",
         "Mid-Career 90th Percentile Salary"]]
    fig = go.Figure()
    for i in range(0, len(df)):
        fig.add_trace(go.Scatter(name=df["School Name"][i], x=a.columns, y=[df["Mid-Career 10th Percentile Salary"][i],
                                                                            df["Mid-Career 25th Percentile Salary"][i],
                                                                            df["Mid-Career 75th Percentile Salary"][i],
                                                                            df["Mid-Career 90th Percentile Salary"][
                                                                                i]]))
    fig.update_layout(
        title="Mid-Career Percentile Salary",
        yaxis_title="Mid-Career Salary",
    )
    return fig

def bubble_plot():
    df = pd.read_csv('lab3-datasets/college-salaries/salaries-by-college-type.csv')

    # Sampling
    df = df.sample(frac=0.5, axis=0, random_state=123)
    # df_state = df[df['School Type'] == 'State'].sample(n=15, replace=False, axis=0)
    # df_art = df[df['School Type'] == 'Liberal Arts'].sample(n=10, replace=False, axis=0)
    # df.drop(labels=df[df['School Type'] == 'State'].index, axis=0, inplace=True)
    # df.drop(labels=df[df['School Type'] == 'Liberal Arts'].index, axis=0, inplace=True)
    #
    # df = pd.concat([df, df_art, df_state])

    fig = px.scatter(df, x="Starting Median Salary", y="Mid-Career Median Salary",
                     size="Mid-Career 75th Percentile Salary", color="School Type", hover_name="School Name",
                     log_x=True, size_max=15)
    fig.update_layout(
        title="Median Salary"
    )

    return fig

def bar_chart(value):
    df = pd.read_csv('lab3-datasets/college-salaries/salaries-by-college-type.csv')
    df = df.iloc[df.groupby(['School Name']).apply(
        lambda x: x['Starting Median Salary'].idxmax())]
    # df = df.sample(frac=0.15, axis=0, random_state=123)
    df.reset_index(inplace=True, drop=True)
    df["Percent change from Starting to Mid-Career Salary"] = (
            (df["Mid-Career Median Salary"] - df["Starting Median Salary"]) * 100 / df["Starting Median Salary"])
    df["Percent change from Starting to Mid-Career Salary"] = [format(x, '.1f') for x in
                                                               df["Percent change from Starting to Mid-Career Salary"]]
    df["Percent change from Starting to Mid-Career Salary"] = df[
        "Percent change from Starting to Mid-Career Salary"].astype("float")
    df = df[value[0] <= df["Percent change from Starting to Mid-Career Salary"]]
    df = df[df["Percent change from Starting to Mid-Career Salary"] <= value[1]]
    fig = px.bar(df, x='School Name', y='Percent change from Starting to Mid-Career Salary')
    fig.update_layout(
        yaxis_title="Growth Rate",
    )
    return fig

def histogram():
    df = pd.read_csv('lab3-datasets/college-salaries/salaries-by-college-type.csv')
    df["Percent change from Starting to Mid-Career Salary"] = (
            (df["Mid-Career Median Salary"] - df["Starting Median Salary"]) * 100 / df["Starting Median Salary"])
    df["Percent change from Starting to Mid-Career Salary"] = [format(x, '.1f') for x in
                                                               df["Percent change from Starting to Mid-Career Salary"]]
    df["Percent change from Starting to Mid-Career Salary"] = df[
        "Percent change from Starting to Mid-Career Salary"].astype("float")
    fig = px.histogram(df, x="Percent change from Starting to Mid-Career Salary")
    fig.update_layout(
        xaxis_title="Growth Rate"
    )
    return fig


import torch
import torch.nn as nn
from torch.optim import Adam

from coatnet import coatnet_0

def Train(epochs, trainDL, validDL):

    best_accuracy = 0.0

    # Define your execution device
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print("The model will be running on", device, "device")
    # Convert model parameters and buffers to CPU or Cuda
    net = coatnet_0()
    net.to(device)

    # Epochs
    num_epochs = 100
    for epoch in range(num_epochs):  # loop over the dataset multiple times
        running_loss = 0.0
        running_acc = 0.0

        for i, (images, labels) in enumerate(trainDL, 0):

            # Forward
            out = net(img)
            # print(out.shape, count_parameters(net))

            # LossFunction

            # Define the loss function with Classification Cross-Entropy loss and an optimizer with Adam optimizer
            loss_fn = nn.CrossEntropyLoss()
            optimizer = Adam(net.parameters(), lr=0.001, weight_decay=0.0001)
            loss = loss_fn(out, labels)
                # Backward
            # backpropagate the loss
            loss.backward()
            # adjust parameters based on the calculated gradients
            optimizer.step()

            # Let's print statistics for every 1,000 images
            running_loss += loss.item()  # extract the loss value
            if i % 1000 == 999:
                # print every 1000 (twice per epoch)
                print('[%d, %5d] loss: %.3f' %
                      (epoch + 1, i + 1, running_loss / 1000))
                # zero the loss
                running_loss = 0.0

        # Compute and print the average accuracy fo this epoch when tested over all 10000 test images
        accuracy = testAccuracy()
        print('For epoch', epoch + 1, 'the test accuracy over the whole test set is %d %%' % (accuracy))


### sample data ###

### number count of data ###
Pi = 5  # incoming patients
Pe = 10  # existing patients
R_icu = 20  # Number of ICU resources (beds)
R_noicu = 40  # Number of general impatient resources (beds)

### weights and percentages ###
Umax = 0.9  # ICU resource max usage (percentage)
w1 = 0.9
w2 = 0.5

### back-up parameters for programming ##
t = []  # bed turnaround time of ICU patients reallocation
xi = []  # possibilities of incoming patients going to different departments
xe = []  # possibilities of existing patients going to different departments
x = [xi, xe]

### The calculated expectation of treatment effectiveness of all the diseases (appeared in the data we use) ###
# for every key-value pair, the value is a list with 2 elements:
# the first one is death rate of historical patients in icu, the second is death rate of historical patients out of icu
Ep_d_icu_noicu = {"29410": [0.33, 0.2], "V1087": [0.5, 0.3], "4011": [0.7, 0.6], "E8497": [0.2, 0.35],
                  "7847": [0.7, 0.5], "25080": [0.5, 0.67], "78009": [0.56, 0.3], "30000": [0.32, 0.2],
                  "V163": [0.6, 0.4], "V1254": [0.24, 0.45],
                  "27482": [0.33, 0.25], "4275": [0.67, 0.8], "E9308": [0.45, 0.5], "V4589": [0.35, 0.7],
                  "87364": [0.65, 0.4], "E9283": [0.57, 0.59], "V0259": [0.7, 0.6], "E9330": [0.7, 0.3],
                  "2749": [0.5, 0.25], "E8780": [0.8, 0.9],
                  "V451": [0.4, 0.57], "79029": [0.4, 0.36], "V162": [0.7, 0.55], "56400": [0.34, 0.44]}

### 5 incoming patients ###
# this is extracted from `diagnoses_icd` join `d_icd_diagnoses`
incoming_patient_disease = {1: [{"subject_id": "1", "seq_num": "27", "icd_code": "29410", "icd_version": "9",
                                 "long_title": "Dementia in conditions classified elsewhere without behavioral disturbance"},
                                {"subject_id": "1", "seq_num": "28", "icd_code": "V1087", "icd_version": "9",
                                 "long_title": "Personal history of malignant neoplasm of thyroid"}],
                            2: [{"subject_id": "2", "seq_num": "36", "icd_code": "4011", "icd_version": "9",
                                 "long_title": "Benign essential hypertension"},
                                {"subject_id": "2", "seq_num": "27", "icd_code": "E8497", "icd_version": "9",
                                 "long_title": "Accidents occurring in residential institution"}],
                            3: [{"subject_id": "3", "seq_num": "26", "icd_code": "7847", "icd_version": "9",
                                 "long_title": "Epistaxis"},
                                {"subject_id": "3", "seq_num": "27", "icd_code": "25080", "icd_version": "9",
                                 "long_title": "Diabetes with other specified manifestations, type II or unspecified type, not stated as uncontrolled"}],
                            4: [{"subject_id": "4", "seq_num": "27", "icd_code": "78009", "icd_version": "9",
                                 "long_title": "Other alteration of consciousness"},
                                {"subject_id": "4", "seq_num": "26", "icd_code": "30000", "icd_version": "9",
                                 "long_title": "Anxiety state, unspecified"}],
                            5: [{"subject_id": "5", "seq_num": "26", "icd_code": "V163", "icd_version": "9",
                                 "long_title": "Family history of malignant neoplasm of breast"},
                                {"subject_id": "5", "seq_num": "25", "icd_code": "V1254", "icd_version": "9",
                                 "long_title": "Personal history of transient ischemic attack (TIA), and cerebral infarction without residual deficits"}]}

# this is extracted from `admissions`
incoming_patient_info = {1: {"age": 66}, 2: {"age": 35}, 3: {"age": 75}, 4: {"age": 58}, 5: {"age": 64}}

# sofa score of incoming patients, extracted from `mimic_derived`
s_i = [18, 19, 17, 10, 12]

### 10 existing patient in icu ###
# this is extracted from `diagnoses_icd` join `d_icd_diagnoses`
existing_patient_disease = {1: [{"subject_id": "6", "seq_num": "25", "icd_code": "27482", "icd_version": "9",
                                 "long_title": "Gouty tophi of other sites, except ear"},
                                {"subject_id": "6", "seq_num": "26", "icd_code": "4275", "icd_version": "9",
                                 "long_title": "Cardiac arrest"}],
                            2: [{"subject_id": "7", "seq_num": "27", "icd_code": "E9308", "icd_version": "9",
                                 "long_title": "Other specified antibiotics causing adverse effects in therapeutic use"},
                                {"subject_id": "7", "seq_num": "31", "icd_code": "V4589", "icd_version": "9",
                                 "long_title": "Other postprocedural status"}],
                            3: [{"subject_id": "8", "seq_num": "25", "icd_code": "87364", "icd_version": "9",
                                 "long_title": "Open wound of tongue and floor of mouth, without mention of complication"},
                                {"subject_id": "8", "seq_num": "26", "icd_code": "E9283", "icd_version": "9",
                                 "long_title": "Human bite"}],
                            4: [{"subject_id": "9", "seq_num": "39", "icd_code": "V1254", "icd_version": "9",
                                 "long_title": "Personal history of transient ischemic attack (TIA), and cerebral infarction without residual deficits"},
                                {"subject_id": "9", "seq_num": "35", "icd_code": "V0259", "icd_version": "9",
                                 "long_title": "Carrier or suspected carrier of other specified bacterial diseases"}],
                            5: [{"subject_id": "10", "seq_num": "25", "icd_code": "E9330", "icd_version": "9",
                                 "long_title": "Antiallergic and antiemetic drugs causing adverse effects in therapeutic use"},
                                {"subject_id": "10", "seq_num": "32", "icd_code": "2749", "icd_version": "9",
                                 "long_title": "Gout, unspecified"}],
                            6: [{"subject_id": "11", "seq_num": "25", "icd_code": "E8780", "icd_version": "9",
                                 "long_title": "Surgical operation with transplant of whole organ causing abnormal patient reaction, or later complication, without mention of misadventure at time of operation"}],
                            7: [{"subject_id": "12", "seq_num": "28", "icd_code": "V4589", "icd_version": "9",
                                 "long_title": "Other postprocedural status"}],
                            8: [{"subject_id": "13", "seq_num": "32", "icd_code": "V4589", "icd_version": "9",
                                 "long_title": "Other postprocedural status"},
                                {"subject_id": "13", "seq_num": "26", "icd_code": "V451", "icd_version": "9",
                                 "long_title": "Renal dialysis status"}],
                            9: [{"subject_id": "14", "seq_num": "26", "icd_code": "79029", "icd_version": "9",
                                 "long_title": "Other abnormal glucose"},
                                {"subject_id": "14", "seq_num": "32", "icd_code": "V162", "icd_version": "9",
                                 "long_title": "Family history of malignant neoplasm of other respiratory and intrathoracic organs"}],
                            10: [{"subject_id": "15", "seq_num": "26", "icd_code": "56400", "icd_version": "9",
                                  "long_title": "Constipation, unspecified"}]}

# this is extracted from `admissions`
existing_patient_info = {1: {"age": 63}, 2: {"age": 18}, 3: {"age": 38}, 4: {"age": 16}, 5: {"age": 69}, 6: {"age": 63},
                         7: {"age": 48}, 8: {"age": 38}, 9: {"age": 91}, 10: {"age": 46}}

# sofa score of existing patients, extracted from `mimic_derived`
s_e = [19, 21, 16, 24, 22, 18, 11, 10, 8, 21]


##################################
# ERROR
##################################

class Error:
    def __init__(self, startPos, endPos, errorName, details):
        self.errorName = errorName
        self.details = details
        self.startPos = startPos
        self.endPos = endPos

    def as_string(self):
        err = f'{self.errorName}: {self.details}'
        err += f' File {self.startPos.fn}, line {self.startPos.ln+1}'
        err += f' \n\n{stringWithArrows(self.startPos.ftxt, self.startPos, self.endPos)}'
        return err

class IllegalCharacterError(Error):
    def __init__(self, startPos, endPos, details):
        super().__init__(startPos, endPos, 'Illegal Character', details)

class InvalidSyntaxError(Error):
    def __init__(self, startPos, endPos, details=''):
        super().__init__(startPos, endPos, 'Invalid Syntax', details)

class RTError(Error):
    def __init__(self, startPos, endPos, details='', context=''):
        super().__init__(startPos, endPos, 'Runtime Error', details)
        self.context = context

    def as_string(self):
        err = f'{self.generateTraceback()}'
        err += f'{self.errorName}, {self.details}'
        err += f' \n\n{stringWithArrows(self.startPos.ftxt, self.startPos, self.endPos)}'
        return err

    def generateTraceback(self):
        result = ''
        pos = self.startPos
        ctx = self.context

        while ctx:
            result = f'  File {pos.fn}, line {str(pos.ln + 1)}, in {ctx.displayName}\n' + result
            pos = ctx.parentEntry
            ctx = ctx.parent

        return 'Traceback (most recent call last):\n' + result

class ExpectedCharError(Error):
    def __init__(self, startPos, endPos, details):
        super().__init__(startPos, endPos, 'Expected Character', details)

##################################
# Decorations
##################################

def stringWithArrows(text, pos_start, pos_end):
    result = ''

    # Calculate indices
    idx_start = max(text.rfind('\n', 0, pos_start.idx), 0)
    idx_end = text.find('\n', idx_start + 1)
    if idx_end < 0:
        idx_end = len(text)

    # Generate each line
    line_count = pos_end.ln - pos_start.ln + 1
    for i in range(line_count):
        # Calculate line columns
        line = text[idx_start:idx_end]
        col_start = pos_start.col if i == 0 else 0
        col_end = pos_end.col if i == line_count - 1 else len(line) - 1

        # Append to result
        result += line + '\n'
        result += ' ' * col_start + '^' * (col_end - col_start)

        # Re-calculate indices
        idx_start = idx_end
        idx_end = text.find('\n', idx_start + 1)
        if idx_end < 0:
            idx_end = len(text)

    return result.replace('\t', '')


from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score
import matplotlib.pyplot as plt
import numpy as np
import os
from random import shuffle, choice, randrange
from time import time
from cv2 import resize
from albumentations import PadIfNeeded, Rotate, RandomBrightnessContrast
import csv

TEST_PATH = "GTSRB/Final_Test/Images"
TRAINING_PATH = "GTSRB/Final_Training/Images"

def read_training_data(rootpath):
    """
    Function for reading the images for training.
    :param rootpath:  path to the traffic sign data
    :return:          list of images, list of corresponding image information: width, height, class, track
    """
    images = []     # images
    img_info = []   # corresponding labels
    # loop over all classes
    for img_class in os.listdir(rootpath):
        prefix = rootpath + '/' + img_class + '/'                   # subdirectory for class
        gt_file = open(prefix + 'GT-' + img_class + '.csv')         # annotations file
        gt_reader = csv.reader(gt_file, delimiter=';')              # csv parser for annotations file
        next(gt_reader)                                             # skip header
        # loop over all images in current annotations file
        for row in gt_reader:
            images.append(plt.imread(prefix + row[0]))              # numpy array representation of image
            img_info.append([int(row[1]), int(row[2]),
                             img_class, row[0][:5]])                # width, height, class, track
        gt_file.close()
    return images, img_info

def read_test_data(rootpath):
    """
    Function for reading the images for testing.
    :param rootpath:  path to the testing traffic sign data
    :return:          list of images, list of corresponding image information: width, height, class, filename
    """
    images = []     # images
    img_info = []   # corresponding labels
    gt_file = open(rootpath + '/GT-final_test.csv')                # annotations file
    gt_reader = csv.reader(gt_file, delimiter=';')                 # csv parser for annotations file
    next(gt_reader)                                                # skip header
    # loop over all images in current annotations file
    for row in gt_reader:
        images.append(plt.imread(rootpath + '/' + row[0]))         # numpy array representation of image
        img_info.append([int(row[1]), int(row[2]),
                         format(int(row[7]), '05d'), row[0][:5]])  # width, height, class, filename
    gt_file.close()
    return images, img_info

def make_square(image, img_info):
    """
    Function for transforming images into square shape by adding padding to the smallest dimension.
    :param image:     image to be transformed
    :param img_info:  image data containing width and height etc
    :return:          processed image of square shape
    """
    if img_info[0] == img_info[1]:  # if image is already square
        return image
    max_side = max(img_info[0], img_info[1])    # figure's maximum dimension size
    pad = PadIfNeeded(max_side, max_side)
    return pad(image=image)['image']    # add padding to least dimension so that its size becomes equal to max's one

def split_train_images(images, img_info):
    """
    Function for splitting images set into training and validation sets with 4 to 1 proportion.
    :param images:    set of images to be splitted
    :param img_info:  set of images' information to be splitted accordingly
    :return:          training and validation sets with their information sets
    """
    tracks_unique = list(set([img_i[2] + '_' + img_i[3] for img_i in img_info]))  # unique tracks' names among classes
    shuffle(tracks_unique)
    proportion = len(tracks_unique)//5  # 80%-20% proportion for train and validation tracks accordingly
    validation_tracks = tracks_unique[:proportion]  # set of unique track names for validation
    t_set, v_set, t_set_info, v_set_info = [], [], [], []
    # loop through the whole set
    for i, i_info in enumerate(img_info):
        if i_info[2] + '_' + i_info[3] in validation_tracks:    # if current image belongs to validation set's track
            v_set.append(images[i])
            v_set_info.append((i_info[2], i_info[3]))
        else:
            t_set.append(images[i])
            t_set_info.append((i_info[2], i_info[3]))
    return t_set, v_set, t_set_info, v_set_info

def show_class_frequencies(t_set_info, rootpath, set_name):
    """
    Function for calculating the frequencies for images of each certain class.
    :param t_set_info:  images set information
    :param rootpath:    path to images set
    :param set_name:    name of a set used
    :return:            frequencies of each class and lists of image indices by classes
    """
    freq = {img_class[:5]: 0 for img_class in os.listdir(rootpath)}
    img_indices_by_classes = {img_class[:5]: [] for img_class in os.listdir(rootpath)}
    # calculate frequencies of each class and collect lists of image indices by classes through given information set
    for i, (img_class, img_track) in enumerate(t_set_info):
        freq[img_class] += 1
        img_indices_by_classes[img_class].append(i)
    # plot the bar chart of calculated frequencies
    plt.bar(freq.keys(), freq.values(), color='orange')
    plt.xlabel("Classes")
    plt.xticks(rotation=65, fontsize=8)
    plt.ylabel("Amount of images")
    plt.title("Class frequencies in " + set_name + " set")
    plt.show()
    return freq, img_indices_by_classes

def augment_image(img, rotate, rand_brightness_contrast):
    """
    Function for augmenting single image.
    :param img:                       image to be augmented
    :param rotate:                    rotation function
    :param rand_brightness_contrast:  brightness & contrast altering function
    :return:                          augmented image
    """
    new_img = img.copy()
    # alter image's brightness on ±0.3 and contrast on ±0.2
    new_img = rand_brightness_contrast(image=new_img)['image']
    new_img = rotate(image=new_img)['image']  # rotate image on ±20deg
    return new_img

def augment_images(t_set, t_set_info, freq, img_indices_by_classes):
    """
    Function for images augmentation.
    :param t_set:                   training set of images
    :param t_set_info:              training set images information
    :param freq:                    frequencies of each class
    :param img_indices_by_classes:  lists of image indices by classes
    :return:                        nothing, data is processed by reference
    """
    rotate, rand_brightness_contrast = \
        Rotate(limit=20, p=1), RandomBrightnessContrast(brightness_limit=0.3, contrast_limit=0.2, p=1)
    max_num_images = max(freq.values())     # get maximum amount of images through all classes
    # loop through all image classes
    for img_class, num_of_images in freq.items():
        # add lacking amount of images to the training set
        for _ in range(max_num_images - num_of_images):
            index = choice(img_indices_by_classes[img_class])   # choose random image index of required class
            new_img = augment_image(t_set[index], rotate, rand_brightness_contrast)
            t_set.append(new_img)
            t_set_info.append((t_set_info[index][0], t_set_info[index][1]))

def get_test_set(rootpath, img_size):
    """
    Function for reading and processing test data.
    :param rootpath: path to test data
    :param img_size: size of images to be transformed to
    :return:         list of test images, list of corresponding image information: class, filename
    """
    test_set, test_set_info = read_test_data(rootpath)                                     # read test data images
    test_set = [make_square(image, test_set_info[i]) for i, image in enumerate(test_set)]  # make images square
    test_set = [resize(image, (img_size, img_size)) for image in test_set]                 # lead images to one size
    test_set_info = [(img_info[2], img_info[3]) for img_info in test_set_info]  # keep only image classes and filenames
    return test_set, test_set_info

def show_incorrect_prediction(img_set, correct_ans, pred_ans):
    """
    Function for detecting incorrect prediction and plotting incorrectly predicted image.
    :param img_set:      image set for taking the image from
    :param correct_ans:  correct predefined answers
    :param pred_ans:     predicted answers
    :return:             nothing
    """
    for i in range(len(correct_ans)):
        if correct_ans[i] != pred_ans[i]:
            print("Some incorrect prediction: expected", correct_ans[i], "received", pred_ans[i])
            plt.imshow(img_set[i])
            plt.title("Image predicted incorrectly: expected " + correct_ans[i] + " received " + pred_ans[i])
            plt.show()
            return

def show_recall_precision(set_to_predict_info, pred_set, classes):
    """
    Function for computing and plotting recall and precision.
    :param set_to_predict_info:  list of predefined truly correct answers
    :param pred_set:             list of predicted answers
    :param classes:              lists of classes
    :return:                     dictionaries with recall and precision scores by classes
    """
    recall = recall_score(set_to_predict_info, pred_set, average=None)
    precision = precision_score(set_to_predict_info, pred_set, average=None)
    # Plot recall bar chart
    plt.bar(classes, recall, color='orange')
    plt.xlabel("Classes")
    plt.xticks(rotation=65, fontsize=8)
    plt.ylabel("Recall score")
    plt.title("Recall score through classes")
    plt.show()
    # Plot precision bar chart
    plt.bar(classes, precision, color='blue')
    plt.xlabel("Classes")
    plt.xticks(rotation=65, fontsize=8)
    plt.ylabel("Precision score")
    plt.title("Precision score through classes")
    plt.show()
    return recall, precision

def train_model(img_size, augmented=True, test_data=True):
    """
    Function for training the model.
    :param img_size:   size of images to be transformed to
    :param augmented:  use augmentation technique on images or not
    :param test_data:  make predictions on test data or validation data
    :return:           nothing
    """
    init_time = time()
    # Step 1: Read all images from training dataset
    start_time = time()
    print("Step 1: Start reading all images from training dataset...")
    train_images, train_img_info = read_training_data(TRAINING_PATH)
    print("Step 1: Completed in", str(round(time() - start_time, 4)) + "s!")

    random_img_index = randrange(len(train_images))     # get index of random image from training dataset
    plt.imshow(train_images[random_img_index])  # plot image
    plt.title("Initial image")
    plt.show()

    # Step 2: Transform images to square shape
    start_time = time()
    print("Step 2: Start transforming images to square shape...")
    train_images = [make_square(image, train_img_info[i]) for i, image in enumerate(train_images)]
    print("Step 2: Completed in", str(round(time() - start_time, 4)) + "s!")

    plt.imshow(train_images[random_img_index])  # plot image made square
    plt.title("Image after making squared")
    plt.show()

    # Step 3: Transform images to same size
    start_time = time()
    print("Step 3: Start transforming images to same size...")
    train_images = [resize(image, (img_size, img_size)) for image in train_images]
    print("Step 3: Completed in", str(round(time() - start_time, 4)) + "s!")

    plt.imshow(train_images[random_img_index])  # plot image resized
    plt.title("Image after resizing")
    plt.show()

    # Step 4: Split data
    start_time = time()
    print("Step 4: Start splitting data...")
    train_set, valid_set, train_set_info, valid_set_info = split_train_images(train_images, train_img_info)
    print("Step 4: Completed in", str(round(time() - start_time, 4)) + "s!")

    # Choose between validation and test sets
    set_to_predict, set_to_predict_info = valid_set, valid_set_info
    if test_data:
        start_time = time()
        print("Start processing test data(reading, reshaping, resizing)...")
        set_to_predict, set_to_predict_info = get_test_set(TEST_PATH, img_size)
        print("Completed in", str(round(time() - start_time, 4)) + "s!")

    # Step 5: Find class frequencies in the resulting training set
    start_time = time()
    print("Step 5: Start finding class frequencies in the resulting training set...")
    frequencies, image_indices_by_classes = show_class_frequencies(train_set_info, TRAINING_PATH, "training")
    print("Step 5: Completed in", str(round(time() - start_time, 4)) + "s!")

    if augmented:
        # Step 6: Augmentation - produce synthetic images from the existing ones
        start_time = time()
        print("Step 6: Start augmentation process...")
        augment_images(train_set, train_set_info, frequencies, image_indices_by_classes)
        print("Step 6: Completed in", str(round(time() - start_time, 4)) + "s!")

        # plot augmented image
        plt.imshow(augment_image(train_images[random_img_index], Rotate(limit=20, p=1),
                                 RandomBrightnessContrast(brightness_limit=0.3, contrast_limit=0.2, p=1)))
        plt.title("Image after augmentation")
        plt.show()

    # Find class frequencies in set to predict
    start_time = time()
    print("Start finding class frequencies in set to predict...")
    image_indices_by_classes = show_class_frequencies(set_to_predict_info, TRAINING_PATH, "to predict")[1]
    print("Completed in", str(round(time() - start_time, 4)) + "s!")

    # Step 7: Find class frequencies in the resulting training set after augmentation
    start_time = time()
    print("Step 7: Start finding class frequencies in the resulting training set after augmentation...")
    show_class_frequencies(train_set_info, TRAINING_PATH, "augmented training")
    print("Step 7: Completed in", str(round(time() - start_time, 4)) + "s!")

    init_set_to_predict = set_to_predict  # save images set before normalization and transforming into matrix

    # Step 8: Normalize images from both training set and set to predict
    start_time = time()
    print("Step 8: Start normalizing images from both training set and set to predict...")
    train_set, set_to_predict = [img/255 for img in train_set], [img/255 for img in set_to_predict]
    print("Step 8: Completed in", str(round(time() - start_time, 4)) + "s!")

    # Step 9: Transform training set and set to predict into matrix containing each image as 1D vector
    start_time = time()
    print("Step 9: Start transforming training set and set to predict into matrix...")
    train_set, train_set_info = [np.ravel(img) for img in train_set], [img_info[0] for img_info in train_set_info]
    set_to_predict = [np.ravel(img) for img in set_to_predict]
    set_to_predict_info = [img_info[0] for img_info in set_to_predict_info]
    print("Step 9: Completed in", str(round(time() - start_time, 4)) + "s!")

    print("Total time spent on data preprocessing:", str(round(time() - init_time, 4)) + "s!")

    # Step 10: Train the model
    start_time = time()
    print("Step 10: Start training the model...")
    clf = RandomForestClassifier(n_estimators=200, n_jobs=-1)
    clf.fit(train_set, train_set_info)
    model_fit_time = round(time() - start_time, 4)
    print("Step 10: Completed in", str(model_fit_time) + "s!")

    # Step 11: Predict the data
    start_time = time()
    print("Step 11: Start predicting the data...")
    prediction = clf.predict(set_to_predict)
    print("Step 11: Completed in", str(round(time() - start_time, 4)) + "s!")

    # Step 12: Validate the model
    start_time = time()
    print("Step 12: Start validating the model...")
    accuracy = accuracy_score(set_to_predict_info, prediction)
    print("Model's accuracy:", accuracy)
    show_incorrect_prediction(init_set_to_predict, set_to_predict_info, prediction)
    classes_recall, classes_precision = \
        show_recall_precision(set_to_predict_info, prediction, image_indices_by_classes.keys())
    print("Model classes recall:", classes_recall, "\nModel classes precision:", classes_precision)
    print("Step 12: Completed in", str(round(time() - start_time, 4)) + "s!")

    print("\nTotal time spent:", str(round(time() - init_time, 4)) + "s.")

    return img_size, accuracy, model_fit_time

# list containing models' accuracy and overall model fit time
models_info = [
    train_model(30, test_data=False),  # train model on 30x30 images and validate using validation set
    train_model(30, augmented=False),  # train model on 30x30 images without augmentation, and validate using test set
    train_model(30),                   # train model on 30x30 images and validate using test set
    train_model(35),
    train_model(40),
    train_model(45),
    train_model(50)
][2:]

# plot precision score depending on image size
plt.plot([info[0] for info in models_info], [info[1] for info in models_info], color='orange')
plt.xlabel("Image sizes")
plt.ylabel("Accuracy score")
plt.title("Accuracy score depending on image size")
plt.show()

# plot model fit time depending on image size
plt.plot([info[0] for info in models_info], [info[2] for info in models_info], color='blue')
plt.xlabel("Image sizes")
plt.ylabel("Model fit time")
plt.title("Model fit time depending on image size")
plt.show()


import jinja2
from bs4 import BeautifulSoup
import os
from tqdm import *

env = jinja2.Environment(loader=jinja2.FileSystemLoader("./"))

for template in tqdm(os.listdir("./")):
    if template.endswith(".html"):
        if template == "index.html":
            outfile = "../index.html"
        else:
            outfile = "../pages/" + template

        template = BeautifulSoup(env.get_template(template).render(), "html.parser").prettify()
        with open(outfile, "w") as output:
            output.write(template)


# ===================================================================
# Author(s):
#
#       Name        Email
#      Jon Perry    dcjmp90@gmail.com
#
# Notes:
#
#   This will hold subclasses of the Abstract Config class
# ===================================================================
"""A Config class for item lookup"""

import bs4 as bs
import urllib.request as url_request
from sanctuary.utils.config.base_config import BaseConfig
from sanctuary.utils.modules.search_module import ItemSearchModule
from sanctuary.utils.parser.cli_arguments import Map

__all__ = ['ItemLookupConfig']

class ItemLookupConfig(BaseConfig):
    """A processor for bot data

    Performs various bot tasks like look up
    of item stats or look up of names of runes.
    Anything that is within the diablo 2 database.

    Parameters
    ----------

    bot_name : str
        The name for the lookup bot

    prefix : str
        The type of prefix to filter in discord

    args : Values objects from builtin
        This will be all the argsparser arguments

    Notes
    -----

    currently only building a single lookup bot, but this may change
    based on needs, the lookups may need to be delegated to many.

    Usage
    -----

    ?<item_type> -- bs4.BeautifulSoup object parse of <item_type>
            will return an array-like structure of all of this <item_type>

    ?<item_type> <item_name> stats -- bs4.BeautifulSoup object parse of <item_name>
            will return stats of <item_name>

    ?<item_type> <item_name> requirements -- bs4.BeautifulSoup object parse of <item_name>
            will return requirements of <item_name>

    >>> ?runewords spirit requirements
    ... returns: lvl. 25, 4 Socket Sword/Shield, Tal->Thul->Ort->Amn

    >>> ?runewords spirit stats
    ...
    """

    def __init__(self,
                 bot_name,
                 args,
                 prefix='?',
    ):
        self.bot_name = bot_name
        self.prefix = prefix
        self.args = args
        super().__init__(self.bot_name,
                         self.prefix,
                         self.args,
        )

        self.searchables = [ v for k, v in self.SEARCH_ITEMS.items() ]
        self.bs_parser = Map({})
        self.searchable = ItemSearchModule(self.config)

        for name in self.searchables:
            url = url_request.urlopen(self.args.BASE_URL+name)
            self.bs_parser[name] = bs.BeautifulSoup(url.read(), self.config.PARSER)

    def _item_type(self, item_type):
        """Parser for all of type"""

        if item_type.lower() in self.bs_parser.keys():
            _bs_parser = self.bs_parser[item_type.lower()]

            items = _bs_parser.findAll(self.config.CONTAINER)
            return items
        else:
            return None

    def __call__(self,
                 item_type,
                 item_name = None,
                 item_spec = None,
                 **kwargs,
    ):
        """Override of the call method"""
        parent_container = self._item_type(item_type)

        if parent_container is None:
            raise ValueError('No known item of type {}. KYS.'.format(item_type))
        else:
            return self.searchable(parent_container,
                                   item_name,
                                   item_spec,
                                   **kwargs)


import csv
from werkzeug.utils import secure_filename
from flask import Blueprint,request,jsonify,render_template,redirect,url_for,Response
from sqlalchemy import exc
from models import Cliente,Tipo_Cliente
from app import db,bcrypt
from auth import tokenCheck,Verificar,admin
from forms import clienteForm
from io import StringIO

appcliente=Blueprint('appcliente',__name__,template_folder="templates")

@appcliente.route('/')
@tokenCheck
def inicio():
    ad = admin()
    return render_template("index.html",exit=True,admon=ad)

@appcliente.route('/listadocliente')
@tokenCheck
def listado_clientes(data=None):
    ad = admin()
    resultado = db.session.query(Cliente, Tipo_Cliente).join(Tipo_Cliente).filter(Cliente.tipo_clientes_id == Tipo_Cliente.id).order_by(Cliente.id).all()
    Clientes = []
    for cliente,tipo_cliente in resultado:
        nuevocliente = Cliente(id=cliente.id,nombre=cliente.nombre,telefono=cliente.telefono,email=cliente.email,direccion=cliente.direccion,RFC=cliente.RFC,tipoCliente=tipo_cliente.nombre)
        Clientes.append(nuevocliente)
    return render_template('listcliente.html',clientes=Clientes,exit=True,admon=ad)

@appcliente.route('/agregarcliente',methods=["POST","GET"])
@tokenCheck
def agregar_cliente(data=None):
    ad = admin()
    if request.method == "POST":
        Nombre = request.form.get('nombre')
        Telefono = request.form.get('telefono')
        Email = request.form.get('email')
        Direccion = request.form.get('direccion')
        RFC = request.form.get('RFC')
        TipoCliente = request.form.get('tipo_clientes_id')
        print(Nombre,Email,Telefono,RFC,Direccion,TipoCliente)
        clientenuevo = Cliente(nombre=Nombre,telefono=Telefono,email=Email,direccion=Direccion,RFC=RFC,tipoCliente=TipoCliente)
        db.session.add(clientenuevo)
        db.session.commit()
        return redirect(url_for('appcliente.listado_clientes'))
    else:
        Tipo_Clientes = Tipo_Cliente.query.all()
        print(Tipo_Clientes)
        return render_template('postcliente.html',tipo_clientes = Tipo_Clientes,exit=True,admon=ad)

@appcliente.route('/detallescliente/<int:id>')
@tokenCheck
def detalles_cliente(cliente_data,id):
    ad = admin()
    cliente = Cliente.query.get_or_404(id)
    resultado = db.session.query(Cliente, Tipo_Cliente).join(Tipo_Cliente).filter(Cliente.id == cliente.id).first()

    nuevocliente = Cliente(id=resultado[0].id,nombre=resultado[0].nombre,telefono=resultado[0].telefono,email=resultado[0].email,direccion=resultado[0].direccion,RFC=resultado[0].RFC,tipoCliente=resultado[1].nombre)
    Clientes = [nuevocliente]
    return render_template('getcliente.html',cliente=nuevocliente,exit=True,admon=ad)

@appcliente.route('/modificarcliente/<int:id>',methods=["POST","GET"])
@tokenCheck
def modificar_cliente(cliente_data,id):
    ad = admin()
    cliente = Cliente.query.get_or_404(id)
    print(cliente)
    formacliente = clienteForm(obj=cliente)
    if request.method == "POST":
        formacliente.populate_obj(cliente)
        db.session.commit()
        return redirect(url_for('appcliente.listado_clientes'))
    Tipo_Clientes = Tipo_Cliente.query.all()
    return render_template('putcliente.html',cliente = cliente,tipo_clientes = Tipo_Clientes,exit=True,admon=ad)

@appcliente.route('/testjoin')
def test():

    resultado = db.session.query(Cliente, Tipo_Cliente).join(Tipo_Cliente).filter(Cliente.tipo_clientes_id == Tipo_Cliente.id).all()
    print(resultado)
    Clientes = []
    for cliente,tipo_cliente in resultado:
        nuevocliente = Cliente(id=cliente.id,nombre=cliente.nombre,telefono=cliente.telefono,email=cliente.email,direccion=cliente.direccion,RFC=cliente.RFC,tipoCliente=tipo_cliente.nombre)
        Clientes.append(nuevocliente)
    #nuevocliente = Cliente(id=resultado[0].id,nombre=resultado[0].nombre,telefono=resultado[0].telefono,email=resultado[0].email,direccion=resultado[0].direccion,RFC=resultado[0].RFC,tipoCliente=resultado[1].nombre)
    print(Clientes)
    respuesta = jsonify({"res": "200"})
    return respuesta

def process_csv_content(content):
    csv_reader = csv.reader(content)
    # Skip the header row
    next(csv_reader)
    for row in csv_reader:
        # Assuming the CSV columns order matches the order in the database model
        nombre,telefono,email,direccion,RFC,tipo_cliente_id = row
        # Convert necessary fields to appropriate types (e.g., int, float, datetime)
        # ...

        # Create a new Servicio instance and insert it into the database
        nuevo_cliente = Cliente(nombre=nombre,telefono=telefono,email=email,direccion=direccion,RFC=RFC,tipoCliente=tipo_cliente_id)
        db.session.add(nuevo_cliente)

    # Commit changes to the database
    db.session.commit()

@appcliente.route('/upload-csv', methods=['POST'])
def upload_csv():
    # Assuming the file is sent as part of the POST request
    file = request.files['file']
    if file and file.filename.endswith('.csv'):
        # Read the content of the uploaded file
        file_content = file.read().decode('utf-8')
        # Use StringIO to create a file-like object in memory
        csv_content = StringIO(file_content)
        # Process the CSV content and insert rows into the database
        process_csv_content(csv_content)
        # Return a response indicating success
        return redirect(url_for('appcliente.listado_clientes'))
    else:
        # Return an error response if the uploaded file is not a CSV
        return redirect(url_for('appcliente.listado_clientes'))


from copy import deepcopy
from typing import Dict

import pytest
import torch.distributed as dist

from pipegoose.distributed.parallel_mode import ParallelMode
from pipegoose.nn.pipeline_parallel.sync.callback import Callback
from pipegoose.nn.pipeline_parallel.sync.handshake import (
    ProgressTracker,
    get_progress_tracker,
)
from pipegoose.testing.utils import init_parallel_context, spawn

MASTER_RANK = 0

def generate_unfinished_tasks(n):
    # {0: {0: False, 1: False, 2: False, 3: False, 4: False},...}
    return {i: {j: False for j in range(n)} for i in range(n)}

def generate_finsihed_task(n):
    # {0: {0: True, 1: True, 2: True, 3: True, 4: True},...}
    return {i: {j: True for j in range(n)} for i in range(n)}

def run_init_progress_tracker(rank, world_size, port, tensor_parallel_size, pipeline_parallel_size, data_parallel_size):
    PROGRESS = generate_unfinished_tasks(n=world_size)

    parallel_context = init_parallel_context(
        rank, world_size, port, tensor_parallel_size, pipeline_parallel_size, data_parallel_size
    )
    tracker = ProgressTracker(MASTER_RANK, parallel_context=parallel_context, parallel_mode=ParallelMode.GLOBAL)

    tracker.initiate(PROGRESS)

    # NOTE: wait until the tracker is initiated
    dist.barrier()

    assert tracker.is_initiated() is True
    assert tracker.clock_idx == 0
    assert tracker.is_all_confirmed(clock_idx=0) is False
    assert tracker.progress == PROGRESS

    # NOTE: progress tracker should be set to global variable
    # this used in pipeline engine
    assert get_progress_tracker() == tracker

    parallel_context.destroy()

def test_init_progress_tracker():
    TENSOR_PARALLEL_SIZE = 2
    PIPELINE_PARALLEL_SIZE = 2
    DATA_PARALLEL_SIZE = 2
    world_size = TENSOR_PARALLEL_SIZE * PIPELINE_PARALLEL_SIZE * DATA_PARALLEL_SIZE

    spawn(
        run_init_progress_tracker,
        world_size=world_size,
        tensor_parallel_size=TENSOR_PARALLEL_SIZE,
        pipeline_parallel_size=PIPELINE_PARALLEL_SIZE,
        data_parallel_size=DATA_PARALLEL_SIZE,
    )

def run_confirm_progress_tracker(rank, world_size, port, tensor_parallel_size, pipeline_parallel_size, data_parallel_size):
    N_CLOCK_CYCLES = world_size
    PROGRESS = generate_unfinished_tasks(N_CLOCK_CYCLES)
    FINAL_PROGRESS = generate_finsihed_task(N_CLOCK_CYCLES)
    INITIAL_PROGRESS = deepcopy(PROGRESS)

    parallel_context = init_parallel_context(
        rank, world_size, port, tensor_parallel_size, pipeline_parallel_size, data_parallel_size
    )
    tracker = ProgressTracker(MASTER_RANK, parallel_context=parallel_context, parallel_mode=ParallelMode.GLOBAL)

    if rank == tracker.master_rank:
        tracker.initiate(PROGRESS)

    # NOTE: wait until the tracker is initiated
    dist.barrier()

    for clock_idx in range(N_CLOCK_CYCLES):
        tracker.confirm(rank)
        assert tracker.is_confirmed(rank, clock_idx=clock_idx) is True

        # NOTE: wait until all workers are confirmed
        dist.barrier()
        assert tracker.is_all_confirmed(clock_idx=clock_idx) is True

        if not (clock_idx == N_CLOCK_CYCLES - 1):
            assert tracker.is_all_confirmed(clock_idx=clock_idx + 1) is False

        assert tracker.clock_idx == clock_idx + 1
        assert tracker.progress != INITIAL_PROGRESS

    assert tracker.progress == FINAL_PROGRESS

    parallel_context.destroy()

@pytest.mark.parametrize("tensor_parallel_size, pipeline_parallel_size, data_parallel_size", [(1, 2, 1), (1, 4, 1), (2, 2, 2)])
def test_confirm_progress_tracker(tensor_parallel_size, pipeline_parallel_size, data_parallel_size):
    world_size = tensor_parallel_size * pipeline_parallel_size * data_parallel_size

    spawn(
        run_confirm_progress_tracker,
        world_size=world_size,
        tensor_parallel_size=tensor_parallel_size,
        pipeline_parallel_size=pipeline_parallel_size,
        data_parallel_size=data_parallel_size,
    )

def run_progress_tracker_callback(rank, world_size, port, tensor_parallel_size, pipeline_parallel_size, data_parallel_size):
    QUEUE = []

    class TestCallback(Callback):
        def after_new_clock_cycle(self, progress: Dict, clock_idx: int):
            QUEUE.append(rank)

    PROGRESS = generate_unfinished_tasks(n=world_size)

    parallel_context = init_parallel_context(
        rank, world_size, port, tensor_parallel_size, pipeline_parallel_size, data_parallel_size
    )
    tracker = ProgressTracker(
        MASTER_RANK, callbacks=[TestCallback()], parallel_context=parallel_context, parallel_mode=ParallelMode.GLOBAL
    )

    if rank == MASTER_RANK:
        tracker.initiate(PROGRESS)

    # NOTE: wait until the tracker is initiated
    dist.barrier()
    tracker.confirm(rank)

    # NOTE: wait until all workers are confirmed
    # callback should be called again after all workers are confirmed
    dist.barrier()
    assert QUEUE == [rank]

    parallel_context.destroy()

def test_progress_tracker_callback():
    TENSOR_PARALLEL_SIZE = 2
    PIPELINE_PARALLEL_SIZE = 2
    DATA_PARALLEL_SIZE = 2
    world_size = TENSOR_PARALLEL_SIZE * PIPELINE_PARALLEL_SIZE * DATA_PARALLEL_SIZE

    spawn(
        run_progress_tracker_callback,
        world_size=world_size,
        tensor_parallel_size=TENSOR_PARALLEL_SIZE,
        pipeline_parallel_size=PIPELINE_PARALLEL_SIZE,
        data_parallel_size=DATA_PARALLEL_SIZE,
    )


'''import time
#拼接符的效率更低，循环一次就要创建一个对象
time01 = time.time()
a = ''
for i in range(100000):
    a = a +"he"
time02 = time.time()
print("运算时间为：",(time02-time01))

#join效率更高，始终只有一个对象
time03 = time.time()
li=[]
for i in range(100000):
    li.append("Test")
b = "".join(li)
time04 = time.time()
指定保留小数点后面几
print("运算时间为：",format(time04-time03,'.5f'))'''

score = int(input("请输入一个在0-100 之间的数字："))
grade = ""
while score>100 or score<0:
    score = int(input("输入错误！请重新输入一个在0-100 之间的数字："))
if score>=90:
    grade = "A"
elif score>=80:
    grade = 'B'
elif score>=70:
    grade = 'C'
elif score>=60:
    grade = 'D'
else:
    grade = 'E'
print("分数为{0},等级为{1}".format(score,grade))

python练习/字符串的分割练习.py


"""
    Ejemplo 05
    Uso del ciclo for
"""
# Ingreso de datos por teclado
tabla = int(input("Ingrese hasta que número de tabla desea generar: "))
limite = int(input("Ingrese el límite de cada tabla: "))

# uso ciclo repetitivo for con un for interno
for i in range(1, tabla+1):
    print("Tabla del número %s" % (i))
    for j in range(1, limite+1):
        valor = i * j
        print("%d * %d = %d" %(i, j, valor))
    print()


# -*- coding: utf-8 -*-
#!/usr/bin/env python
#   Author: WildfootW
#

from vpython import *

ball_radius = 0.05
ball_mass = 0.2
ball_init_position_relative_x = [-0.06, 0, -0.1]
group_init_position_absolute_z = [-3 * ball_radius, 0 * ball_radius, 3 * ball_radius]
ball_init_velocity = [vec(1, 0, 0), vec(2, 0, 0), vec(2.2, 0, 0)]
groups_amount = 3
spring_origin_length = 0.5
spring_constant = [15, 12, 17]

# constant
gravity = vec(0, -1 * 9.80665, 0)

# scene
scene = canvas(width = 800, height = 600,     # unit: pixels
               center = vec(0, 0.2, 0),        # camera will continually look to center
               background = vec(0.10546875, 0.38671875, 0.17968750))
et_graph = graph(width = 800, height = 600,
                 title = "Energy - Time",
                 xtitle = "time (s)", ytitle = "energy (J)")
aet_graph = graph(width = 800, height = 600,
                  title = "Average Energy - Time",
                  xtitle = "time (s)", ytitle = "average energy (J/s)")
et_curve_kinetic    = gcurve(graph = et_graph,  color = color.blue, width = 4)
et_curve_potential  = gcurve(graph = et_graph,  color = color.red,  width = 4)
aet_curve_kinetic   = gcurve(graph = aet_graph, color = color.blue, width = 4)
aet_curve_potential = gcurve(graph = aet_graph, color = color.red,  width = 4)

# object
#title_text = text(text = "Three balls doing horizontal SHMs", align = "center") # read-only
floor = box(length = 0.8, width = 0.8, height = 0.1, color = color.black)
wall  = box(length = 0.1, width = 0.8, height = 0.1, color = color.gray(0.5))
balls = []
for i in range(groups_amount):
    ball = sphere(radius = ball_radius, color = color.orange)
    balls.append(ball)
springs = []
for i in range(groups_amount):
    spring = helix(radius = 0.02, thickness = 0.01)
    spring.k = spring_constant[i]
    springs.append(spring)

# init status
#title_text.pos = vec(0, scene.center.y * 2, 0)
floor.pos = vec(0, (floor.height / 2) * -1, 0)
wall.pos = vec((floor.length / 2 - wall.length / 2) * -1, wall.height / 2, 0)
for i in range(groups_amount):
    balls[i].pos = vec(wall.pos.x + wall.length / 2 + spring_origin_length + ball_init_position_relative_x[i], balls[i].radius, group_init_position_absolute_z[i])
    balls[i].v = ball_init_velocity[i]
for i in range(groups_amount):
    springs[i].pos = vec(wall.pos.x + wall.length / 2, balls[i].radius, group_init_position_absolute_z[i])
    springs[i].axis = balls[i].pos - springs[i].pos
current_time = 0
total_kinetic = 0
total_potential = 0

#time.sleep(3) # let vpython load init state

# sport
dt = 10 ** -3
while True:
    rate(1 / dt) # limit execute amount in 1 second
    current_time = current_time + dt

    sum_kinetic = 0
    sum_potential = 0

    for i in range(groups_amount):
        balls[i].pos = balls[i].pos + balls[i].v * dt
        springs[i].axis = balls[i].pos - springs[i].pos

        spring_force = springs[i].k * (mag(springs[i].axis) - spring_origin_length) * norm(springs[i].axis) * -1
        balls[i].a = spring_force / ball_mass
        balls[i].v = balls[i].v + balls[i].a * dt
        balls[i].kinetic = 0.5 * ball_mass * pow(mag(balls[i].v), 2)
        balls[i].potential = 0.5 * springs[i].k * pow(mag(springs[i].axis) - spring_origin_length, 2)
        sum_kinetic += balls[i].kinetic
        sum_potential += balls[i].potential

    et_curve_kinetic.plot(pos = (current_time, sum_kinetic))
    et_curve_potential.plot(pos = (current_time, sum_potential))
    total_kinetic += sum_kinetic
    total_potential += sum_potential
    aet_curve_kinetic.plot(pos = (current_time, total_kinetic / current_time))
    aet_curve_potential.plot(pos = (current_time, total_potential / current_time))

    summarize =  "The average kinetic is " + str(total_kinetic / current_time) + " (J/s). "
    summarize += "The average potential is " + str(total_potential / current_time) + " (J/s).\n"
    scene.caption = summarize

'''
print(summarize)

# show answer in scene
# warning: if the text is too long, it take vpython long time to render and sometimes will cause some problem
text(text = "Displacement: " + str(ball.pos - ball_init_position) + " (m)", pos = vec(-2, 12, 0), align = "left")
text(text = "Max height: " + str(ball_max_height) + " (m)", pos = vec(-2, 10, 0), align = "left")
'''


# -*- coding: utf-8 -*-
'''
Created on 2016年11月26日

@author: zqh

对应 GT 进程，实际的桌子实例房间进程
'''

from freetime5.util import ftlog
from majiang2.plugins.srvtable.srvtable import Mj2PluginSrvTable
from tuyoo5.core import tychecker
from tuyoo5.core import tygame
from tuyoo5.core import tyglobal
from tuyoo5.core import typlugin
from xuezhan.plugins.srvtable._private import _checkers

_DEBUG = 1

if _DEBUG:
    def debug(*argl, **argd):
        ftlog.debug(*argl, **argd)
else:
    def debug(*argl, **argd):
        pass

class Mj2XueZhanPluginSrvTable(Mj2PluginSrvTable):

    def __init__(self):
        super(Mj2XueZhanPluginSrvTable, self).__init__()
        self.checker1 = tychecker.Checkers(
            tychecker.check_userId,
            tychecker.check_gameId,
            tychecker.check_clientId,
            _checkers.check_roomId,
        )
        self.checker2 = tychecker.Checkers(
            tychecker.check_userId,
            tychecker.check_gameId,
            tychecker.check_clientId,
            _checkers.check_roomId,
            _checkers.check_tableId,
            _checkers.check_seatId0,
        )
        self.checker3 = tychecker.Checkers(
            tychecker.check_userId,
            tychecker.check_gameId,
            tychecker.check_clientId,
            _checkers.check_roomId,
            _checkers.check_tableId,
            _checkers.check_seatIdObserver,
            _checkers.check_action,
        )

    def destoryPlugin(self):
        super(Mj2XueZhanPluginSrvTable, self).destoryPlugin()

    @typlugin.markPluginEntry(initBeforeConfig=[tyglobal.SRV_TYPE_GAME_TABLE])
    def initPluginBefore(self):
        super(Mj2XueZhanPluginSrvTable, self).initPluginBefore()

    @typlugin.markPluginEntry(cmd="room/vipTableList", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
    def doRoomVipTableList(self, msg):
        if _DEBUG:
            debug('doRoomVipTableList->', msg)
        mi = self.checker1.check(msg)
        if mi.error:
            ftlog.error('doRoomVipTableList the msg params error !', mi.error)
        else:
            room = tyglobal.rooms()[mi.roomId]
            room.doGetVipTableList(mi.userId, mi.clientId)
        return 1

# 需要转换为RPC模式
#     @typlugin.markPluginEntry(cmd="room/playingTableList", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
#     def doRoomGetPlayingTableList(self, msg):
#         ftlog.debug('msg=', msg, caller=self)
#         result = gdata.rooms()[roomId].doGetPlayingTableList()
#         if router.isQuery():
#             mo = MsgPack()
#             mo.setCmd("room")
#             mo.setResult("action", "playingTableList")
#             mo.updateResult(result)
#             router.responseQurery(mo)

#     @typlugin.markPluginEntry(cmd="room/rank_list", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
#     def doRoomRankList(self, msg):
#         ftlog.debug('msg=', msg, caller=self)
#         gdata.rooms()[roomId].doGetRankList(userId, msg)

#     @typlugin.markPluginEntry(cmd="room/change_betsConf", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
#     def doRoomChangeBetsConf(self, msg):
#         ftlog.debug('msg=', msg, caller=self)
#         betsConf = msg.getParam("betsConf")
#         gdata.rooms()[roomId].doChangeBetsConf(betsConf)

    @typlugin.markPluginEntry(cmd="table/enter", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
    def doTableEnter(self, msg):
        if _DEBUG:
            debug('doTableEnter->', msg)
        mi = self.checker2.check(msg)
        if mi.error:
            ftlog.error('doTableEnter the msg params error !', mi.error)
        else:
            room = tyglobal.rooms()[mi.roomId]
            table = room.maptable[mi.tableId]
            table.doEnter(msg,
                          mi.userId,
                          mi.clientId)
        return 1

    @typlugin.markPluginEntry(cmd="table/leave", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
    def doTableLeave(self, msg):
        if _DEBUG:
            debug('doTableLeave->', msg)
        mi = self.checker2.check(msg)
        if mi.error:
            ftlog.error('doTableLeave the msg params error !', mi.error)
        else:
            room = tyglobal.rooms()[mi.roomId]
            table = room.maptable[mi.tableId]
            table.doLeave(msg,
                          mi.userId,
                          mi.clientId)
        return 1

    @typlugin.markPluginEntry(cmd="table/sit", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
    def doTableSit(self, msg):
        if _DEBUG:
            debug('doTableSit->', msg)
        mi = self.checker2.check(msg)
        if mi.error:
            ftlog.error('doTableSit the msg params error !', mi.error)
        else:
            room = tyglobal.rooms()[mi.roomId]
            table = room.maptable[mi.tableId]
            table.doSit(msg,
                        mi.userId,
                        mi.seatId0,
                        mi.clientId)
        return 1

    @typlugin.markPluginEntry(cmd="table/stand_up", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
    def doTableStandUp(self, msg):
        '''
        此命令一定是由客户端发送的命令, 如果是内部控制命令,那么需要进行区分命令,不能混合调用
        主要是为了避免站起的原因混乱,
        '''
        if _DEBUG:
            debug('doTableStandUp->', msg)
        mi = self.checker2.check(msg)
        if mi.error:
            ftlog.error('doTableStandUp the msg params error !', mi.error)
        else:
            room = tyglobal.rooms()[mi.roomId]
            table = room.maptable[mi.tableId]
            table.doStandUp(msg,
                            mi.userId,
                            mi.roomId,
                            mi.tableId,
                            mi.seatId0,
                            tygame.TableStandUpEvent.REASON_USER_CLICK_BUTTON,
                            mi.clientId)
        return 1

    @typlugin.markPluginEntry(cmd="table_call/*", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
    def doTableCall(self, msg):
        if _DEBUG:
            debug('doTableCall->', msg)
        mi = self.checker3.check(msg)
        if mi.error:
            ftlog.error('doTableCall the msg params error !', mi.error)
        else:
            room = tyglobal.rooms()[mi.roomId]
            table = room.maptable[mi.tableId]
            table.doTableCall(msg, mi.userId, mi.seatIdObserver, mi.action, mi.clientId)
        return 1

    @typlugin.markPluginEntry(cmd="table_manage/*", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
    def doTableManage(self, msg):
        # TODO 转换为RPC模式
        if _DEBUG:
            debug('doTableManage->', msg)
        mi = self.checker3.check(msg)
        if mi.error:
            ftlog.error('doTableManage the msg params error !', mi.error)
        else:
            room = tyglobal.rooms()[mi.roomId]
            table = room.maptable[mi.tableId]
            table.doTableManage(msg, mi.action)
        return 1

#     @typlugin.markPluginEntry(cmd="room/detail_infos", srvType=tyglobal.SRV_TYPE_GAME_TABLE)
#     def getRoomOnlineInfoDetails(self, msg):
#         cp = gdata.curProcess.cpu_percent()
#         datas = {'cpu': cp}
#         if roomId in gdata.rooms():
#             room = gdata.rooms()[roomId]
#             ucount, pcount, users = room.getRoomOnlineInfoDetail()
#             datas[roomId] = [ucount, pcount, users]
#         else:
#             datas[roomId] = 'not on this server'
#         msg.setResult('datas', datas)
#         return msg


# Filename: Export List of US WSOC
# Version: 1.0
# Date: Sept 2022
# Description: Scrapes Wikipedia. Exports CSV list of women's soccer programs in the US.

import pandas as pd

def menu():
    print("\n*** MAIN MENU ***\n\n [1] Create D1 Sheet\n [2] Create D2 Sheet\n [3] Create D3 Sheet\n [4] Create NAIA Sheet\n [5] Quit\n")

def d1():
    wiki_url = 'https://en.wikipedia.org/wiki/List_of_NCAA_Division_I_women%27s_soccer_programs'
    df = pd.read_html(wiki_url)
    df[0].to_csv('wsoc_d1.csv', index=False)
    print("\n....... D1 table created!\n\n")

def d2():
    wiki_url = 'https://en.wikipedia.org/wiki/List_of_NCAA_Division_II_women%27s_soccer_programs'
    df = pd.read_html(wiki_url)
    df[0].to_csv('wsoc_d2.csv', index=False)
    print("\n....... D2 table created!\n\n")

def d3():
    wiki_url = 'https://en.wikipedia.org/wiki/List_of_NCAA_Division_III_institutions'
    df = pd.read_html(wiki_url)
    df[0].to_csv('wsoc_d3.csv', index=False)
    print("\n....... D3 table created!\n\n")

def naia():
    wiki_url = 'https://en.wikipedia.org/wiki/List_of_NAIA_institutions'
    df = pd.read_html(wiki_url)
    df[0].to_csv('wsoc_naia.csv', index=False)
    print("\n....... NAIA table created!\n\n")

while True:
    menu()
    option = input("Enter choice >> ")

    if option=="1":
        d1()
    elif option=="2":
        d2()
    elif option=="3":
        d3()
    elif option=="4":
        naia()
    elif option=="5":
        print("Goodbye.")
        break
    else:
        menu()
    #except ValueError:
     #   print("Invalid choice. Enter number 1-5.")
exit


"""
Django settings for {{cookiecutter.package_name}} project.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os

SECRET_KEY = os.getenv('DJANGO_SECRET', 'open_secret')

# Application definition

INSTALLED_APPS = (
    'statici18n',
    '{{cookiecutter.package_name}}',
)

# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'

# statici18n
# http://django-statici18n.readthedocs.io/en/latest/settings.html

STATICI18N_DOMAIN = 'text'
STATICI18N_PACKAGES = (
    '{{cookiecutter.package_name}}.translations',
)
STATICI18N_ROOT = '{{cookiecutter.package_name}}/public/js'
STATICI18N_OUTPUT_DIR = 'translations'


# 19:35-20:34
# My Solution
# - 처리하기 쉽게 시계방향 90도로 돌리고 시작함
# - DP array를 만들고, 각 위치에 가능한 경우 중 최대값을 계속 기록
# - DP[r][c] = max(DP[r-1][c + dc] + A[r][c])
# where dc = [-1, 0, 1], 단, 0 <= dc + c <= n
# - 마지막 행의 최대값을 출력

def rotate_a_mtx_by_90_degree(a):
    n = len(a)
    m = len(a[0])
    result = [[0] * n for _ in range(m)] # 결과 리스트
    # Transpose 후에 각 열의 원소를 뒤집는 것
    for i in range(n):
        for j in range(m):
            result[j][n - i - 1] = a[i][j]
    return result

# column의 이동
diff = [-1, 0, 1]

t = int(input())

for _ in range(t):

    n, m = map(int, input().split())
    case = list(map(int, input().split()))
    data = [ [0] * m for _ in range(n) ]

    for i, e in enumerate(case):
        row = i // m
        col = i % m
        data[row][col] = e

    rotate_90 = rotate_a_mtx_by_90_degree(data)
    dp = [ [0] * n for _ in range(m)]
    dp[0] = rotate_90[0]

    for r in range(1, m):
        cur_row = rotate_90[r]
        for c, cur_rc_value in enumerate(cur_row):
            max_value = 0
            max_idx = 0
            # 직전 행에서 가능한 계산 범위에 대해 모두 계산하며 최대값을 갱신
            for d in diff:
                prev_c = c + d
                # 범위가 벗어나는 경우는 제외
                if 0 <= prev_c and prev_c < n:
                    cur_sum = dp[r-1][prev_c] + cur_rc_value
                    dp[r][c] = max(dp[r][c], cur_sum)

    print(max(dp[m-1]))

# Solution
for tc in range(int(input())):
    # 금광 정보 입력
    n, m = map(int, input().split())
    array = list(map(int, input().split()))

    # 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화
    dp = []
    index = 0
    for i in range(n):
        dp.append(array[index:index + m])
        index += m

    # 다이나믹 프로그래밍 진행
    for j in range(1, m):
        for i in range(n):
            # 왼쪽 위에서 오는 경우
            if i == 0:
                left_up = 0
            else:
                left_up = dp[i - 1][j - 1]

            # 왼쪽 아래에서 오는 경우
            if i == n - 1:
                left_down = 0
            else:
                left_down = dp[i + 1][j - 1]

            # 왼쪽에서 오는 경우
            left = dp[i][j - 1]
            dp[i][j] = dp[i][j] + max(left_up, left_down, left)

    result = 0
    for i in range(n):
        result = max(result, dp[i][m - 1])

    print(result)


foot=inch=0
Centimeter=meter=0
footToMeter=footToCentimeter=inchToMeter=inchToCentimeter=0
def read():
    foot=int(input('Enter Foot : '))
    inch=int(inch('Enter inch : '))
def calculate ():
    footToMeter=0.3048*foot
    footToCentimeter=100*footToMeter
    inchToMeter=(1.0/12)*0.3048*inch
    inchToCentimeter=100*inchToMeter
def write():
    print('The ',foot,' foot is ',footToMeter,' meter')
    print('The ',foot,' foot is ',footToCentimeter,' Centimeter')
    print('The ',inch,' inch is ',inchToMeter,'meter' )
    print('The ',inch,' inch is ',inchToCentimeter,'centimeter')
def main():
    read()
    calculate()
    write()
main()

python/Python/Python (Computer program language) -- Problems/20_1_convertInchesToMillimeters.py


# https://codeforces.com/contest/1593/problem/C

import sys

def sol(n, seq):
    dst = [n - item for item in seq]
    dst.sort(reverse=True)
    sm, t = 0, 0
    while sm < n:
        if len(dst) > 0:
            v = dst.pop()
            if sm + v < n:
                sm += v
                t += 1
            else:
                break
        else:
            break
    return t

inp = [list(map(int, line.strip().split())) for line in sys.stdin]

for i in range(1, len(inp), 2):
    n, _ = inp[i]
    seq = inp[i+1]
    print(sol(n, seq))


import torch

class CircleLoss(torch.nn.Module):
    def __init__(self, m=0.25, gamma=256):
        super(CircleLoss, self).__init__()
        self.m = m
        self.gamma = gamma
        self.loss = torch.nn.CrossEntropyLoss()

    def forward(self, logits, labels):
        alpha = torch.clamp_min(logits + self.m, min=0).detach()
        alpha[labels] = torch.clamp_min(-logits[labels] + 1 + self.m, min=0).detach()
        delta = torch.ones_like(logits, device=logits.device, dtype=logits.dtype) * self.m
        delta[labels] = 1 - self.m
        return self.loss(alpha * (logits - delta) * self.gamma, labels)

from matplotlib import pyplot as plt
from PIL import Image
from typing import List, TypeVar, Type

t_image = TypeVar('Image')

def show_images(images: List[t_image], max: int = 30, nrow: int = 5):
    def concat_vertical(imgs: List[t_image]):
        widths = sum([im.width for im in imgs])
        dst = Image.new('RGB', (widths, imgs[0].height))
        for n, im in enumerate(imgs):
            dst.paste(im, (im.width * n, 0))

        return dst

    def concat_horizontal(imgs: List[t_image]):
        heights = sum([im.height for im in imgs])
        dst = Image.new('RGB', (imgs[0].width, heights))
        for n, im in enumerate(imgs):
            dst.paste(im, (0, im.height * n))

        return dst

    if max > 1:
        images = images[:max]

    vertical = []
    for n in range(0, len(images), nrow):
        vertical.append(concat_vertical(images[n:n + nrow]))
    im = concat_horizontal(vertical)

    plt.imshow(im)
    plt.show()
    plt.close()

import torch
import torchvision.utils as vutils
import numpy as np

def show_images_tensor(images: torch.Tensor, max=32, nrow=5):
    if max > 1:
        images = images[:max]

    grid = vutils.make_grid(images, nrow=nrow, padding=2, normalize=True).cpu()
    im = np.transpose(grid, (1, 2, 0))

    plt.imshow(im)
    plt.show()
    plt.close()


from flask import request
from flask_restplus import Resource, fields, Namespace
import base64
from models import ShortnerModel
from schemas.urlshortner import ShortnerSchema

URL_NOT_FOUND = "Url not found."

shortner_ns = Namespace("shortner", description="Shortner related operations")

shortner_schema = ShortnerSchema()

# Model required by flask_restplus for expect

shortner = shortner_ns.model(
    "Shortner",
    {
        "encode_url": fields.String,
        "short": fields.String,
    },
)

class Shortner(Resource):
    @shortner_ns.expect(shortner)
    def get(self, shortkey):
        print("In detail")
        short_url = ShortnerModel.find_by_shortkey(shortkey)
        if short_url:
            return short_url.json()
        return {"message": URL_NOT_FOUND}, 404

class ShortnerCreate(Resource):
    @shortner_ns.expect(shortner)
    @shortner_ns.doc("Store a new url")
    def post(self):
        print("In post")
        shorter_json = request.get_json()
        shorter_json["encode_url"] = base64.urlsafe_b64encode(str(shorter_json['url']).encode("ascii"))
        desired_length = 6
        shorter_json["short"] = shorter_json["encode_url"][:desired_length]
        shorter_json.pop('url')
        shorter_data = shortner_schema.load(shorter_json)
        # shorter_data = ShortnerModel()
        # shorter_data._encode_url = encode_url
        shorter_data.save_to_db()
        return shorter_data.json(), 201


'''
Hai_Tutu = input("Hi Tutu, Silahkan Masukkan hari yang ingin Anda telusuri :")

SENIN = [' Algoritma Graf', 'Sistem Operasi', ' PAK', 'Praktikum INLAN']
SELASA = [' Matematika Teknik', ' Bhs Indonesia', ' PKN']
RABU = ['Hari rabu Anda tidak ada kelas']
KAMIS = ['IMK']
JUMAT = ['Sistem Basis Data', ' Praktikum Sistem Basis Data', ' INLAN']

HARI={'senin':SENIN, 'selasa':SELASA, 'sabu':RABU, 'kamis':KAMIS, 'jumat':JUMAT}

hari_pertama=0
for i in range(len(HARI[Hai_Tutu.lower()])):

    print("Kelas ke-", hari_pertama+1, " ", HARI[Hai_Tutu][hari_pertama])
    hari_pertama +=1
'''
Hai_Nama = input("Masukkan Nama :")

#Hai_Tutu = input("Hi,",Hai_Nama, " Silahkan Masukkan hari yang ingin Anda telusuri :")
Hai_Tutu = input("Hi,{} Silahkan Masukkan hari yang ingin Anda telusuri :".format(Hai_Nama))

SENIN = [' Hari ke-1 Algoritma Graf', 'Hari ke-3 Sistem Operasi', 'Hari ke-4 PAK', 'Hari ke-5 Praktikum INLAN']
SELASA = ['Hari ke-2 Matematika Teknik', 'Hari ke-4 Bhs Indonesia', 'Hari ke-6 PKN']
RABU = ['Hari rabu Anda tidak ada kelas']
KAMIS = ['Kelas ke-1 IMK', 'Kelas ke-3 LogMat', 'Kelas ke-4 Praktekkom']
JUMAT = ['Kelas ke-2 Sistem Basis Data', 'Kelas ke-4 Praktikum Sistem Basis Data', 'Kelas ke-6 INLAN']

HARI={'senin':SENIN, 'selasa':SELASA, 'rabu':RABU, 'kamis':KAMIS, 'jumat':JUMAT}

hari_pertama=0
for i in range(len(HARI[Hai_Tutu.lower()])):
    print(HARI[Hai_Tutu][hari_pertama])
    hari_pertama +=1


from django.conf.urls import patterns, include, url
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin

urlpatterns = patterns('',
    url(r'^asset/$', include('depotwork.apps.asset.urls')),
                        )

urlpatterns += patterns('',
    url(r'^$', 'depotwork.core.views.home', name='home'),

    url(r'^login', 'depotwork.core.views.login', {'template_name': 'core/cover.html'}, name='login'),
    url(r'^logout', 'django.contrib.auth.views.logout', {'next_page': '/'}, name='logout'),
    url(r'^signup/$', 'depotwork.auth.views.signup', name='signup'),
    url(r'^setting/', include('depotwork.core.urls')),

    url(r'^feeds/', include('depotwork.feeds.urls')),
    url(r'^questions/', include('depotwork.questions.urls')),
    url(r'^articles/', include('depotwork.articles.urls')),
    url(r'^messages/', include('depotwork.messages.urls')),

    url(r'^notifications/all', 'depotwork.activities.views.notifications', name='notifications'),
    url(r'^notifications/last/', 'depotwork.activities.views.last_notifications', name='last_notifications'),
    url(r'^notifications/check/$', 'depotwork.activities.views.check_notifications', name='check_notifications'),
    url(r'^notification/read','depotwork.activities.views.make_notification_read', name='make_notification_read'),

    url(r'^search/$', 'depotwork.search.views.search', name='search'),

    url(r'^i18n/', include('django.conf.urls.i18n', namespace='i18n')),
)

if settings.DEBUG:
    urlpatterns += patterns("",
        url(r'^media/(?P<path>.*)$', 'django.views.static.serve',
            {'document_root': settings.MEDIA_ROOT}
        ),
    )


import os
from simpleplayer import voicegen

text_to_say_gen = [
    "Suara diaktifkan",
    "Suara dinonaktifkan",
    "Direktori tidak ditemukan",
    "Berhasil menghapus lagu",
    "Lagu tidak ditemukan",
    "Daftar putar terakhir",
    "Berhasil menambahkan lagu",
    "Direktori berhasil diubah",
    "Memutar lagu berikutnya",
    "Daftar putar pertama",
    "Berhenti memutar lagu",
    "Daftar putar kosong",
    "Memutar lagu sebelumnya",
    "Lagu sudah ada",
    "Input tidak valid",
    "Lagu ditemukan",
    "Memutar lagu saat ini",
    "Tidak ada lagu yang diputar",
]

if not os.path.exists('voices'):
    os.makedirs('voices')

if __name__ == "__main__":
    for voice in text_to_say_gen:
        voicegen(voice, f"voices/{voice}", 'id')