import sys
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
import nltk
nltk.download('stopwords')
nltk.download('wordnet') # download for lemmatization
nltk.download("averaged_perceptron_tagger")
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem.wordnet import WordNetLemmatizer
import re
import matplotlib.pyplot as plt
import pickle

from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer

from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.multioutput import MultiOutputClassifier
from sklearn.metrics import classification_report, make_scorer, f1_score

def load_data(database_filepath = 'sqlite:///data/disaster.db'):
    '''
    Reads data into dataframes from database.

    Returns:
        Dataframes containing dependent and independent variables, as well column names for independent variables.
    '''
    engine = create_engine(database_filepath)
    sql = "select * from model_data4"
    df = pd.read_sql(sql, con=engine)

    # We remove 'child_alone' column as it has no values.
    df = df.drop(['child_alone', 'offer', 'tools'], axis = 1)

    X = df[["message", "genre"]]
    Y = df.iloc[:,5:]

    column_names = list(Y.columns.values)

    return X, Y, column_names

def tokenize(text):
    '''
    Extracts tokens from string by means of cleaning, tokenising and lemmatising input.

    Input:
        Text string to be tokenised.

    Output:
        List of cleaned tokens.
    '''

    url_regex = 'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+'
    # detect all URL present in the messages
    detected_urls = re.findall(url_regex, text)
    # replace URL with "urlplaceholder"
    for url in detected_urls:
        text = text.replace(url, "urlplaceholder")

    tokens = word_tokenize(text)
    lemmatizer = WordNetLemmatizer()

    clean_tokens = []
    for tok in tokens:
        clean_tok = lemmatizer.lemmatize(tok).lower().strip()
        clean_tokens.append(clean_tok)

    return clean_tokens

# Engineer new features.
class StartingVerbExtractor(BaseEstimator, TransformerMixin):
    '''
    Function to extract starting verb from each sentence.

    Input:
        Base estimator and
        Transformer classes used within ML pipelines.
    Return:
        Transform method returns a dataframe containing transformed values.
    '''

    def starting_verb(self, text):
        sentence_list = nltk.sent_tokenize(text)
        for sentence in sentence_list:
            pos_tags = nltk.pos_tag(tokenize(sentence))
            first_word, first_tag = pos_tags[0]
            if first_tag in ['VB', 'VBP'] or first_word == 'RT':
                return True
        return False

    def fit(self, X, y=None):
        return self

    def transform(self, X):
        X_tagged = pd.Series(X).apply(self.starting_verb)
        return pd.DataFrame(X_tagged)

def pipeline2(clf  = AdaBoostClassifier(random_state = 1)):
     pipeline = Pipeline([
         ('features', FeatureUnion([
            ('text_pipeline', Pipeline([
                ('vect', CountVectorizer(tokenizer=tokenize)),
                ('tfidf', TfidfTransformer())
            ])),
            ('starting_verb', StartingVerbExtractor())
         ])),
         ('clf', MultiOutputClassifier(clf))
     ])
     return pipeline

def build_model():
    '''
    Builds the model to be fitted to the data.

    Input:
        None.

    Output:
        Returns the model object which could be used to fit and predict on data.
    '''
    parameters_ada = {
    'clf__estimator__learning_rate': [0.1, 0.3],
    'clf__estimator__n_estimators': [100, 200]
    }

    pipeline_2 = pipeline2()
    pipeline_cv = GridSearchCV(estimator=pipeline_2, param_grid=parameters_ada, cv=3, verbose=10, n_jobs=-1)

    #pipeline_cv = GridSearchCV(estimator=pipeline_2, param_grid=parameters_ada, cv=3, verbose=10, n_jobs=-1)

    return pipeline_cv

def evaluate_model(model, X_test, Y_test, category_names):
    '''
    Function that predicts values based on model selected, and generates an accuracy report.

    Input:
        Model:      Model to be used for predictions.
        X_test:     Test data containing independent variables to be used for predictions.
        Y_test:     Dependent variable to be used for accuracy evaluation.

    Returns:
        Nothing.
    '''
    y_pred = model.predict(X_test)
    print(classification_report(Y_test, y_pred, target_names = category_names))

def save_model(model, model_filepath):
    '''
    Saves model to pickle file.

    Input:
        model:          Model to be saved.
        model_path:     Path to where model should be saved.

    Returns:
        Nothing.
    '''
    pickle.dump(model, open(model_filepath, 'wb'))

def main():
    if len(sys.argv) == 3:
        database_filepath, model_filepath = sys.argv[1:]
        print('Loading data...\n    DATABASE: {}'.format(database_filepath))
        X, Y, category_names = load_data("sqlite:///" + database_filepath)
        #X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2)
        X_load = X["message"].values
        Y_load = Y.values
        X_train, X_test, Y_train, Y_test = train_test_split(X_load, Y_load, random_state = 1)
        print("Xtrain size: {}".format(X_train.shape[0]))
        print("Ytrain size: {}".format(Y_train.shape[0]))

        print('Building model...')
        model = build_model()

        print('Training model...')
        np.random.seed(333)

        model.fit(X_train, Y_train)

        print('Evaluating model...')
        evaluate_model(model, X_test, Y_test, category_names)

        print('Saving model...\n    MODEL: {}'.format(model_filepath))
        save_model(model, model_filepath)

        print('Trained model saved!')

    else:
        print('Please provide the filepath of the disaster messages database '\
              'as the first argument and the filepath of the pickle file to '\
              'save the model to as the second argument. \n\nExample: python '\
              'train_classifier.py ../data/DisasterResponse.db classifier.pkl')

if __name__ == '__main__':
    main()
#%%


import logging

from django.core.mail import send_mail
from django.conf import settings
from django.shortcuts import render, redirect
from django.template.loader import render_to_string
from django.http import HttpResponse
from .forms import ContactForm

from utils.logging import setup_logger

logger, log_level = setup_logger(__name__)

def main(request):
    if log_level <= logging.INFO:
        logger.info("START")

    if log_level <= logging.INFO:
        logger.info("END")
    return render(request, 'index.html')

def about(request):
    return render(request, 'about.html')

def contact(request):
    if log_level <= logging.INFO:
        logger.info("START")

    if log_level <= logging.DEBUG:
        logger.debug(f"request.method={request.method}")

    if request.method == 'POST':
        form = ContactForm(request.POST)

        if form.is_valid():
            name = form.cleaned_data['name']
            subject = form.cleaned_data['subject']
            email = form.cleaned_data['email']
            phone = form.cleaned_data['phone']
            message = form.cleaned_data['message']

            html = render_to_string('emails/contact_form.html', {
                'name': name,
                'subject': subject,
                'email': email,
                'phone': phone,
                'message': message,
            })

            send_mail(subject, "", settings.EMAIL_HOST_USER,
                      ["steve213nsw@gmail.com"], html_message=html)

            return redirect('/contact')
    else:
        form = ContactForm()

    if log_level <= logging.INFO:
        logger.info("END")

    return render(request, 'contact.html', {'form': form})


#!/usr/bin/env python

"""
Calculates diffusion coefficient using Einstein relation from LAMMPS trajectory files.
"""

import os
import re
import glob

import numpy as np
import pandas as pd
import seaborn as sns
import statsmodels.api as sm
import matplotlib.pyplot as plt

from matplotlib.ticker import ScalarFormatter

from pymatgen.io.lammps.outputs import parse_lammps_log, parse_lammps_dumps

from mdproptools.common import constants
from mdproptools.common.com_mols import calc_com
from mdproptools.utilities.plots import set_axis

__author__ = "Rasha Atwi, Matthew Bliss"
__maintainer__ = "Rasha Atwi"
__email__ = "rasha.atwi@stonybrook.edu"
__status__ = "Development"
__date__ = "Sep 2021"
__version__ = "0.0.4"

class Diffusion:
    def __init__(self, timestep=1, units="real", outputs_dir=None, diff_dir=None):
        self.units = units
        if self.units not in constants.SUPPORTED_UNITS:
            raise KeyError(
                "Unit type not supported. Supported units are: "
                + str(constants.SUPPORTED_UNITS)
            )
        self.outputs_dir = outputs_dir or os.getcwd()
        self.diff_dir = diff_dir or os.getcwd()
        self.timestep = timestep

    @staticmethod
    def _prepare_unwrapped_coords(dump):
        # Ensure access to unwrapped coordinates, may want to add scaled
        # coordinates in future ('sx', 'sxu', etc.)
        if "xu" and "yu" and "zu" not in dump.data.columns:
            assert (
                "x" and "y" and "z" in dump.data.columns
            ), "Missing wrapped and unwrapped coordinates (x y z xu yu zu)"
            assert "ix" and "iy" and "iz" in dump.data.columns, (
                "Missing unwrapped coordinates (xu yu zu) and box location ("
                "ix iy iz) for converting wrapped coordinates (x y z) into "
                "unwrapped coordinates. "
            )
            box_x_length = dump.box.bounds[0][1] - dump.box.bounds[0][0]
            box_y_length = dump.box.bounds[1][1] - dump.box.bounds[1][0]
            box_z_length = dump.box.bounds[2][1] - dump.box.bounds[2][0]
            dump.data["xu"] = dump.data["x"].add(dump.data["ix"].multiply(box_x_length))
            dump.data["yu"] = dump.data["y"].add(dump.data["iy"].multiply(box_y_length))
            dump.data["zu"] = dump.data["z"].add(dump.data["iz"].multiply(box_z_length))
        return dump

    def _calculate_type_com(self, df, ind):
        return df.groupby(ind).apply(
            lambda x: pd.Series(
                x["mass"].values @ x[["xu", "yu", "zu"]].values / x.mass.sum(),
                index=["xu", "yu", "zu"],
            )
        )

    def _modify_dump_coordinates(self, msd_df):
        ref_com = self._calculate_type_com(msd_df.xs(0, 0), ["type"])
        com = self._calculate_type_com(msd_df, ["Time (s)", "type"])
        drift = com - com[[]].join(ref_com)
        msd_df.loc[:, ["xu", "yu", "zu"]] -= drift
        return msd_df

    def detect_linear_region():
        pass

    def get_msd_from_dump(
        self,
        filename,
        tao_coeff=4,
        msd_type="com",
        num_mols=None,
        num_atoms_per_mol=None,
        mass=None,
        com_drift=False,
        avg_interval=False,
    ):
        dumps = parse_lammps_dumps(f"{self.outputs_dir}/{filename}")
        msd_dfs = []
        for dump in dumps:
            assert "id" in dump.data.columns, "Missing atom id's in dump file."
            dump.data = dump.data.sort_values(by=["id"])
            dump.data.reset_index(inplace=True)
            dump = self._prepare_unwrapped_coords(dump)
            if msd_type == "allatom":
                df = dump.data[["id", "xu", "yu", "zu"]]
                msd_dfs.append(df)
                id_cols = ["id"]
                col_1d = ["Time (s)"]
            elif msd_type == "com":
                df = calc_com(
                    dump,
                    num_mols,
                    num_atoms_per_mol,
                    mass,
                    atom_attributes=["xu", "yu", "zu"],
                )
                # convert to SI units
                df["mass"] = df["mass"] * constants.MASS_CONVERSION[self.units]
                df.reset_index(inplace=True)
                msd_dfs.append(df)
                id_cols = ["type", "mol_id"]
                col_1d = ["Time (s)", "type"]
            # convert to SI units
            df.loc[:, "xu"] = df["xu"] * constants.DISTANCE_CONVERSION[self.units]
            df.loc[:, "yu"] = df["yu"] * constants.DISTANCE_CONVERSION[self.units]
            df.loc[:, "zu"] = df["zu"] * constants.DISTANCE_CONVERSION[self.units]
            df["Time (s)"] = (
                dump.timestep * self.timestep * constants.TIME_CONVERSION[self.units]
            )
        msd_df = pd.concat(msd_dfs).set_index(["Time (s)"] + id_cols).sort_index()
        if msd_type == "com" and com_drift:
            msd_df = self._modify_dump_coordinates(msd_df)
        coords = ["xu", "yu", "zu"]
        disps = ["dx2", "dy2", "dz2"]
        msd_all = msd_df.copy()
        ref_df = msd_all.xs(0, 0)
        msd_all[disps] = (msd_all[coords] - msd_all[[]].join(ref_df[coords])) ** 2
        msd_all["msd"] = msd_all[disps].sum(axis=1)
        one_d_cols = disps + ["msd"]
        msd_all = msd_all[one_d_cols]
        msd = msd_all.groupby(col_1d).mean()
        if msd_type == "com":
            msd = msd.reset_index().pivot(columns="type", index="Time (s)")
            msd = msd.sort_index(axis=1, level=1)
            msd.columns = ["".join([str(i) for i in v]) for v in msd.columns.values]
        msd.reset_index(inplace=True)
        msd_all.reset_index(inplace=True)
        if avg_interval:
            times = list(msd_df.index.levels[0])
            times = times[::tao_coeff]
            msd_df = msd_df[msd_df.index.get_level_values(0).isin(times)]
            msd_df[disps] = (
                msd_df[coords]
                .groupby(id_cols)
                .transform(lambda x: (x - x.shift(1)) ** 2)
            )
            msd_df.drop(0, level=0)
            msd_df["msd"] = msd_df[disps].sum(axis=1)
            msd_df = msd_df[one_d_cols]
            msd_int = msd_df.groupby(id_cols).mean().reset_index()
            return msd, msd_all, msd_int
        return msd, msd_all

    def get_msd_from_log(self, log_pattern):
        log_files = glob.glob(f"{self.outputs_dir}/{log_pattern}")
        # based on pymatgen.io.lammps.outputs.parse_lammps_dumps function
        if len(log_files) > 1:
            pattern = r"%s" % log_pattern.replace("*", "([0-9]+)")
            pattern = ".*" + pattern.replace("\\", "\\\\")
            log_files = sorted(log_files, key=lambda f: int(re.match(pattern, f).group(1)))
        list_log_df = []
        for file in log_files:
            log_df = parse_lammps_log(file)
            list_log_df.append(log_df[0])
        for p, l in enumerate(list_log_df[:-1]):
            list_log_df[p] = l[:-1]
        full_log = pd.concat(list_log_df, ignore_index=True)
        msd = full_log.filter(regex="msd")
        for col in msd:
            msd.loc[:, col] = msd[col] * constants.DISTANCE_CONVERSION[self.units] ** 2
        msd["Time (s)"] = (
            full_log["Step"] * self.timestep * constants.TIME_CONVERSION[self.units]
        )
        return msd

    def calc_diff(
        self,
        msd,
        initial_time=None,
        final_time=None,
        dimension=3,
        diff_names=None,
        save=False,
        plot=False,
    ):
        # initial and final time in seconds
        if initial_time is None:
            initial_time = {}
        if final_time is None:
            final_time = {}
        min_t = min(msd["Time (s)"])
        max_t = max(msd["Time (s)"])
        msd_col_names = [col for col in msd.columns if "msd" in col.lower()]
        diff = np.zeros((len(msd_col_names), 3))
        models = []
        counter = 0
        for ind, col in enumerate(msd_col_names):
            msd_df = msd[
                (msd["Time (s)"] >= initial_time.get(counter, min_t))
                & (msd["Time (s)"] <= final_time.get(counter, max_t))
            ]
            counter += 1
            model = sm.OLS(msd_df[col], msd_df["Time (s)"]).fit()
            models.append(model)
            diff[ind] = [
                model.params[0] / (2 * dimension),
                model.bse[0] / (2 * dimension),
                model.rsquared,
            ]
            if save:
                if diff_names:
                    diff_file = f"{self.diff_dir}/diff_{diff_names[ind]}.txt"
                else:
                    diff_file = f"{self.diff_dir}/diff_{ind + 1}.txt"
                with open(diff_file, "w") as f:
                    f.write(str(model.summary()))
        ind = diff_names or [i + 1 for i in range(len(msd_col_names))]
        diffusion = pd.DataFrame(
            diff,
            columns=["diffusion (m2/s)", "std", "R2"],
            index=ind,
        )

        if plot:
            paired = plt.get_cmap("Paired")
            colors = iter(paired(np.linspace(0, 1, 10)))
            ncols = 2
            nrows = int(np.ceil(len(msd_col_names) / ncols))
            fig, axes = plt.subplots(nrows, ncols, figsize=(12, 8))
            fig_log, axes_log = plt.subplots(nrows, ncols, figsize=(12, 8))
            time_data = msd["Time (s)"] * 10**9
            for i, (ax, ax_log, col) in enumerate(
                zip(axes.flatten(), axes_log.flatten(), msd_col_names)
            ):
                color = next(colors)
                y_formatter = ScalarFormatter(useOffset=False)

                # normal plot
                pred = models[i].predict()
                ax.plot(
                    time_data,
                    msd[col],
                    color=color,
                    linewidth=2,
                    label=ind[i],
                )
                ax.plot(time_data, pred, color="k", ls="--", linewidth=2)
                ax.locator_params(axis="y", nbins=6)
                # log plot
                st_line = 10 ** (np.log10(msd[col].max()) - np.log10(time_data.max()))
                ax_log.plot(
                    time_data,
                    msd[col],
                    color=color,
                    linewidth=2,
                    label=ind[i],
                )
                ax_log.plot(
                    time_data, time_data * st_line, color="k", ls="--", linewidth=2
                )
                ax_log.set(xscale="log", yscale="log")

                for axis in [ax, ax_log]:
                    set_axis(axis, axis="both")
                    axis.legend(
                        fontsize=16,
                        frameon=False,
                    )
                    axis.set_xlabel(r"$\mathrm{Time, 10^9 (s)}$", fontsize=18)
                    axis.set_ylabel(r"$\mathrm{MSD\ (m^2)}$", fontsize=18)
                    axis.yaxis.set_major_formatter(y_formatter)
                    axis.yaxis.offsetText.set_fontsize(18)

            for figure, axis, name in zip(
                [fig, fig_log], [axes, axes_log], ["msd.png", "msd_log.png"]
            ):
                if len(msd_col_names) % 2 != 0:
                    figure.delaxes(ax=axis.flatten()[-1])
                figure.tight_layout()
                figure.savefig(
                    f"{self.diff_dir}/{name}",
                    bbox_inches="tight",
                    pad_inches=0.1,
                )

        diffusion.to_csv(f"{self.diff_dir}/diffusion.csv")
        print("Diffusion results written to a .csv file.")
        return diffusion

    def get_diff_dist(
        self, msd_int, dump_freq, dimension=3, tao_coeff=4, plot=False, diff_names=None
    ):
        delta = dump_freq * self.timestep * constants.TIME_CONVERSION[self.units]
        msd_int["diff"] = msd_int["msd"] / (2 * dimension * tao_coeff * delta)
        msd_int.to_csv(f"{self.diff_dir}/msd_int.csv")
        if plot:
            paired = plt.get_cmap("Paired")
            colors = iter(paired(np.linspace(0, 1, 10)))
            if "type" in msd_int.columns:
                # if data is available for the com of each molecule type
                groups = msd_int.groupby("type")
                ind = diff_names or [i + 1 for i in range(len(groups))]
                ncols = 2
                nrows = int(np.ceil(groups.ngroups / ncols))
                fig, axes = plt.subplots(nrows, ncols, figsize=(12, 8))
                for ax, (key, grp) in zip(axes.flatten(), groups):
                    color = next(colors)
                    set_axis(ax, axis="both")
                    sns.histplot(
                        grp["diff"] * 10**9,
                        bins="sqrt",
                        color=color,
                        edgecolor="k",
                        label=ind[key - 1],
                        kde=True,
                        stat="density",
                        ax=ax,
                    )
                    ax.legend(
                        fontsize=16,
                        frameon=False,
                    )
                    ax.set_xlabel(
                        r"$\mathrm{Diffusivity, 10^{-9}\ (m^2/s)}$", fontsize=18
                    )
                    ax.set_ylabel(
                        "Frequency",
                        fontsize=18,
                    )
                    ax.xaxis.get_major_ticks()[1].label1.set_visible(False)
                    ax.xaxis.set_major_formatter(ScalarFormatter())
                    y_formatter = ScalarFormatter(useOffset=False)
                    ax.yaxis.set_major_formatter(y_formatter)
                    ax.yaxis.offsetText.set_fontsize(18)
                    ax.locator_params(axis="y", nbins=6)
                if len(groups) % 2 != 0:
                    fig.delaxes(ax=axes.flatten()[-1])
                fig.tight_layout()
                fig.savefig(
                    f"{self.diff_dir}/diff_dist.png",
                    bbox_inches="tight",
                    pad_inches=0.1,
                )
            else:
                # if data is available for all atoms
                fig, ax = plt.subplots(figsize=(8, 6))
                set_axis(ax, axis="both")
                sns.histplot(
                    msd_int["diff"] * 10**9,
                    bins="sqrt",
                    color=next(colors),
                    edgecolor="k",
                    kde=True,
                    stat="density",
                    ax=ax,
                )
                ax.set_xlabel(r"$\mathrm{Diffusivity, 10^{-9}\ (m^2/s)}$", fontsize=18)
                ax.set_ylabel(
                    "Frequency",
                    fontsize=18,
                )
                ax.xaxis.get_major_ticks()[1].label1.set_visible(False)
                ax.xaxis.set_major_formatter(ScalarFormatter())
                y_formatter = ScalarFormatter(useOffset=False)
                ax.yaxis.set_major_formatter(y_formatter)
                ax.yaxis.offsetText.set_fontsize(18)
                ax.locator_params(axis="y", nbins=6)
                fig.tight_layout()
                fig.savefig(
                    f"{self.diff_dir}/diff_dist.png",
                    bbox_inches="tight",
                    pad_inches=0.1,
                )


# In[]
import pandas as pd
import numpy as np
import csv
from unidecode import unidecode
import pandas_gbq
from google.cloud import bigquery
import locale

projeto = "rh-analytics-397518"
dataset = "powerbi"
# Execute uma consulta SQL
extrato = "powerbi.beneficios_va_vr_restaurante"

df_extrato = pd.read_gbq(extrato, project_id=projeto)

# %%

df_extrato["referencia"] = df_extrato["referencia"].astype("datetime64[us]")

# pivot df_extrato
df_pivot = df_extrato.pivot_table(
    index=[
        "id_da_pessoa",
        "no_pessoal",
        "referencia",
    ],
    columns="tipo_de_plano_de_beneficios_co",
    values="credito_er",
    aggfunc="sum",  # ou outra função de agregação, como 'mean', conforme sua necessidade
).reset_index()

# In[]

def formatar_nome_coluna(nome_coluna):
    nome_sem_acentos = unidecode(nome_coluna)  # Remove acentos
    nome_sem_pontos = nome_sem_acentos.replace(".", "")  # Remove pontos
    nome_sem_pontos = nome_sem_acentos.replace("%", "")  # Remove pontos
    nome_sem_barras = nome_sem_pontos.replace("/", "_")  # Remove pontos
    nome_sem_abertura_parenteses = nome_sem_barras.replace("(", "_")  # Remove pontos
    nome_sem_fechamento_parenteses = nome_sem_abertura_parenteses.replace(
        ")", "_"
    )  # Remove pontos
    nome_formatado = nome_sem_fechamento_parenteses.replace(
        " ", "_"
    )  # Substitui espaços por underscores
    nome_formatado_minusculo = nome_formatado.lower()  # Converte para minúsculas
    return nome_formatado_minusculo

df_pivot.columns = [formatar_nome_coluna(nome) for nome in df_pivot.columns]
df_pivot = df_pivot.rename(columns={"vale_aliment.": "vale_aliment"})

# %%

projeto = "rh-analytics-397518"
dataset = "powerbi"
tabela = "powerbi.smart_va_vr"

pandas_gbq.to_gbq(df_pivot, tabela, project_id=projeto, if_exists="replace")

# %%


import unittest
from datetime import datetime

from exobuilder.contracts.futurecontract import FutureContract
from exobuilder.exo.transaction import Transaction
from .assetindexdict import AssetIndexDicts
from .datasourcefortest import DataSourceForTest

class TransactionTestCase(unittest.TestCase):
    def setUp(self):
        self.assetindex = AssetIndexDicts()
        self.symbol = 'EP'
        self.date = datetime(2014, 1, 5, 0, 0, 0)
        self.futures_limit = 12
        self.instrument_dbid = 11
        self.datasource = DataSourceForTest(self.assetindex, self.futures_limit, 0)
        self.instrument = self.datasource.get(self.symbol, self.date)

        self.contract_dict = {'_id': '577a4fa34b01f47f84cab23c',
                              'contractname': 'F.EPZ16',
                              'cqgsymbol': 'F.EPZ16',
                              'expirationdate': datetime(2016, 12, 16, 0, 0),
                              'idcontract': 6570,
                              'idinstrument': 11,
                              'month': 'Z',
                              'monthint': 12,
                              'year': 2016}
        self.fut_contract = FutureContract(self.contract_dict, self.instrument)
        self.trans = Transaction(self.fut_contract, self.date, 4.0, 12.3, leg_name='leg1')

    def test_constructor(self):
        t = Transaction(self.fut_contract, self.date, 4.0, 12.3)

        self.assertEqual(t._asset, self.fut_contract)
        self.assertEqual(t._date, self.date)
        self.assertEqual(t._qty, 4.0)
        self.assertEqual(t._price, 12.3)
        self.assertEqual(t._leg_name, '')

    def test_has_leg_name(self):
        self.assertEqual(self.trans._leg_name, 'leg1')
        self.assertEqual(self.trans.leg_name, 'leg1')

    def test_has_asset(self):
        self.assertEqual(self.trans.asset, self.fut_contract)

    def test_has_date(self):
        self.assertEqual(self.trans.date, self.date)

    def test_has_qty(self):
        self.assertEqual(self.trans.qty, 4.0)

    def test_has_price(self):
        self.assertEqual(self.trans.price, 12.3)

    def test_has_usdvalue(self):
        self.assertEqual(self.trans.usdvalue, 4*12.3*self.fut_contract.pointvalue)

    def test_has_as_dict(self):
        self.assertEqual({'date': self.trans.date,
                          'qty': self.trans.qty,
                          'price': self.trans.price,
                          'asset': self.fut_contract.as_dict(),
                          'usdvalue': self.trans.usdvalue}, self.trans.as_dict())


from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import numpy as np
import time

import knn

def standardize(x):
    mu = np.mean(x, axis=0)
    sigma = np.std(x, axis=0)
    sigma[sigma == 0] = 1
    return (x - mu) / sigma

# 1、读取数据集
t0 = time.time()
dataset_name = 'iris'
if dataset_name == 'iris':
    dataset = datasets.load_iris()
    x = dataset.data
    y = dataset.target
elif dataset_name == 'digits':
    dataset = datasets.load_digits()
    x = dataset.data
    y = dataset.target
    #x = standardize(x)
elif dataset_name == 'skin':
    xlist = []
    ylist = []
    with open('Skin_NonSkin.txt', 'r') as f:
        for line in f.readlines():
            numlist = line[:-1].split('\t')
            xlist.append([int(num) for num in numlist[:-1]])
            ylist.append(int(numlist[-1]))
    x = np.array(xlist)
    y = np.array(ylist) - 1
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
print('读取数据集\n耗时：%.4fs\n' % (time.time() - t0))

# 2、测试简单kNN
t0 = time.time()
y_pred = knn.knn(x_train, y_train, x_test, 4)
print('简单kNN\n耗时：%.4fs' % (time.time() - t0))
print(classification_report(y_test, y_pred))

# 3、测试基于k-d树的kNN
t0 = time.time()
y_pred = knn.knn_kdt(x_train, y_train, x_test, 4)
print('基于k-d树的kNN\n耗时：%.4fs' % (time.time() - t0))
print(classification_report(y_test, y_pred))


from selenium.webdriver.chrome.service import Service
from selenium import webdriver
from pyfiglet import Figlet
from textwrap import wrap
import requests
import socket
import folium
import time
import os
#
''' pip install -U -r requirements.txt ''' # !!!TURN YOUR ATTENTION!!!
#
def get_ip_by_hostname(hostname):
    try: return socket.gethostbyname(hostname)
    except socket.gaierror as error: print(error)
    return socket.gethostname()

def get_info_by_ip(ip='127.0.0.1'):
    text = ""
    try:
        response = requests.get(url=f'http://ip-api.com/json/{ip}').json()
        data = {
            '[IP]':str(response.get('query')) + " " + str(response.get('org')),
            '[Сoordinates]': str(response.get('lat')) + ", " + str(response.get('lon')),
            '[Region]':str(response.get('city')) + " (" + str(response.get('zip')) + "), " + str(response.get('regionName')) + " (" + str(response.get('region')) + "), " + str(response.get('country')) + ", " + str(response.get('timezone'))
        }
        for name,info in data.items():
            if name == '[IP]': text = f'{name} : {info}'
            elif name == '[Сoordinates]': text = text + "; " + f'{name} : {info}'
            else: text = text + "; " + f'{name} : {info}'
            print(f'{name}:{info}')
        return '\n'.join(wrap(text.replace(';', '\n'), 40)), response.get('lat'), response.get('lon'), data['[Region]'], response.get('query'), response.get('org')
    except requests.exceptions.ConnectionError as error: print(error)

def marker(lat,lon, reg, ip, org):     #max_zoom_start:18
    marker = folium.Map(location=[lat,lon], zoom_start=13, tiles= "CartoDB dark_matter") # the value of the "tiles" parameter sets the style of the map
    folium.CircleMarker(location=[lat,lon], popup = f"{org}<br/>{reg}", radius=50, line_color='#3186cc', fill_color='#3186cc').add_to(marker)
    marker.save(f'{os.getcwd()}/map_{ip}.html', 'wb')
    return f'map_{ip}.html'

def run_html_file(html_file):
    try:
        option = webdriver.ChromeOptions()
        option.add_argument("user-agent=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0")
        # provide the correct address for your files - {os.getcwd()}, I have it is: /USER/v.syroiezhin
        directory = os.getcwd().split("/", 3)
        driver = webdriver.Chrome(service=Service(f"/{directory[1]}/{directory[2]}/.wdm/drivers/chromedriver/mac64/103.0.5060.53/chromedriver"), options=option)
        driver.get("file://" + f"{os.getcwd()}/{html_file}")

    except Exception as error: print(error)
    finally:
        time.sleep(5) # Selenium working hours
        driver.close()
        driver.quit()

# if __name__ == '__main__': # line above
def main(hostname):
    '''
    Now I will call the code of this program in another python file,
    (tk_wbs_IP.py) passing it the <<hostname>> parameter.
    But if you comment out the <<main>> function and unblock the line below and above,
    then this program will work independently through the console!
    '''
    # hostname = input(Figlet(font='slant').renderText('Enter URL :')) # line below
    text,lat,lon,reg,ip,org = get_info_by_ip(get_ip_by_hostname(hostname))
    html_file = marker(lat,lon,reg,ip,org)
    run_html_file(html_file)
    return text


from typing import Callable, Iterable, List
from numpy import sign
from interval import Interval

T = float

def find_root_intervals(
    f: Callable[[T], T],
    interval: Interval,
    window: int
) -> Iterable[Interval]:
    assert window > 0
    while True:
        left = interval.left
        right = left + window
        if interval.right < right:
            break
        if f(left) * f(right) < 0:
            yield Interval(left, right)


import re
import pickle
from nltk.corpus import wordnet as wn
from nltk import pos_tag
from collections import OrderedDict
from  more_itertools import unique_everseen

with open('redundancy_pruned_feature_list.pickle', 'rb') as handle:
    redundancy_pruned_feature_list = pickle.load(handle)

#print(redundancy_pruned_feature_list)
opinion_features_and_words = []

for i in redundancy_pruned_feature_list:
	adj_list = []
	noun_list = []
	for j, word in enumerate(i[0]):
		if re.match("^[a-zA-Z]*$", word):
			#print(word, pos_tag([word]))
			if pos_tag([word])[0][1] == 'JJ': # or pos_tag([word]) == 'RB'
				adj_list.append(word)
			else:
				noun_list.append(word)
		else:
			noun_list.append(word)
	opinion_features_and_words.append(tuple((noun_list, adj_list)))

#for i in opinion_features_and_words:
	#print(i)

f = open('cleaned_data_for_pruning.txt', 'r')

sentences = []

for l in f:
	se = re.sub("[^\w\d'\s.]+",'',l)
	x = se.strip().split('.')
	for i in x:
		sentences.append(i.strip())
#print(sentences)

pos_words_in_sentence = []
words_in_sentence = []
for i in range(len(sentences)):
	if sentences[i] != '' or sentences[i] != '\n':
		sentence_word = sentences[i].split(' ')
		sentence_word = list(filter(None, sentence_word))
	if sentence_word != []:
		words_in_sentence.append(sentence_word)
		pos_words_in_sentence.append(pos_tag(sentence_word))

new_opinion_features_and_words = []
adj_opinion_word = []

for i in opinion_features_and_words:
	if i[1] == [] and i[0] != []:
		for ix, j in enumerate(words_in_sentence):
			adj_word = []
			flag = 0
			for w in i[0]:
				if w not in words_in_sentence[ix]:
					flag = 1
					break
			if flag == 0:
				index = words_in_sentence[ix].index(i[0][0])
				adj_ind = []
				for ind, pw in enumerate(pos_words_in_sentence[ix]):
					if pw[1] == 'JJ':
						adj_ind.append(ind)
				if adj_ind != []:
					mn = 1000
					min_ind = 1000
					for ind in adj_ind:
						if abs(ind - index) < mn:
							mn = abs(ind - index)
							min_ind = ind
					adj_word = [words_in_sentence[ix][min_ind]]
					#print(pos_tag(adj_word))
			if flag == 0 and adj_word != [] and pos_tag(adj_word)[0][1] == 'JJ':
				adj_opinion_word.append(adj_word[0])
				new_opinion_features_and_words.append(tuple((i[0], adj_word)))
	elif i[1] != [] and i[0] == []:
		for ix, j in enumerate(words_in_sentence):
			noun_word = []
			flag = 0
			for w in i[1]:
				if w not in words_in_sentence[ix]:
					flag = 1
					break
			if flag == 0:
				index = words_in_sentence[ix].index(i[1][0])
				noun_ind = []
				for ind, pw in enumerate(pos_words_in_sentence[ix]):
					if pw[1] == 'NN':
						noun_ind.append(ind)
				if noun_ind != []:
					mn = 1000
					min_ind = 1000
					for d in noun_ind:
						if abs(ind - index) < mn:
							mn = abs(ind - index)
							min_ind = ind
					noun_word = [words_in_sentence[ix][min_ind]]
			if flag == 0 and noun_word != [] and pos_tag(noun_word)[0][1] == 'NN':
				new_opinion_features_and_words.append(tuple((noun_word, i[1])))

opinion_words_list = []

for i in list(unique_everseen(new_opinion_features_and_words)):
	if i[0] != i[1]:
		opinion_words_list.append(i)
'''
for i in opinion_words_list:
	print(i)'''
count_simple = [0] * len(opinion_words_list)
for idx,i in enumerate(opinion_words_list):
	for sen in words_in_sentence:
		if set(i[0])<set(sen) and set(i[1])<set(sen):
			count_simple[idx] += 1

sortedlist_simple = [i[0] for i in sorted(zip(opinion_words_list, count_simple), key=lambda l: l[1], reverse=True)]
count2_simple = sorted(count_simple, reverse=True)

with open('opinion_words_list.pickle', 'wb') as handle:
    pickle.dump(sortedlist_simple, handle)

t = set(adj_opinion_word)
adj_opinion_word = []

for i in t:
	adj_opinion_word.append(i)

with open('adj_opinion_word.pickle', 'wb') as handle:
    pickle.dump(adj_opinion_word, handle)

### INFREQUENT FEATURE SETS ###
infrequent_feature_list = []

for i in opinion_features_and_words:
	if i[1] == [] and i[0] != []:
		for ix, j in enumerate(words_in_sentence):
			adj_word = []
			flag = 0
			for w in i[0]:
				if w not in words_in_sentence[ix]:
					flag = 1
					break
			if flag == 1:
				for adj in adj_opinion_word:
					if adj in words_in_sentence[ix]:
						index = words_in_sentence[ix].index(adj)
						noun_ind = []
						for ind, pw in enumerate(pos_words_in_sentence[ix]):
							if pw[1] == 'NN':
								noun_ind.append(ind)
						if noun_ind != []:
							mn = 1000
							min_ind = 1000
							for ind in noun_ind:
								if abs(ind - index) < mn:
									mn = abs(ind - index)
									min_ind = ind
							noun_word = [words_in_sentence[ix][min_ind]]
						if noun_word != [] and pos_tag(noun_word)[0][1] == 'NN':
							infrequent_feature_list.append(tuple((noun_word, [adj])))

new_infrequent_feature_list = []
for i in list(unique_everseen(infrequent_feature_list)):
	if i[0] != i[1]:
		new_infrequent_feature_list.append(i)

not_include = []
for ind, i in enumerate(new_infrequent_feature_list):
	if i in opinion_words_list:
		not_include.append(ind)

infrequent_feature_list = [i for j, i in enumerate(new_infrequent_feature_list) if j not in not_include]
'''
for i in infrequent_feature_list:
	print(i)
'''
all_feature_list = opinion_words_list + infrequent_feature_list

count = [0] * len(all_feature_list)
for idx,i in enumerate(all_feature_list):
	for sen in words_in_sentence:
		if set(i[0])<set(sen) and set(i[1])<set(sen):
			count[idx] += 1

sortedlist = [i[0] for i in sorted(zip(all_feature_list, count), key=lambda l: l[1], reverse=True)]
count2 = sorted(count, reverse=True)
for i in range(len(sortedlist)):
	print(sortedlist[i], count2[i])

with open('sorted_opinion_list.pickle', 'wb') as handle:
    pickle.dump(sortedlist, handle)


#There is no comment except this one. Other comments are not comments, either functions or matarials for converting this into an apk
import os
from kivy.metrics import dp
from kivymd.uix.datatables import MDDataTable
from kivymd.uix.screenmanager import ScreenManager
from kivymd.uix.screen import MDScreen
from openpyxl import load_workbook as wb
from openpyxl import Workbook as wrk
from openpyxl.styles import Font,Alignment,Border,Side
from kivymd.app import MDApp
from kivy.uix.popup import Popup
from kivymd.uix.boxlayout import BoxLayout
from kivymd.uix.button import MDRaisedButton
from kivymd.uix.textfield import MDTextField
from kivymd.uix.label import MDLabel
from kivymd.uix.filemanager.filemanager import MDFileManager
from kivy.lang.builder import Builder
from kivymd.uix.scrollview import MDScrollView
# from android.storage import primary_external_storage_path
# from android.permissions import request_permissions, Permission

hm = 'Follow these steps\n\n1. Click on "Choose Routine" and select your routine(excel format) from folder.\n\n2. ' \
     'Now enter your course codes separeted by spaces or your semester no with major(If you have any.[NM,DS,RE,CS]).\n\nEx: ' \
     '"MAT101 ENG101 AOL101 SE111 SE112_L SE113" or "1" or "7_NM" \nwithout quotation marks.\n\n3. Now enter your section in section box.\n\n4. ' \
     'Click on "Routine Page" button to see and save routine. \n\n5. Click "Show Routine" to see routine and "Save" to save your routine in exccel format in the same directory. \n\nNOTE: This works with only excel file. '

semester = {
    '1': "MAT101 ENG101 AOL101 SE111 SE112_L SE113",
    '2': "MAT102 PHY101 SE121 SE122_L SE123 SE212 SE213",
    '3': "SE131 SE132_L SE133_L SE211 SE222 STA101 BNS101",
    '4': "SE214 SE215_L SE221 SE223 SE224_L SE232 SE233_L GE235 SE532",
    '5': "SE225 SE226_L SE231_L SE234 SE311 SE312 SE313_L GE324",
    '6': "SE321 SE322_L SE323 SE332 SE333 SE334_L SE411 SE544",
    '7_NM': "SE331 EMP101 SE442 SE535 SE447 SE599",
    '7_DS': "SE331 EMP101 SE442 DS331 DS332 DS411 DS412 DS421 DS422",
    '7_CS': "SE331 EMP101 SE442 CS211 CS418 CS422",
    '7_RE': "SE331 EMP101 SE442 RE331 RE411 RE412 RE421 RE422",
    '8_NM': "SE341 SE431",
    '8_DS': "CS334 CS335 CS439",
    '8_CS': "DS432 DS424 DS431",
    '8_RE': "RE423 RE424 RE431"
}

days ={
    "Sat" : [],
    "Sun" : [],
    "Mon" : [],
    "Tue" : [],
    "Wed" : [],
    "Thu" : []
}

day={}
times=[]
loctn = ['','']

def routine_separateor(loc,lst):
    sheet = wb(loc)
    routine = sheet.active
    ltrs = ['B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q']
    x=6
    times.append(routine["A3"].value)
    for i in range(2,len(ltrs),2):
        times.append(routine[ltrs[i]+'3'].value)
    for i in range(x,x+19):
        if routine['A'+str(i)].value == "Sunday":
            x = i
            break
        for ltr in ltrs:
            cursor = ltr +str(i)
            if routine[cursor].value in lst:
                if ltr == 'B':
                    time = routine['A' + '3'].value
                else:
                    time = routine[ltr + '3'].value
                room = routine['A'+ str(i)].value
                sub = routine[cursor].value
                days["Sat"].append([sub,time,room])
    i = x
    while True:
        if routine['A'+str(i)].value == "Monday":
            break
        for ltr in ltrs:
            cursor = ltr +str(i)
            if routine[cursor].value in lst:
                if ltr == 'B':
                    time = routine['A' + '3'].value
                else:
                    time = routine[ltr + '3'].value
                room = routine['A'+ str(i)].value
                sub = routine[cursor].value
                days["Sun"].append([sub,time,room])
        i+=1

    while True:
        if routine['A'+str(i)].value == "Tuesday":
            break
        for ltr in ltrs:
            cursor = ltr +str(i)
            if routine[cursor].value in lst:
                if ltr == 'B':
                    time = routine['A' + '3'].value
                else:
                    time = routine[ltr + '3'].value
                room = routine['A'+ str(i)].value
                sub = routine[cursor].value
                days["Mon"].append([sub,time,room])
        i += 1

    while True:
        if routine['A'+str(i)].value == "Wednesday":
            break
        for ltr in ltrs:
            cursor = ltr +str(i)
            if routine[cursor].value in lst:
                if ltr == 'B':
                    time = routine['A' + '3'].value
                else:
                    time = routine[ltr + '3'].value
                room = routine['A'+ str(i)].value
                sub = routine[cursor].value
                days["Tue"].append([sub,time,room])
        i += 1

    while True:
        if routine['A'+str(i)].value == "Thursday":
            break
        for ltr in ltrs:
            cursor = ltr +str(i)
            if routine[cursor].value in lst:
                if ltr == 'B':
                    time = routine['A' + '3'].value
                else:
                    time = routine[ltr + '3'].value
                room = routine['A'+ str(i)].value
                sub = routine[cursor].value
                days["Wed"].append([sub,time,room])
        i += 1

    while True:
        if routine['A'+str(i)].value == None:
            break
        for ltr in ltrs:
            cursor = ltr +str(i)
            if routine[cursor].value in lst:
                if ltr == 'B':
                    time = routine['A' + '3'].value
                else:
                    time = routine[ltr + '3'].value
                room = routine['A'+ str(i)].value
                sub = routine[cursor].value
                days["Thu"].append([sub,time,room])
        i += 1

def create_routine(dic,sec,times,path):
    border = Border(
        left=Side(style='medium'),  # You can use 'thick' for thicker borders
        right=Side(style='medium'),
        top=Side(style='medium'),
        bottom=Side(style='medium')
    )
    workbook = wrk()
    rtn = workbook.active
    rtn.title="routine"
    lst = ['B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q']
    clm = len(times)-1
    row = 2*len(dic)+3
    rtn.merge_cells(f"A1:{lst[clm]}1")
    rtn["A1"].value = "Section : "+sec
    rtn["A1"].font = Font(name="Times New Roman",size=20,bold=True)
    rtn["A1"].alignment = Alignment(horizontal="center")
    rtn["A1"].border = border
    rtn[lst[clm]+'1'].border = border
    rtn.column_dimensions["A"].width = 16.5
    for i in range(clm+1):
        rtn.column_dimensions[lst[i]].width = 17

    i=0
    for time in times:
        rtn[lst[i] + '2'].value = time
        rtn[lst[i] + '2'].font = Font(name="Times New Roman", size =  14 ,bold=True)
        rtn[lst[i] + '2'].alignment = Alignment(vertical="center")
        rtn[lst[i] + '2'].alignment = Alignment(horizontal="center")
        rtn[lst[i] + '2'].border = border
        i+=1
    i=3

    for key in dic.keys():
        rtn['A' + str(i+1)].border = border
        rtn.merge_cells(f"A{str(i)}:A{str(i + 1)}")
        rtn['A'+str(i)].value = key
        rtn['A'+str(i)].font = Font(name="Times New Roman", size=14, bold=True)
        rtn['A' + str(i)].alignment = Alignment(vertical="center")
        rtn['A' + str(i)].alignment = Alignment(horizontal="center")
        rtn['A' + str(i)].border = border
        i+=2

    i=0
    for j in range(3,row,2):
        key = dic[rtn["A"+str(j)].value]
        for k in range(1,clm+2):
            c = lst[k-1]
            rtn[c + str(j)].border = border
            rtn[c + str(j + 1)].border = border
            for x in key:
                if rtn[c+'2'].value == x[1]:
                    rtn[c + str(j)].value = str(x[0])
                    rtn[c + str(j+1)].value = f"(Room : {str(x[2])})"
                    rtn[c + str(j)].font = Font(name="Times New Roman", size=13.5)
                    rtn[c + str(j+1)].font = Font(name="Times New Roman", size=12)
                    rtn[c + str(j)].alignment = Alignment(horizontal="center")
                    rtn[c + str(j + 1)].alignment = Alignment(horizontal="center")

                    break

        i+=1

    workbook.save(f"{path}/{sec}.xlsx")

kv = '''

ScreenManager:
    Front:
    Second:
    Routine_Show:

<Front>:

    name: "front"

    BoxLayout:
        padding: 20
        orientation: "vertical"
        MDLabel:
            text : "Instructions"
            style : "Times New Roman"
            font_style: "H3"
            size_hint: 1,.1
            pos_hint: {"x":.15,"center_y": 1}

        MDLabel:
            size_hint: .5,.05
            pos_hint: {"center_x":.5,"center_y":1}

        Scroll:
            size_hint: 1,.75
            do_scroll_y : True
            MDLabel:
                text: root.message
                text_size :  self.width, None
                pos_hint: {"center_x":1,"center_y":1}
                valign:"top"
                size_hint_y: None
                height: max(self.texture_size[1],self.parent.height)

        MDLabel:
            size_hint: .5,.05
            pos_hint: {"center_x":.5,"center_y":1}

        MDRaisedButton:
            text: "Routine Scrapper"
            pos_hint: {"center_x":.5,"center_y":1}
            on_press: root.manager.current = "function"

        MDLabel:
            size_hint: .5,.1
            pos_hint: {"center_x":.5,"center_y":1}

<Second>:
    name: "function"

<Routine_Show>:
    name: "show"

<Scroll@MDScrollView>

'''

Generated=False

class Second(MDScreen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.orientation = "vertical"
        self.spacing=15
        self.padding=20
        b1 = MDRaisedButton(text="Choose Routine",size_hint=[.5,.08],pos_hint={"center_x":.5,"center_y":.85},on_press= self.selectfile,md_bg_color="#30c6d1",text_color="#292929")
        self.b2 = MDRaisedButton(text="Routine Page", size_hint=[.5, .07], pos_hint={"center_x": .5,"center_y":.34},on_press= self.show_routine,md_bg_color="#31de8d",text_color="#292929",disabled=True)
        b3 = MDRaisedButton(text="Help", size_hint=[.2, .07], pos_hint={"center_x": .5,"center_y":.2},on_press = self.poppup,md_bg_color="#3c3d3d",text_color="white")

        self.add_widget(b1)

        self.code_text = MDTextField(multiline=False,size_hint=[.6, .1],pos_hint={"center_x": .5,"center_y":.65},hint_text="Enter Course Codes or Semester")
        self.add_widget(self.code_text)

        self.sec = MDTextField(multiline = False,size_hint=[.25, .06],pos_hint={"center_x": .5,"center_y":.5},hint_text="Enter Section")
        self.add_widget(self.sec)

        self.add_widget(self.b2)

        self.add_widget(b3)
        self.add_widget(MDLabel(text="0242320005341689", size_hint=[.5, .1],pos_hint={"center_x": .55,"center_y":.08},theme_text_color="Custom",text_color="#171717"))

    def first(self,obj):
        self.manager.current= 'third'

    def selectfile(self,obj):
       # primary_external_storage_path()   or
        path = os.path.expanduser("~") or os.path.expanduser("/")
        self.file = MDFileManager(select_path=self.select_path)
        self.file.show(path)

    def select_path(self, path: str):
        self.path = path
        self.exit_manager()

    def exit_manager(self,*arg):
        self.file.close()
        self.b2.disabled=False
    def show_routine(self,obj):
        loc = self.path
        loc_list=loc.split('/')
        file = loc_list.pop().split('.')
        loctn[0] = '/'.join(loc_list)
        loctn[1] = self.sec.text.upper()
        if file[-1]=='xlsx':
            location=loc
            self.save_loc='/'.join(loc_list)
            self.section = self.sec.text.upper()
            code = self.code_text.text
            if code[0] in semester.keys():
                txt = semester[code[0]].split()
            else:
                txt=code.split()
            subjects = []
            for ele in txt:
                if ele[-1] == 'L':
                    lab = ele.split('_')
                    subjects.append(lab[0] + self.section + '1')
                    subjects.append(lab[0] + self.section + '2')
                else:
                    subjects.append(ele + self.section)
            routine_separateor(location, subjects)
            for keys in days:
                if days[keys] != []:
                    day[keys] = days[keys]
            for keys in days:
                days[keys] = []

            Generated = True

            self.manager.current = "show"

        else:
            wrong = wrongfile()
            pop = Popup(title="Wrong File",content=wrong, size_hint=[.8, .2], pos_hint={"center_x": .5})
            pop.open()

    def poppup(self,obj):
        self.manager.current = "front"

class wrongfile(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.txt = MDLabel(text="Please select an excel file.",
                           size_hint=[.5,1],size = self.size,pos_hint={"top":1.1},
                           theme_text_color="Custom",text_color="#e6e5e3")
        self.add_widget(self.txt)

class success(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.txt = MDLabel(text="Successfully saved the routine ",
                           size_hint=[.5,1],size = self.size,pos_hint={"top":1.1},
                           theme_text_color="Custom",text_color="#e6e5e3")
        self.add_widget(self.txt)

class helptxt(BoxLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.txt = MDLabel(text=hm,
                           size_hint=[.5,1],size = self.size,pos_hint={"top":1.1},
                           theme_text_color="Custom",text_color="#e6e5e3",font_style="Body2")
        self.add_widget(self.txt)

class Front(MDScreen):
    message=hm
    pass

class Routine_Show(MDScreen):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.add_widget(MDRaisedButton(text='Show Routine',on_press = self.show, pos_hint={'center_x':.5,'center_y':.9},md_bg_color="#30c6d1",text_color="#292929"))
        self.add_widget(MDRaisedButton(text='Save', pos_hint={"center_x": .5, "center_y": .2}, on_press=self.store,md_bg_color="#31de8d",text_color="#292929"))
        self.add_widget(MDRaisedButton(text='Routine Scrapper', pos_hint={"center_x": .5, "center_y": .1}, on_press=self.change,md_bg_color="#176963",text_color="white"))

    def show(self,obj):
        clmn = [('',dp(22))]
        row = []
        for time in times:
            clmn.append((time,dp(25)))
        for key in day.keys():
            lst=[key]
            k = day[key]
            for time in times:
                hagu = False
                for subs in k:
                    if subs[1] == time:
                        lst.append(f"{subs[0]}\nRoom: {subs[2]}")
                        hagu=True
                        break
                if hagu == False:
                    lst.append('')
            row.append(lst)

        # for key in day.keys():
        #     clmn.append((key,dp(23)))
        # end = len(day)+1
        # time_size=len(times)
        # for time in times:
        #     # time = times[t]
        #     lst = [time]
        #     for i in range(1,end):
        #         hagu = False
        #         k = day[clmn[i][0]]
        #         for subs in k:
        #             if subs[1] == time:
        #                 lst.append(f"{subs[0]}\nRoom: {subs[2]}")
        #                 hagu = True
        #                 break
        #         if hagu == False:
        #             lst.append('')
        #     row.append(lst)

        pd = 25
        table = MDDataTable(
            pos_hint={'center_x':.5,'center_y':.55},
            size_hint = [.9,.56],
            column_data = clmn,
            row_data = row,
            rows_num = 8
        )
        self.add_widget(table)

    def store(self,obj):

        create_routine(day, loctn[1], times, loctn[0])
        show = success()
        pop = Popup(title=f"{loctn[0]}/{loctn[1]}.xlsx",content=show, size_hint=[.8, .2], pos_hint={"center_x": .5})
        pop.open()

    def change(self,obj):
        self.manager.current = 'function'
        day.clear()
        times.clear()

sm = ScreenManager()
sm.add_widget(Front(name='front'))

class DIU_Routine(MDApp):
    def build(self):
        self.theme_cls.theme_style= "Dark"
        kk = Builder.load_string(kv)
        kk.message=hm
        return kk

    # def on_start(self):
    #     request_permissions([Permission.WRITE_EXTERNAL_STORAGE, Permission.READ_EXTERNAL_STORAGE])

if __name__ == "__main__":
    DIU_Routine().run()


# -*- coding: utf-8 -*-
import torch.nn as nn
import torch

class Affine(nn.Module):
    """
    实现全连接层, y=x * W_t + b
    """

    def __init__(self, in_features: int, out_features: int):
        super().__init__()
        self.w = nn.Parameter(torch.randn(in_features, out_features))
        self.b = nn.Parameter(torch.randn(out_features))

    def forward(self, x):
        x = x.mm(self.w)
        return x + self.b.expand_as(x)

def test_Affine():
    # 输入特征数量是3， 输出特征数量是4
    affine = Affine(3, 4)
    x = torch.randn(2, 3, requires_grad=True)
    output = affine(x)

    # 直接使用nn.Linear
    linear = nn.Linear(3, 4)
    linear_output = linear(x)
    print("output: {}\nlinear_output: {}".format(output, linear_output))

class Perceptron(nn.Module):
    """
    多层感知机
    """

    def __init__(self, input_features, hidden_features, output_features):
        nn.Module.__init__(self)
        self.layer1 = Affine(input_features, hidden_features)
        self.layer2 = Affine(hidden_features, output_features)

    def forward(self, input):
        x1 = self.layer1(input)
        output = self.layer2(x1)
        return output

    def print_parameters(self):
        for name, patameter in self.named_parameters():
            print("name:{}, type:{}".format(name, patameter.size()))

class NN_Perecptron(nn.Module):

    def __init__(self, input_features, hidden_features, output_features):
        nn.Module.__init__(self)
        self.hidden_layer = nn.Linear(in_features=input_features, out_features=hidden_features, bias=True)
        self.output_layer = nn.Linear(in_features=hidden_features, out_features=output_features, bias=True)

    def forward(self, input: torch.Tensor):
        hidden_output = self.hidden_layer(input)
        output = self.output_layer(hidden_output)
        return output

    def print_parameters(self):
        for name, patameter in self.named_parameters():
            print("name:{}, type:{}".format(name, patameter.shape))

def test_Perceptron():
    input = torch.randn(5, 3)
    perceptron = Perceptron(3, 4, 2)
    perceptron.print_parameters()
    output = perceptron(input)
    print("output:{}".format(output))

    print("==" * 30)

    nn_perceptron = NN_Perecptron(input_features=3, hidden_features=4, output_features=2)
    print("output: {}".format(nn_perceptron(input)))
    nn_perceptron.print_parameters()

    # name:hidden_layer.weight, type:torch.Size([4, 3]) # 这里的[4,3]而不是[3,4]是由于x乘的是W转置的原因
    # name:hidden_layer.bias, type:torch.Size([4])
    # name:output_layer.weight, type:torch.Size([2, 4])
    # name:output_layer.bias, type:torch.Size([2])

def test_batch_norm():
    # 4 Channel
    bn1d = nn.BatchNorm1d(4)
    bn1d.weight.data = torch.ones(4) * 4
    bn1d.bias.data = torch.zeros(4)

    input_x = torch.randn(2, 4)
    bn_out = bn1d(input_x)
    print("bn_out: {}".format(bn_out))
    print("bn_out mean(0): {}\nbn_out.var() :{}".format(bn_out.mean(0), bn_out.var(unbiased=False)))

def test_dropout():
    # 每个元素以0.5的概率舍弃
    dropout = nn.Dropout(0.5)
    input_x = torch.randn(3, 4)
    print("before dropout, input_x:{}".format(input_x))
    o = dropout(input_x)
    print("after dropout, input_x:{}".format(o))

def test_RNN():
    """
     h_t = \text{tanh}(W_{ih} x_t + b_{ih} + W_{hh} h_{(t-1)} + b_{hh})
    :return:
    """
    rnn = nn.RNN(input_size=100, hidden_size=50, num_layers=1, bias=True, batch_first=True, dropout=0.5,
                 nonlinearity="relu")
    # (batch, seq_len input_size)
    input_x = torch.rand((10, 20, 100))

    # num_layers * num_directions, batch, hidden_size
    h_0 = torch.zeros((1 * 1, 10, 50))

    # output size: [seq_len, batch, num_directions * hidden_size]
    # h_n size: [num_layers * num_directions, batch, hidden_size]
    output, h_n = rnn(input_x, h_0)

    print("output size:{}\nh_n size:{}".format(output.size(), h_n.size()))

    output = output.transpose(0, 1)
    print("output shape:{}".format(output.shape))

    id(output[-1, :, :].storage()) == id(h_n.storage())

    print("====" * 4 + "RNN 参数 size" + "====" * 4)
    for name, parameter in rnn.named_parameters():
        print("name:{}, parameter size:{}".format(name, parameter.shape))

def test_lstm():
    torch.manual_seed(1000)
    # input shape: [batch, seq_len, input_size] batch_first=True
    # seq可以理解为时间序列的长度，比如在NLP里面可以代表一句话的长度
    input_x = torch.randn((2, 3, 4))

    lstm = nn.LSTM(input_size=4, batch_first=True, hidden_size=5, num_layers=1)

    # h_0 shape: [num_layers * num_directions, batch, hidden_size]
    h_0 = torch.randn(1, 2, 5)
    # c_0 shape: [num_layers * num_directions, batch, hidden_size]
    c_0 = torch.rand(1, 2, 5)

    # output shape: [batch, seq_len, num_directions * hidden_size]
    # h_n shape: [num_layers * num_directions, batch, hidden_size]
    # c_n shape: [num_layers * num_directions, batch, hidden_size]
    output, (h_n, c_n) = lstm(input_x, (h_0, c_0))

    last_out = output[-1, :, :]

    print("last_out: {}".format(last_out))
    print("tanh(c_n): {}".format(torch.tanh(c_n.transpose(0, 1))))
    print("out_last :{}".format(h_n / torch.tanh(c_n)))

    # print("h_last: {}".format(h_last))
    print("output:{}\nh_n shape:{}\nh_n: {}\nc_n:shape:{}\nc_n:{}".format(output.shape, h_n.shape, h_n, c_n.shape, c_n))

def test_embedding():
    embedding = nn.Embedding(num_embeddings=10, embedding_dim=3, padding_idx=0)
    # 可以用预训练好的词向量初始化embedding
    embedding.weight.data = torch.arange(0, 30).view(10, 3)

    input_x = torch.arange(7, 0, -1).long()
    output = embedding(input_x)
    print("output: {}".format(output))

    embedding = nn.Embedding(5, 3)
    input_ids = torch.LongTensor([[1, 2, 3, 4], [0, 1, 2, 4]])
    print("input_ids shape:{}".format(input_ids.shape))
    # input_ids shape: [2,4]

    out = embedding(torch.LongTensor(input_ids))
    print("out shape:{}".format(out.shape))
    # out shape: [2, 4, 3]

def conv1_test():
    conv1 = nn.Conv1d(in_channels=128, out_channels=100, kernel_size=3, stride=1, padding=3)
    # N, C, L = batch_size, in_channel, sequence_len
    input_x = torch.randn(29, 128, 63)
    # 计算输出的特征大小: (L_in - kernel_size +  2 * padding)/ stride + 1
    #
    conv1_out = conv1(input=input_x)
    print("conv1_out shape: {}".format(conv1_out.shape))
    # [29, 100, 67]

def test_embeddingBag():
    embedding = nn.EmbeddingBag(num_embeddings=10, embedding_dim=3)
    # 三个batch, 分别包含2个,3个,3个indices
    input_x = torch.LongTensor([1,2,4,5,4,3,2,9])
    offsets = torch.LongTensor([0,2,5])
    embedding_mean = embedding(input_x, offsets)
    print("embedding_mean: {}".format(embedding_mean))
    # embedding_mean: tensor([[-0.0401, -0.1045, -0.3961],
    #         [ 0.3339,  2.7423,  0.7119],
    #         [-0.9661,  0.0946,  0.2269]], grad_fn=<EmbeddingBagBackward>)

if __name__ == "__main__":
    # test_Perceptron()
    # test_batch_norm()
    # test_dropout()
    # test_RNN()
    # test_lstm()
    # test_embedding()
    conv1_test()