#!/usr/bin/python3
"""
Tools to simplify visualization
"""
# Author: Lukas Huber
# Created: 2021-05-16

import sys
import warnings
from typing import Optional

import numpy as np
import numpy.typing as npt
import numpy.linalg as LA

import matplotlib as mpl

# import matplotlib.pyplot as plt

def draw_obstacle_patches(
    obstacle_list,
    ax,
    plot_dims: npt.ArrayLike = (0, 1),
    colors: Optional[list[str]] = None,
    plot_centers: bool = True,
    ellipse_alpha: float = 0.5,
    axes_scaling: float = 1.0,
):
    for ii, obs in enumerate(obstacle_list):
        path_axes = obs.axes_length * 2 * axes_scaling
        ell = mpl.patches.Ellipse(
            obs.center_position,
            path_axes[0],
            path_axes[1],
            obs.orientation * 180 / np.pi,
            color=colors[ii],
            zorder=-2,
        )

        ell.set_clip_box(ax.bbox)
        ell.set_alpha(ellipse_alpha)
        ax.add_artist(ell)

        if plot_centers:
            ax.plot(
                gmm.means_[n, plot_dims[0]],
                gmm.means_[n, plot_dims[1]],
                "k.",
                markersize=12,
                linewidth=30,
            )
        # ax.plot(gmm.means_[n, 0], gmm.means_[n, 1], 'k+', s=12)

def draw_gaussians(
    gmm,
    ax,
    plot_dims: npt.ArrayLike = (0, 1),
    colors: Optional[list[str]] = None,
    plot_centers: bool = True,
    ellipse_alpha: float = 0.5,
):
    if colors is None:
        colors = [
            "navy",
            "turquoise",
            "darkorange",
            "blue",
            "green",
            "purple",
            "black",
            "violet",
            "tan",
            "red",
        ]

    if isinstance(colors, np.ndarray):
        color_list = []
        for ii in range(colors.shape[1]):
            color_list.append(colors[:, ii])
        colors = color_list

    n_gaussian = gmm.n_components

    for n in range(n_gaussian):
        color = colors[np.mod(n, len(colors))]
        if gmm.covariance_type == "full":
            covariances = gmm.covariances_[n][plot_dims, :][:, plot_dims]
        elif gmm.covariance_type == "tied":
            covariances = gmm.covariances_[plot_dims, :][:, plot_dims]
        elif gmm.covariance_type == "diag":
            covariances = np.diag(gmm.covariances_[n][plot_dims])
        elif gmm.covariance_type == "spherical":
            covariances = np.eye(gmm.means_.shape[1]) * gmm.covariances_[n]

        v, w = np.linalg.eigh(covariances)
        u = w[0] / np.linalg.norm(w[0])
        angle = np.arctan2(u[1], u[0])
        angle = 180 * angle / np.pi  # convert to degrees
        v = 2.0 * np.sqrt(2.0) * np.sqrt(v)

        ell = mpl.patches.Ellipse(
            gmm.means_[n, plot_dims],
            v[0],
            v[1],
            180 + angle,
            color=color,
            zorder=-2,
        )

        ell.set_clip_box(ax.bbox)
        ell.set_alpha(ellipse_alpha)
        ax.add_artist(ell)

        if plot_centers:
            ax.plot(
                gmm.means_[n, plot_dims[0]],
                gmm.means_[n, plot_dims[1]],
                "k.",
                markersize=12,
                linewidth=30,
            )
        # ax.plot(gmm.means_[n, 0], gmm.means_[n, 1], 'k+', s=12)


import os
import numpy as np
import pandas as pd
import gdal, osr
import scipy.stats
from netCDF4 import Dataset
from matplotlib import pyplot as plt
from matplotlib import cm
import seaborn as sns
from sklearn.metrics import mean_absolute_error, mean_squared_error, median_absolute_error, r2_score

from statsmodels.stats.multitest import multipletests
from matplotlib import pyplot as plt
from matplotlib import cm
from matplotlib.colors import ListedColormap
from matplotlib import pyplot
from mpl_toolkits.mplot3d import Axes3D
from pylab import rcParams

# Функция предсказания для выбранного года значения урожайности
def predict(path, year, crop_data, country, crop):
    # Папки, в которых хранятся данные
    all = os.path.join(path, '01_06')
    feb = os.path.join(path, '02')
    apr = os.path.join(path, '04')
    june = os.path.join(path, '06')

    for parameter in ['Tmp', 'Pressure', 'Rainfall']:
        # Присоединяем все параметры к нужным папкам
        all_parameter = os.path.join(all, parameter)
        feb_parameter = os.path.join(feb, parameter)
        apr_parameter = os.path.join(apr, parameter)
        june_parameter = os.path.join(june, parameter)

        # Ищем файл, который будет использоваться в качестве основного
        name = str(year)
        # Первое полугодие в общем
        all_files = os.listdir(all_parameter)
        all_files.sort()
        for file in all_files:
            if file.startswith(name):
                all_parameter_main = os.path.join(all_parameter, file)
        # Распределение парамерта в феврале
        feb_files = os.listdir(feb_parameter)
        feb_files.sort()
        for file in feb_files:
            if file.startswith(name):
                feb_parameter_main = os.path.join(feb_parameter, file)
        # Распределение парамерта в апреле
        apr_files = os.listdir(apr_parameter)
        apr_files.sort()
        for file in apr_files:
            if file.startswith(name):
                apr_parameter_main = os.path.join(apr_parameter, file)
        # Распределение парамерта в июне
        june_files = os.listdir(june_parameter)
        june_files.sort()
        for file in june_files:
            if file.startswith(name):
                june_parameter_main = os.path.join(june_parameter, file)

        # Массивы для указанного года
        ALL_PARAMETER = np.load(all_parameter_main)
        FEB_PARAMETER = np.load(feb_parameter_main)
        APR_PARAMETER  = np.load(apr_parameter_main)
        JUNE_PARAMETER  = np.load(june_parameter_main)

        ##################################################################################################
        # Блок сравнения массивов одного года с распределениями соответствующего параметра в другие годы #
        ##################################################################################################
        result_list = []
        for YEAR in range(1990, year):

            # Ищем файл, который будет использоваться в качестве основного
            name = str(YEAR)
            # Первое полугодие в общем
            all_files = os.listdir(all_parameter)
            all_files.sort()
            for file in all_files:
                if file.startswith(name):
                    all_parameter_main = os.path.join(all_parameter, file)
            # Распределение парамерта в феврале
            feb_files = os.listdir(feb_parameter)
            feb_files.sort()
            for file in feb_files:
                if file.startswith(name):
                    feb_parameter_main = os.path.join(feb_parameter, file)
            # Распределение парамерта в апреле
            apr_files = os.listdir(apr_parameter)
            apr_files.sort()
            for file in apr_files:
                if file.startswith(name):
                    apr_parameter_main = os.path.join(apr_parameter, file)
            # Распределение парамерта в июне
            june_files = os.listdir(june_parameter)
            june_files.sort()
            for file in june_files:
                if file.startswith(name):
                    june_parameter_main = os.path.join(june_parameter, file)

            # Распределение в этот конкретный год
            ALL_PARAMETER_THIS = np.load(all_parameter_main)
            FEB_PARAMETER_THIS = np.load(feb_parameter_main)
            APR_PARAMETER_THIS = np.load(apr_parameter_main)
            JUNE_PARAMETER_THIS = np.load(june_parameter_main)

            # Производим сравнение двух выборок по критерию Крускала-Уоллиса
            # Либо можно использовать ks_2samp - критерий Колмогорова-Смирнова
            all_stat = scipy.stats.kruskal(ALL_PARAMETER, ALL_PARAMETER_THIS)
            feb_stat = scipy.stats.kruskal(FEB_PARAMETER, FEB_PARAMETER_THIS)
            apr_stat = scipy.stats.kruskal(APR_PARAMETER, APR_PARAMETER_THIS)
            june_stat = scipy.stats.kruskal(JUNE_PARAMETER, JUNE_PARAMETER_THIS)

            if parameter == 'Tmp':
                # Записываем значение статистики
                result_list.append([YEAR, all_stat.statistic, all_stat.pvalue, feb_stat.statistic, feb_stat.pvalue,
                                    apr_stat.statistic, apr_stat.pvalue, june_stat.statistic, june_stat.pvalue])
            else:
                result_list.append([all_stat.statistic, all_stat.pvalue, feb_stat.statistic, feb_stat.pvalue,
                                    apr_stat.statistic, apr_stat.pvalue, june_stat.statistic, june_stat.pvalue])

        # Переводим массив в нужный формат
        result_list = np.array(result_list)
        # После того, как таблица по конкретному параметру сформирована - присоединяем
        if parameter == 'Tmp':
            data = result_list
        else:
            data = np.hstack((data, result_list))

    dataframe = pd.DataFrame(data, columns=['Year', 'TMP_All.stat', 'TMP_All.pvalue', 'TMP_Feb.stat', 'TMP_Feb.pvalue',
                                            'TMP_Apr.stat', 'TMP_Apr.pvalue', 'TMP_June.stat', 'TMP_June.pvalue',
                                            'PRS_All.stat', 'PRS_All.pvalue', 'PRS_Feb.stat', 'PRS_Feb.pvalue',
                                            'PRS_Apr.stat', 'PRS_Apr.pvalue', 'PRS_June.stat', 'PRS_June.pvalue',
                                            'RAN_All.stat', 'RAN_All.pvalue', 'RAN_Feb.stat','RAN_Feb.pvalue',
                                            'RAN_Apr.stat', 'RAN_Apr.pvalue', 'RAN_June.stat', 'RAN_June.pvalue'])

    # В подготовленном датасете каждая строка содержит значения статистики + значение pvalue
    # Необходимо ввести поправку на множественное тестирование и сравнить к какому году ближе всего
    local_data1 = np.array(dataframe[['TMP_All.pvalue', 'TMP_Feb.pvalue', 'TMP_Apr.pvalue', 'TMP_June.pvalue',
                                     'PRS_All.pvalue', 'PRS_Feb.pvalue', 'PRS_Apr.pvalue', 'PRS_June.pvalue',
                                     'RAN_All.pvalue', 'RAN_Feb.pvalue', 'RAN_Apr.pvalue', 'RAN_June.pvalue']])
    local_data2 = np.array(dataframe[['TMP_All.stat', 'TMP_Feb.stat', 'TMP_Apr.stat', 'TMP_June.stat',
                                     'PRS_All.stat', 'PRS_Feb.stat', 'PRS_Apr.stat', 'PRS_June.stat',
                                     'RAN_All.stat', 'RAN_Feb.stat', 'RAN_Apr.stat', 'RAN_June.stat']])
    # Сумма превышений статистик над скорректированным pvalue
    sum_vals = []
    for id_string in range(0, len(local_data1)):
        pvals = np.ravel(local_data1[id_string])
        # Поправка на множественное тестирование Бонферронни
        arr = multipletests(pvals, method = 'bonferroni')
        corrected_pvals = arr[1]

        # Теперь берем значения статистик
        statistics = np.ravel(local_data2[id_string])

        # Разность значения статистик и скорректированных pvalue
        diff = statistics - corrected_pvals
        # Суммируем значения превышений, то есть чем меньше значение суммы превышений статистик над уровнем значимости
        # Тем выше более похожи два рассматриваемых года
        sum_vals.append(np.sum(diff))

    sum_vals = np.array(sum_vals)
    # Индекс самого минимального значения в рассчитанных характеристиках
    id_min = np.argmin(sum_vals)
    dataframe['sum_vals'] = sum_vals

    similar_year = str(dataframe['Year'][id_min])
    print('Наиболее "похожий" на', year ,'год -', similar_year)

    # Загружаем датасет с данными по урожайности
    crop_dataframe = pd.read_csv(crop_data, sep=',', dtype={'Entity': str, 'Year': str})
    # Выбираем только те данные, которые есть для конкретной стртаны
    crop_dataframe = crop_dataframe[crop_dataframe.Entity == country]
    crop_dataframe.drop(columns='Code', inplace=True)

    predicted_dataset = crop_dataframe[crop_dataframe.Year == similar_year[:4]]
    prediction = np.array(predicted_dataset[crop])
    print('Предсказанное значение урожайности -', prediction[0])

    actual_dataset = crop_dataframe[crop_dataframe.Year == str(year)]
    actual = np.array(actual_dataset[crop])
    print('Действительное значение урожайности -', actual[0], '\n')

    return(prediction, actual)

# Графики остатков + информация по метрикам
# Расчет метрики - cредняя абсолютная процентная ошибка
def mean_absolute_percentage_error(y_true, y_pred):
    y_true = np.ravel(y_true)
    y_pred = np.ravel(y_pred)
    # У представленной ниже формулы есть недостаток, - если в массиве y_true есть хотя бы одно значение 0.0,
    # то по формуле np.mean(np.abs((y_true - y_pred) / y_true)) * 100 мы получаем inf, поэтому
    zero_indexes = np.argwhere(y_true == 0.0)
    for index in zero_indexes:
        y_true[index] = 0.01
    value = np.mean(np.abs((y_true - y_pred) / y_true)) * 100
    return (value)

# Зададим функцию, которая будет выводить на экран значения метрик
def print_metrics(y_test, prediction):
    print('Mean absolute error in the test sample -', round(mean_absolute_error(y_test, prediction),2))
    print('Median absolute error in the test sample -', round(median_absolute_error(y_test, prediction),2))
    print('Root mean square error in the test sample -', round(mean_squared_error(y_test, prediction) ** 0.5, 2))
    print('Mean absolute percentage error in the test sample -', round(mean_absolute_percentage_error(y_test, prediction), 2))

# Зададим функцию для отрисовки графиков
def residuals_plots(y_test, prediction, color='blue'):
    prediction = np.ravel(prediction)
    y_test = np.ravel(y_test)
    # Рассчитываем ошибки
    errors = prediction - y_test
    errors = np.ravel(errors)

    plot_data = pd.DataFrame({'Errors': errors,
                              'Prediction': prediction})

    with sns.axes_style("ticks"):
        g = (sns.jointplot('Prediction', 'Errors', height=7, alpha=0.6,
                           data=plot_data, color=color).plot_joint(sns.kdeplot, zorder=0, n_levels=6))
        g.ax_joint.plot([min(prediction) - 0.1, max(prediction) + 0.1], [0, 0], linewidth=1, linestyle='--',
                        color=color)
        g.ax_marg_y.axhline(y=0, linewidth=1, linestyle='--', color=color)
        plt.xlabel('Predicted value', fontsize=15)
        plt.ylabel('Errors, tones/ha', fontsize=15)
        plt.show()

        g = (sns.jointplot('Prediction', 'Errors', kind="kde", data=plot_data, space=0, height=7,
                           color=color, alpha=0.2))
        g.set_axis_labels('Predicted value', 'Errors, tones/ha', fontsize=15)
        g.ax_joint.plot([min(prediction) - 0.1, max(prediction) + 0.1], [0, 0], linewidth=1, linestyle='--',
                        color=color)
        g.ax_marg_y.axhline(y=0, linewidth=1, linestyle='--', color=color)
        plt.show()

# Применение модели для Франции
# Wheat (tonnes per hectare)
# Rice (tonnes per hectare)
# Maize (tonnes per hectare)
# Barley (tonnes per hectare)
# France Germany Italy Romania Spain Czech Republic Netherlands Switzerland Austria Poland
# country = 'Poland'
# crop = 'Barley (tonnes per hectare)'
# main_path = os.path.join('/media/mikhail/Data/ITMO/Reanalysis_grid_Europe/Processed_grid/Distributions_files', country)
#
# reals = []
# preds = []
# ys = []
# # 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
# for j in [2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018]:
#     pred, real = predict(main_path, j, '/media/mikhail/Data/ITMO/Reanalysis_grid_Europe/Crop_yields_info.csv', country, crop = crop)
#     reals.append(real)
#     preds.append(pred)
#     ys.append(j)
#
# ys = np.array(ys)
# reals = np.array(reals)
# preds = np.array(preds)
# print_metrics(reals, preds)
# residuals_plots(reals, preds, color = 'blue')
#
# # Переводим все в одномерный массивы
# ys = np.ravel(ys)
# reals = np.ravel(reals)
# preds = np.ravel(preds)
# # Теперь необходимо сохранить предсказания в файл
# df = pd.DataFrame({'Year': ys,
#                    'Prediction': preds,
#                    'Real': reals})
#
# file_name = 'Distribution_' + country + '_' + crop + '.csv'
# file_path = os.path.join('/media/mikhail/Data/ITMO/Reanalysis_grid_Europe/RESULTS', file_name)
# df.to_csv(file_path, sep=';', encoding='utf-8', index = False)


from typing import List

from user.model import Buyer
from product.model import Product

from product.product_schemas import BaseProduct

async def get_basket_goods(username: str) -> List[BaseProduct]:

    user: Buyer = await Buyer.objects.get(username=username)
    user_basket: List[BaseProduct] = await Product.objects.select_related(['baskets']).filter(
        baskets__user_id=user.id
            ).values()

    return user_basket

async def dict_for_redis(key_prefix: str, list_of_items: List[any]):

    new_dict = dict()
    for item in list_of_items:
        dict_key: str = key_prefix + item['name']
        new_dict[dict_key] = item

    return new_dict


from mlc.utils.io_utils import get_files_given_a_pattern
import numpy as np
import json
import os
from pathlib import Path

def get_stats_scores(dir_results):
    scores = get_scores(dir_results)

    data_out = dict(training_exp=Path(dir_results).stem)
    for scores_by in ["best_2d_iou_score", "best_3d_iou_score"]:
        scores = {k: v for k, v in sorted(scores.items(), key=lambda item: item[1]['best_iou_valid_score'][scores_by])}
        list_scores = [sc['best_iou_valid_score'][scores_by] for sc in scores.values()]
        data_out[f"by_{scores_by}"] = {list(scores.keys())[-1]: scores[list(scores.keys())[-1]]}
        data_out[f"by_{scores_by}"]["stats"]=dict(
                    std=np.std(list_scores),
                    variance=np.std(list_scores)**2,
                    median=np.median(list_scores),
                    mean=np.mean(list_scores),
                    max=np.max(list_scores),
                    min=np.min(list_scores),
                    scores=list_scores,
                    samples=list_scores.__len__())

    # scores = {k: v for k, v in sorted(scores.items(), key=lambda item: item[1]['best_h_valid_score'])}
    # list_scores = [sc['best_h_valid_score'] for sc in scores.values()]
    # data_out[f"by_best_h_valid_score"] = {list(scores.keys())[-1]: scores[list(scores.keys())[-1]]}
    # data_out[f"by_best_h_valid_score"]["stats"]=dict(
    #                 std=np.std(list_scores),
    #                 variance=np.std(list_scores)**2,
    #                 median=np.median(list_scores),
    #                 mean=np.mean(list_scores),
    #                 max=np.max(list_scores),
    #                 min=np.min(list_scores),
    #                 scores=list_scores,
    #                 samples=list_scores.__len__())
    return data_out

def get_scores(training_dir):
    list_json_fn  = get_files_given_a_pattern(training_dir, "best_score.json", exclude='log')
    if list_json_fn.__len__() == 0:
        assert list_json_fn.__len__() > 0, f"No best_score.json files found at {os.path.join(training_dir)}"
    scores = {}
    for json_fn in list_json_fn:
        exp_label = json_fn.split("/")[-2]
        scores[exp_label] = json.load(open(os.path.join(json_fn, "best_score.json")))
    return scores


import re
import tensorflow as tf
from typing import List

def fit_bn(model, *args, **kwargs):
    """Resets batch normalization layers of model, and recalculates the
    statistics for each batchnorm layer by running a pass on the data.

    Args:
        model: An instance of tf.keras.Model
        *args, **kwargs: Params that'll be passed to `.fit` method of model
    """
    kwargs["epochs"] = 1
    if not isinstance(model, tf.keras.Model):
        raise TypeError("model must be an instance of tf.keras.Model")

    if not model.built:
        raise ValueError("Call `fit_bn` after the model is built and trained")

    assign_ops = []
    for layer in model.layers:
        if isinstance(layer, tf.keras.layers.BatchNormalization):
            assign_ops.extend(
                [
                    layer.moving_mean.assign(tf.zeros_like(layer.moving_mean)),
                    layer.moving_variance.assign(tf.ones_like(layer.moving_variance)),
                ]
            )

    _trainable = model.trainable
    _metrics = model._metrics
    model.trainable = False
    model._metrics = []

    model.fit(*args, **kwargs)

    model.trainable = _trainable
    model._metrics = _metrics

def get_variable_name(variable) -> str:
    """Get the variable name from the variable tensor."""
    param_name = variable.name
    m = re.match("^(.*):\\d+$", param_name)
    if m is not None:
        param_name = m.group(1)
    return param_name

def is_variable_matched_by_regexes(variable, regexes: List[str]) -> bool:
    """Whether variable is matched in regexes list by its name."""
    if regexes:
        # var_name = get_variable_name(variable)
        var_name = variable.name
        for r in regexes:
            if re.search(r, var_name):
                return True
    return False


#!/usr/bin/env python3
import cgi
import cgitb
import json
import numpy as np
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Model
from tensorflow.keras.applications.inception_v3 import InceptionV3, preprocess_input
from pickle import load
from tensorflow.keras.preprocessing.image import load_img, img_to_array
import requests
from io import BytesIO
from flask import Flask, request, jsonify
from flask_cors import CORS
import os
import keras
import keras.utils as image
from keras.preprocessing.text import tokenizer_from_json
from keras.utils import pad_sequences
import matplotlib.pyplot as plt
import tensorflow as tf
import string
import requests
from PIL import Image
from io import BytesIO
import ssl
ssl._create_default_https_context = ssl._create_unverified_context

# Enable detailed error messages
cgitb.enable()

# Load the trained model to classify sign
base_model = InceptionV3(
    weights='inception_v3_weights_tf_dim_ordering_tf_kernels.h5')
vgg_model = Model(base_model.input, base_model.layers[-2].output)

def preprocess_img_from_url(url):
    # Inception V3 expects images in 299x299 size
    response = requests.get(url, verify=False)
    img = load_img(BytesIO(response.content), target_size=(299, 299))
    x = img_to_array(img)
    x = np.expand_dims(x, axis=0)
    x = preprocess_input(x)
    return x

def encode(image):
    image = preprocess_img_from_url(image)
    vec = vgg_model.predict(image)
    vec = np.reshape(vec, (vec.shape[1]))
    return vec

def greedy_search(pic, wordtoix, max_length):
    # Your implementation for greedy search goes here
    start = 'startseq'
    for i in range(max_length):
        seq = [wordtoix[word] for word in start.split() if word in wordtoix]
        seq = pad_sequences([seq], maxlen=max_length)
        yhat = model.predict([pic, seq])
        yhat = np.argmax(yhat)
        word = ixtoword[yhat]
        start += ' ' + word
        if word == 'endseq':
            break
    final = start.split()
    final = final[1:-1]
    final = ' '.join(final)
    return final

# Load the model (new-model-1.h5) for generating captions
model = load_model('new-model-1.h5')

# Load wordtoix and ixtoword from pickle files
with open('wordtoix.pkl', 'rb') as f:
    wordtoix = load(f)

with open('ixtoword.pkl', 'rb') as f:
    ixtoword = load(f)

############## Semantic model ################

def feature_extractions(directory, image_url):
    model = tf.keras.applications.vgg16.VGG16()
    model = keras.models.Model(inputs=model.input, outputs=model.layers[-2].output)
    url= image_url
    image_response = requests.get(url)
    img = Image.open(BytesIO(image_response.content))
    img = img.resize((224, 224))  # Resize the image to match the VGG16 input size

    arr = keras.utils.img_to_array(img, dtype=np.float32)
    arr = arr.reshape((1, arr.shape[0], arr.shape[1], arr.shape[2]))
    arr = keras.applications.vgg16.preprocess_input(arr)

    features = model.predict(arr, verbose=0)
    return features
def sample_caption(model, tokenizer, max_length, vocab_size, feature):
    caption = "<startseq>"
    while 1:
        encoded = tokenizer.texts_to_sequences([caption])[0]
        padded = pad_sequences([encoded], maxlen=max_length, padding='pre')[0]
        padded = padded.reshape((1, max_length))
        pred_Y = model.predict([feature, padded])[0,-1,:]
        next_word = tokenizer.index_word[pred_Y.argmax()]
        caption = caption + ' ' + next_word
        if next_word == '<endseq>' or len(caption.split()) >= max_length:
            break
    caption = caption.replace('<startseq> ', '')
    caption = caption.replace(' <endseq>', '')
    return(caption)

def funSemantic(image_url):
    with open('./semantic/File1.json', 'r') as f:
        tokenizer_json = json.load(f)
    tokenizer = tokenizer_from_json(tokenizer_json)
    model = keras.models.load_model("./semantic/File2.h5")
    vocab_size = tokenizer.num_words
    max_length = 37
    img = image_url
    features = feature_extractions("./semantic", img)
    filename = "img1.jpg"  # This should be the filename or identifier of the image
    # plt.figure()
    caption = sample_caption(model, tokenizer, max_length, vocab_size, features)
    img = tf.keras.utils.load_img("./semantic/" + filename)
    return(caption)

############## End Semantic model ################

# Create a Flask app
app = Flask(__name__)
CORS(app, supports_credentials=True)

# Define your Flask route to process the image

@app.route('/', methods=['POST'])
def process_image_route():
    data = request.get_json()
    image_url = data["image_url"]
    enc = encode(image_url)
    image = enc.reshape(1, 2048)

    # Define max_length (adjust this value based on your sequence length)
    max_length = 74

    # Example usage for generating captions using greedy search
    pred = greedy_search(image, wordtoix, max_length)

    semantic_caption = funSemantic(image_url)

    # Create a dictionary to store the caption
    result = {"caption": pred,"semantic": semantic_caption}
    # Return the JSON response
    return jsonify(result)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)


import os

from skimage import io
import torch
from torch.autograd import Variable
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torchvision import transforms

import numpy as np
from PIL import Image

from tqdm import auto

from data_loader import RescaleT
from data_loader import ToTensorLab
from data_loader import SalObjDataset

from model import U2NET  # full size version 173.6 MB
from model import U2NETP  # small version u2net 4.7 MB

# normalize the predicted SOD probability map
def normPRED(d):
    ma = torch.max(d)
    mi = torch.min(d)

    dn = (d - mi) / (ma - mi)

    return dn

def save_output(image_name, pred, d_dir):
    predict = pred
    predict = predict.squeeze()
    predict_np = predict.cpu().data.numpy()

    im = Image.fromarray(predict_np * 255).convert("RGB")
    img_name = image_name.split(os.sep)[-1]
    image = io.imread(image_name)
    imo = im.resize((image.shape[1], image.shape[0]), resample=Image.BILINEAR)

    pb_np = np.array(imo)

    aaa = img_name.split(".")
    bbb = aaa[0:-1]
    imidx = bbb[0]
    for i in range(1, len(bbb)):
        imidx = imidx + "." + bbb[i]

    imo.save(d_dir + imidx + ".png")

def main():
    # --------- 1. get image path and name ---------
    model_name = "u2net"  # u2netp

    image_dir = os.path.join(os.getcwd(), "test_data", "test_images")
    prediction_dir = os.path.join(
        os.getcwd(), "test_data", model_name + "_results" + os.sep
    )
    model_dir = os.path.join(
        os.getcwd(), "saved_models", model_name, model_name + ".pth"
    )
    main_path = "/home/piotr/Downloads/carcutter_dataset/background_remove/val/"
    # img_name_list = glob.glob(image_dir + os.sep + "*")
    img_name_list = [main_path + file for file in os.listdir(main_path)]
    print(img_name_list)

    # --------- 2. dataloader ---------
    # 1. dataloader
    test_salobj_dataset = SalObjDataset(
        img_name_list=img_name_list,
        lbl_name_list=[],
        transform=transforms.Compose([RescaleT(320), ToTensorLab()]),
    )
    test_salobj_dataloader = DataLoader(
        test_salobj_dataset, batch_size=1, shuffle=False, num_workers=1
    )

    # --------- 3. model define ---------
    if model_name == "u2net":
        print("...load U2NET---173.6 MB")
        net = U2NET(3, 1)
    elif model_name == "u2netp":
        print("...load U2NEP---4.7 MB")
        net = U2NETP(3, 1)

    if torch.cuda.is_available():
        net.load_state_dict(torch.load("saved_models/trained_models/u2net_2650_0.06782126222969964.pth")["model"])
        net.cuda()
    else:
        net.load_state_dict(
            torch.load("saved_models/trained_models/u2net_interior2.pth", map_location="cpu")[
                "model"])
    net.eval()
    os.makedirs("saved_images", exist_ok=True)
    # --------- 4. inference for each image ---------
    for i_test, data_test in auto.tqdm(enumerate(test_salobj_dataloader)):

        print("inferencing:", img_name_list[i_test].split(os.sep)[-1])

        inputs_test = data_test["image"]
        inputs_test = inputs_test.type(torch.FloatTensor)

        if torch.cuda.is_available():
            inputs_test = Variable(inputs_test.cuda())
        else:
            inputs_test = Variable(inputs_test)

        d1, d2, d3, d4, d5, d6, d7 = net(inputs_test)

        # normalization
        pred = d1[:, 0, :, :].detach()
        img = Image.open(img_name_list[i_test])
        pred = F.interpolate(pred.unsqueeze(0), img.size[::-1])[0].permute(1, 2, 0).numpy()
        img = np.asarray(img)
        pred_img = (img * (1 - pred) + pred * np.array([0, 255, 0])).astype("uint8")
        res_img = np.hstack([pred_img, img])
        # img = Image.fromarray((pred[:, :, 0] * 255).astype("uint8"), "L")
        img = Image.fromarray(res_img)
        img.save(f"saved_images2/{img_name_list[i_test].split('/')[-1]}")

        del d1, d2, d3, d4, d5, d6, d7

if __name__ == "__main__":
    main()


from fastapi import APIRouter, HTTPException
from enum import Enum
from collections import Counter

from fastapi.params import Query
from src import database as db
import sqlalchemy
from sqlalchemy import func
from src.api import datatypes

from sqlalchemy.exc import IntegrityError
from psycopg2.errors import ForeignKeyViolation
from sqlalchemy.orm.exc import NoResultFound

router = APIRouter()

@router.post("/fantasy_teams/", tags=["fantasy_teams"])
def create_fantasy_team(team: datatypes.Fantasy_Team):
    """
    Creates a new fantasy team with the
    specified team name and user id.

    `fantasy_team_name`: name of the fantasy team
    `user_id`: id of the user that owns this fantasy team

    Team balance is auto set to $10,000,000

    returns the id of the created fantasy_team
    """

    with db.engine.begin() as conn:

        sql = """
            INSERT INTO fantasy_teams (fantasy_team_name, user_id, fantasy_team_balance)
            VALUES ((:name),(:user_id), 10000000)
            returning fantasy_team_id"""

        params = {
                  'name': team.fantasy_team_name,
                  'user_id': team.user_id,
                  }

        try:
            new_team_id = conn.execute(sqlalchemy.text(sql),params).scalar_one()
        except sqlalchemy.exc.IntegrityError as e:
            error_msg = e.orig.diag.message_detail
            raise HTTPException(422, error_msg)

    return {"Team {} added".format(new_team_id)}

@router.post("/fantasy_teams/players", tags=["fantasy_teams"])
def add_player_to_fantasy_team(player_team: datatypes.PlayerTeam):
    """
    adds a player to the specified fantasy team.

    `player_id`: player id in which to add to the team
    `fantasy_team_id`: team id in which to add the player to

    returns player id and team id that the player was added to
    """

    with db.engine.begin() as conn:

        player_count = """
                select count(*)
                from player_fantasy_team
                where player_fantasy_team.fantasy_team_id = :ftid
        """

        player_count_result = conn.execute(sqlalchemy.text(player_count),{'ftid': player_team.fantasy_team_id}).scalar()

        if player_count_result == 11:
            raise HTTPException(422, "Team is full (11/11)")

        query = sqlalchemy.text("""
        SELECT *
        FROM player_fantasy_team
        WHERE player_id = :player_id AND fantasy_team_id = :fantasy_team_id
        """)

        result = conn.execute(query, {"player_id": player_team.player_id, "fantasy_team_id": player_team.fantasy_team_id}).fetchone()

        if result is not None:
            error_msg = "Player is already on this team."
            raise HTTPException(422, error_msg)

        bal_subq = """
                select fantasy_team_balance
                from fantasy_teams
                where fantasy_teams.fantasy_team_id = (:id)
                for share
                """
        val_subq = """
                select player_value
                from players
                where players.player_id = (:p_id)
                for share
                """

        try:
            balance = conn.execute(sqlalchemy.text(bal_subq),{'id':player_team.fantasy_team_id}).scalar_one()
            value = conn.execute(sqlalchemy.text(val_subq),{'p_id':player_team.player_id}).scalar_one()
        except NoResultFound as e:
            raise HTTPException(422, "Player or fantasy team not found.")

        sql = """
            INSERT INTO player_fantasy_team (player_id, fantasy_team_id)
            VALUES ((:player_id),(:fantasy_team_id))
            """

        subtract = """
            update fantasy_teams
            set fantasy_team_balance = (:new_bal)
            where fantasy_team_id = (:id)
            """

        params = {'player_id':player_team.player_id, 'fantasy_team_id':player_team.fantasy_team_id}

        try:
            if balance < value:
                raise HTTPException(422, "Team balance is too low.")
            conn.execute(sqlalchemy.text(sql),params)
            conn.execute(sqlalchemy.text(subtract),{'new_bal': balance-value,
                                                    'id': player_team.fantasy_team_id})
        except sqlalchemy.exc.IntegrityError as e:
            error_msg = e.orig.diag.message_detail
            raise HTTPException(422, error_msg)

    return {"Added player {} to team {}".format(player_team.player_id, player_team.fantasy_team_id)}

@router.delete("/fantasy_teams/{fantasy_team_id}/players", tags=["fantasy_teams"])
def remove_player_from_fantasy_team(player_team: datatypes.PlayerTeam):
    """
    removes a player from the specified fantasy team

    returns the player id that was removed and the team id the player was removed from
    """

    with db.engine.begin() as conn:

        query = sqlalchemy.text("""
        SELECT *
        FROM player_fantasy_team
        WHERE player_id = :player_id AND fantasy_team_id = :fantasy_team_id
        """)

        result = conn.execute(query, {"player_id": player_team.player_id, "fantasy_team_id": player_team.fantasy_team_id}).fetchone()

        if result is None:
            error_msg = "Player is not on this team."
            raise HTTPException(422, error_msg)

        bal_subq = """
                select fantasy_team_balance
                from fantasy_teams
                where fantasy_teams.fantasy_team_id = (:id)
                for share
                """
        val_subq = """
                select player_value
                from players
                where players.player_id = (:p_id)
                for share
                """

        try:
            balance = conn.execute(sqlalchemy.text(bal_subq),{'id':player_team.fantasy_team_id}).scalar_one()
            value = conn.execute(sqlalchemy.text(val_subq),{'p_id':player_team.player_id}).scalar_one()
        except NoResultFound as e:
            raise HTTPException(422, "Player or fantasy team not found.")

        reemburse = """
            update fantasy_teams
            set fantasy_team_balance = (:new_bal)
            where fantasy_team_id = (:id)
            """

        sql = """
            delete from player_fantasy_team
            where player_id = (:player_id) and fantasy_team_id = (:fantasy_team_id)
            """

        params = {
                'player_id': player_team.player_id,
                'fantasy_team_id': player_team.fantasy_team_id
                  }

        try:
            conn.execute(sqlalchemy.text(sql),params)
            conn.execute(sqlalchemy.text(reemburse),{'new_bal': balance+value,
                                                    'id': player_team.fantasy_team_id})
        except sqlalchemy.exc.IntegrityError as e:
            error_msg = e.orig.diag.message_detail
            raise HTTPException(422, error_msg)

    return {"Removed player {} from team {}".format(player_team.player_id, player_team.fantasy_team_id)}

@router.get("/fantasy_teams/{fantasy_team_id}/score", tags=["fantasy_teams"])
def get_fantasy_team_score(fantasy_team_id: int):
    """
    returns the score of the specified fantasy team,
    which is a sum of the team's player scores
    """

    with db.engine.connect() as conn:

        team_has_players = """
            select fantasy_team_id from player_fantasy_team
            where fantasy_team_id = (:id)
        """
        thp_result = conn.execute(sqlalchemy.text(team_has_players),{"id": fantasy_team_id}).fetchone()

        if thp_result is None:
            return {
                "team_id": fantasy_team_id,
                "Total_score": 0
        }

        sql = """
            SELECT player_fantasy_team.fantasy_team_id, SUM(player_score) AS total_team_score
            FROM (
            SELECT player_fantasy_team.player_id, SUM(num_goals*5 + num_assists*3 + num_passes*0.05 + num_shots_on_goal*0.2 - num_turnovers*0.2) AS player_score
            FROM player_fantasy_team
            JOIN games ON games.player_id = player_fantasy_team.player_id
            WHERE player_fantasy_team.fantasy_team_id = (:fantasy_team_id)
            GROUP BY player_fantasy_team.player_id
            ) AS subquery
            JOIN player_fantasy_team ON player_fantasy_team.player_id = subquery.player_id
            GROUP BY player_fantasy_team.fantasy_team_id
            """

        try:
            result = conn.execute(sqlalchemy.text(sql),{'fantasy_team_id':fantasy_team_id}).fetchone()
        except sqlalchemy.exc.IntegrityError as e:
            error_msg = e.orig.diag.message_detail
            raise HTTPException(422, error_msg)

        if result is None:
            raise HTTPException(422, "Fantasy team not found.")

    return {
        "team_id": fantasy_team_id,
        "Total_score": result[1]
    }

@router.put("/fantasy_teams/{fantasy_league_id}/join", tags=["fantasy_teams"])
def add_team_to_fantasy_league(team_id: int, league_id: int):
    """
    This endpoint adds a fantasy team to a fantasy league
    It updates the league_id column of a team

    returns the team id and the league id
    """

    with db.engine.begin() as conn:
        league_budget_subq = """
                select fantasy_league_budget
                from fantasy_leagues
                where fantasy_leagues.fantasy_league_id = (:league_id)
                for share
                """
        team_value_subq = """
                select fantasy_team_balance
                from fantasy_teams
                where fantasy_teams.fantasy_team_id = (:team_id)
                for share
                """

        try:
            league_budget = conn.execute(sqlalchemy.text(league_budget_subq),{'league_id':league_id}).scalar_one()
        except NoResultFound as e:
            raise HTTPException(422, "Fantasy league not found.")

        try:
            team_value = conn.execute(sqlalchemy.text(team_value_subq),{'team_id':team_id}).scalar_one()
        except NoResultFound as e:
            raise HTTPException(422, "Fantasy team not found.")

        sql = """
            update fantasy_teams
            set fantasy_league_id = (:league_id)
            where fantasy_team_id = (:team_id)
            """

        params = {'league_id': league_id, 'team_id': team_id}

        try:
            if(team_value > league_budget):
                raise HTTPException(422, "Team value is too high for this league.")
            conn.execute(sqlalchemy.text(sql),params)
        except sqlalchemy.exc.IntegrityError as e:
            error_msg = e.orig.diag.message_detail
            raise HTTPException(422, error_msg)

    return ("Team {} addded to fantasy league {}".format(team_id, league_id))


import sys
from pathlib import Path

import flask
from flask import Flask, Response, jsonify
from flask_cors import CORS

sys.path.append(str(Path(__file__).resolve().parents[1])) # allows running the api from anywhere

app = Flask(__name__) # flask app creation
CORS(app) # cors patch to allow working with localhost

phonebook = {}

@app.route("/phonebook", methods=["GET"]) # api endpoint, and allowed methods on it
def api_get_phonebook():
    payload = {
        'phonebook': phonebook
    }

    return jsonify(payload), 200 # returned payload and status code

@app.route("/phonebook", methods=["POST"]) # api endpoint, and allowed methods on it
def api_add_to_phonebook():
    name = flask.request.form.get('name')
    phone_number = flask.request.form.get('phone_number')

    if name is None or phone_number is None: # make sure they are defined, otherwise return a 400 error
        return jsonify({'error':'please provide a `name` and a `phone_number` field'}), 400

    print(f"adding {name} and {phone_number} to phonebook")
    phonebook[name] = phone_number

    return jsonify({}), 200 # returned payload and status code

def main():
    phonebook["John"] = "657-532-1112"

if __name__ == "__main__":
    main() # initialize the app (logging, folders etc.)
    app.run(host="0.0.0.0", port=5999) # run the api on localhost on port 5999


# Licensed to the .NET Foundation under one or more agreements.
# The .NET Foundation licenses this file to you under the Apache 2.0 License.
# See the LICENSE file in the project root for more information.

"""
This module contains a single class, IronPythonInstance, which
encapsulates a separately-spawned, interactive Iron Python process.
Its purpose is to enable testing behaviour of the top-level console,
when that differs from behaviour while importing a module and executing
its statements.
"""
from .test_env import is_netcoreapp, is_posix
if is_netcoreapp:
    import clr
    clr.AddReference("System.Diagnostics.Process")
    clr.AddReference("System.Threading.Thread")
from System.Diagnostics import Process, ProcessStartInfo
from System.IO import StreamReader, StreamWriter
from System.Threading import Thread

class IronPythonInstance:
    """
    Class to hold a single instance of the Iron Python interactive
console for testing purposes, and direct input to and from the instance.

    Example usage:
    from sys import exec_prefix
    ip = IronPythonInstance(sys.executable, exec_prefix)
    AreEqual(ip.Start(), True)
    if ip.ExecuteLine("1+1") != "2":
        raise "Bad console!"
    else:
        print "Console passes sanity check."
    ip.End()

    """
    def __init__(self, pathToBin, wkDir, *parms):
        self.proc = Process()
        self.proc.StartInfo.FileName = pathToBin
        self.proc.StartInfo.WorkingDirectory = wkDir
        self.proc.StartInfo.Arguments = " ".join(parms)
        self.proc.StartInfo.UseShellExecute = False
        self.proc.StartInfo.RedirectStandardOutput = True
        self.proc.StartInfo.RedirectStandardInput = True
        self.proc.StartInfo.RedirectStandardError = True

    def Start(self):
        if (not self.proc.Start()):
            return False
        else:
            self.reader = self.proc.StandardOutput
            self.reader2 = self.proc.StandardError
            self.writer = self.proc.StandardInput
            self.InitializeErrorWatcher()
            self.EatToPrompt()
            return True

    def StartAndRunToCompletion(self):
        if (not self.proc.Start()):
            return (False, None, None)
        else:
            self.reader = self.proc.StandardOutput
            self.reader2 = self.proc.StandardError
            self.writer = self.proc.StandardInput
            # This will hang if the output exceeds the buffer size
            output = self.reader.ReadToEnd()
            output2 = self.reader2.ReadToEnd()
            return (True, output, output2, self.proc.ExitCode)

    def EnsureInteractive(self):
        twoPlusTwoResult = self.ExecuteLine("2 + 2", True)
        if "4" != twoPlusTwoResult:
            raise AssertionError('EnsureInteractive failed. 2+2 returned ' + twoPlusTwoResult)

    # Note that the prompt text could occur in the middle of other output.
    # However, it is important to read all the output from the child process
    # to avoid deadlocks. Hence, we assume that ">>> " will only occur
    # as the prompt.
    def EatToPrompt(self, readError=False):
        result = self.EatToMarker(">>> ", readError)
        return result[0 : -len(">>> ")]

    def EatToMarker(self, marker, readError=False):
        slurped = ""
        while not marker in slurped:
            nextChar = self.reader.Read()
            if nextChar == -1: raise ValueError("unexpected end of input after reading '%s'" % slurped)
            slurped += chr(nextChar)
            if slurped == '...': raise ValueError("found ... instead of %s, after reading %s" % (marker, slurped))

        assert(slurped.endswith(marker))

        if readError:
            # This should be returned as separate return values, instead of being appended together
            return self.ReadError() + slurped
        else:
            return slurped

    # Execute a single-line command, and return the output
    def ExecuteLine(self, line, readError=False):
        self.writer.Write(line+"\n")
        return self.EatToPrompt(readError).rstrip()

    def ExecuteAndExit(self, line):
        self.writer.Write(line+"\n")
        i = 0
        while i < 40 and not self.proc.HasExited:
            Thread.CurrentThread.Join(100)
            i += 1
        return self.proc.ExitCode

    # Submit one line of a multi-line command to the console. There can be
    # multiple calls to ExecutePartialLine before a final call to ExecuteLine
    def ExecutePartialLine(self, line):
        self.writer.Write(line+"\n")
        ch = self.reader.Read()
        if ch == -1 or chr(ch) != '.' : raise AssertionError('missing the first dot')
        ch = self.reader.Read()
        if ch == -1 or chr(ch) != '.' : raise AssertionError('missing the second dot')
        ch = self.reader.Read()
        if ch == -1 or chr(ch) != '.' : raise AssertionError('missing the third dot')
        ch = self.reader.Read()
        if ch == -1 or chr(ch) != ' ' : raise AssertionError('missing the last space char')

    def End(self):
        if 'writer' in dir(self) and 'Close' in dir(self.writer):
            self.writer.Close()

        try:
            if not self.proc.HasExited:
                self.proc.Kill()
        except:
            print('Leaked ipy process could not kill!')

    # Functions for the remote console

    def EnsureInteractiveRemote(self, readError=True):
        """Sometimes remote output can become available after the prompt is printed locally."""

        twoPlusTwoResult = self.ExecuteLine("2 + 2", readError)
        if "4" == twoPlusTwoResult:
            return
        if "" != twoPlusTwoResult:
            raise AssertionError('EnsureInteractive failed. 2+2 returned ' + twoPlusTwoResult)
        twoPlusTwoResult = self.EatToMarker("4\r\n")
        if "4\r\n" != twoPlusTwoResult:
            raise AssertionError('EnsureInteractive failed. 2+2 returned ' + twoPlusTwoResult)

    def ExecuteLineRemote(self, line, expectedOutputLines=1):
        """Sometimes remote output can become available after the prompt is printed locally."""

        result = self.ExecuteLine(line)
        if "" != result:
            return result
        for i in range(expectedOutputLines):
            output = self.EatToMarker("\r\n")
            if output == "":
                raise AssertionError('ExecuteLineRemote failed. Returned empty after %s. Error is %s' % (result, self.ReadError()))
            result += output
        return result[0:-2]

    # Functions to read stderr

    def InitializeErrorWatcher(self):
        from System.Threading import Thread, ThreadStart
        import _thread
        self.errorLock = _thread.allocate_lock()
        self.errorString = ""
        th = Thread(ThreadStart(self.WatchErrorStream))
        th.IsBackground = True
        th.Start()

    def WatchErrorStream(self):
        while True:
            nextChar = self.reader2.Read()
            if (nextChar == -1): break
            self.errorLock.acquire()
            self.errorString += chr(nextChar)
            self.errorLock.release()

    def GetUnreadError(self):
        self.errorLock.acquire()
        result = self.errorString
        self.errorString = ""
        self.errorLock.release()
        return result

    def ReadError(self):
        # For reading the error stream, there is no marker to know when to stop reading.
        # Instead, we keep reading from the error stream until there is no text written
        # to it for 1 second.

        from time import sleep

        result = self.GetUnreadError()
        prev = result
        while True:
            sleep(1)
            result += self.GetUnreadError()
            if (result == prev): break
            prev = result

        return result


from itertools import product

def solveDay(my_file):
    data = parse_data(my_file)
    print('Part 1: ', part1(data))
    print('Part 2: ', part2(data[1], tuple(data[0]['42']),
                            tuple(data[0]['31'])))

def parse_data(my_file):
    with open(my_file) as f:
        data = f.read().split('\n\n')
        draft_rules = dict(
            rule.split(': ') for rule in data[0].replace('"', '').split('\n'))
        draft_rules = {
            k: [rule.split() for rule in v.split(' | ')]
            for k, v in draft_rules.items()
        }
        rules = {
            k: v[0]
            for k, v in draft_rules.items() if not v[0][0].isdigit()
        }
        messages = data[1].split()
        find_rule(draft_rules, rules, '0')
        return rules, messages

def find_rule(draft, rules, rule):
    if rule in rules:
        return rules[rule]
    else:
        rules[rule] = sum([[
            ''.join(res)
            for res in (product(*[find_rule(draft, rules, c) for c in comb]))
        ] for comb in draft[rule]], [])
        return rules[rule]

def part1(data):
    return sum(mes in data[0]['0'] for mes in data[1])

def part2(messages, *rules):
    count = 0
    for message in messages:
        result = []
        for rule in rules:
            total = 0
            rule_len = len((rule[0]))
            while True:
                if message.startswith(rule):
                    message = message[rule_len:]
                    total += 1
                else:
                    break
            result.append(total)
        if not message and result[0] > result[1] > 0:
            count += 1
    return count


from typing import Optional

from sqlalchemy import Column, BigInteger, ForeignKey, String, Float, Enum
from pydantic import BaseModel, constr
from aplicativo.database import Base
from aplicativo.enumerators.cidade.Cidade import Cidade
from aplicativo.models.utils.ClasseBase import ClasseBase

class Perfil(Base, ClasseBase):
    __tablename__ = "perfil"
    id = Column(BigInteger, primary_key=True, nullable=False)
    usuario_id = Column(ForeignKey("usuario.id"), nullable=False)
    nome = Column(String(255))
    endereco = Column(String(255))
    cidade_id = Column(Enum(Cidade), nullable=False)
    geolocalizacao = Column(Float, nullable=False)
    email = Column(String(255))
    cnpj_cpf = Column(String(255))
    _fields = [
        "usuario_id",
        "nome",
        "endereco",
        "cidade_id",
        "geolocalizacao",
        "email",
        "cnpj_cpf",
    ]

    @staticmethod
    def from_dict(dicionario):
        dicionario["cidade_id"] = Cidade(dicionario["cidade_id"]).name
        return ClasseBase.from_dict(dicionario, Perfil)

    def to_dict(self):
        dicionario = {key: getattr(self, key) for key in self._fields}
        return dicionario

    def to_json(self):
        dicionario = {key: getattr(self, key) for key in self._fields}
        dicionario["cidade_id"] = dicionario["cidade_id"].value
        dicionario["id"] = self.id
        return dicionario

    @staticmethod
    def to_update(dicionario):
        return ClasseBase.to_update(dicionario, Perfil)

    @staticmethod
    def to_update(dicionario):
        fields_to_edit = {
            nome_campo: dicionario[nome_campo]
            for nome_campo in Perfil._fields
            if nome_campo in dicionario
        }
        if fields_to_edit.get("cidade_id"):
            fields_to_edit["cidade_id"] = Cidade(dicionario["cidade_id"]).name
        return fields_to_edit

class PerfilModel(BaseModel):
    id: Optional[int]
    usuario_id: int
    nome: constr(max_length=255)
    endereco: constr(max_length=255)
    cidade_id: int
    geolocalizacao: float
    email: constr(max_length=255)
    cnpj_cpf: constr(max_length=255)


# -*- coding: utf-8 -*-
import torch
import torch.autograd as autograd
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable

class TextCNN(nn.Module):

    def __init__(self, config):
        super(TextCNN, self).__init__()
        self.kernel_num = config.kernel_num  # Number of conv kernels
        self.embedding_length = config.wordvec_dim
        self.Ks = config.kernel_sizes
        self.word_embeddings = nn.Embedding(config.weight.shape[0], self.embedding_length)  # Embedding layer
        self.word_embeddings = self.word_embeddings.from_pretrained(config.weight, freeze=False)  # Load pretrianed word embedding, and fine-tuing

        self.convs = nn.ModuleList([nn.Conv2d(1, config.kernel_num, (K, config.wordvec_dim), bias=True) for K in self.Ks])
        self.relu = nn.ReLU(inplace=True)
        self.dropout = nn.Dropout(0.5)
        self.fc = nn.Linear(len(self.Ks)*self.kernel_num, config.label_num)
        self.bn1 = nn.BatchNorm1d(len(self.Ks)*self.kernel_num)
        # self.fc1 = nn.Linear(len(self.Ks)*self.kernel_num, fc1out)
        # self.bn2 = nn.BatchNorm1d(fc1out)
        # self.fc2 = nn.Linear(fc1out, config.label_num)
        self.softmax = nn.Softmax(dim=1)

    def forward(self, x):
        # (batch_size, batch_dim)
        # Embedding
        x = self.word_embeddings(x)  # (batch_size, batch_dim, embedding_len)

        x = x.unsqueeze(1)  # (batch_size, 1, batch_dim, embedding_len)
        # print(x.size())

        # Conv and relu
        x = [self.relu(conv(x)).squeeze(3) for conv in self.convs]  # [(batch_size, kernel_num, batch_dim-K+1), ...]*len(Ks)
        # print([i.shape for i in x])

        # max-over-time pooling (actually merely max)
        x = [F.max_pool1d(xi, xi.size()[2]).squeeze(2) for xi in x] # [(batch_size, kernel_num), ...]*len(Ks)
        # print([i.shape for i in x])
        x = torch.cat(x, dim=1)  # (batch_size, kernel_num*len(Ks))

        x = self.bn1(x)  # Batch Normaliztion
        x = self.dropout(x)  # (batch_size, len(Ks)*kernel_num), dropout
        # print(x.size())

        x = self.fc(x)  # (batch_size, label_num)
        # print(x.size())

        # x = self.fc1(x)
        # x = self.bn2(x)
        # x = self.fc2(x)
        logit = self.softmax(x)
        return logit

if __name__ == '__main__':
    pass


def parse_args():
    from argparse import ArgumentParser

    parser = ArgumentParser()
    parser.add_argument('base_path')
    parser.add_argument('-d', '--output-path', required=False, default='.')
    return parser.parse_args()

def main() -> None:
    from pathlib import Path
    from mutagen import File
    import pickle

    args = parse_args()
    base_path = Path(args.base_path).resolve()
    output_base_path = Path(args.output_path).resolve()
    for p in base_path.rglob('*'):
        out_path = output_base_path / p.relative_to(base_path)
        if p.is_dir():
            print('process: path={}'.format(
                p.resolve()
            ))
            out_path.mkdir(parents=True, exist_ok=True)
        else:
            with p.open('rb') as f:
                guess = File(f, easy=True)
            if not guess:
                print('failed guess: path={}'.format(
                    p.resolve()
                ))
                continue
            filename = f'{p.name}.pickle'
            dumpfile = out_path.parent / filename
            with dumpfile.open('wb') as f:
                pickle.dump(guess, f)

if __name__ == '__main__':
    main()


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

"""
给你一个大小为 m x n 的二进制矩阵 grid ，其中 0 表示一个海洋单元格、1 表示一个陆地单元格。
一次 移动 是指从一个陆地单元格走到另一个相邻（上、下、左、右）的陆地单元格或跨过 grid 的边界。
返回网格中无法在任意次数的移动中离开网格边界的陆地单元格的数量。

输入：grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
输出：3
解释：有三个 1 被 0 包围。一个 1 没有被包围，因为它在边界上。
"""
from typing import List

class Solution:
    def numEnclaves(self, grid: List[List[int]]) -> int:
        # 先要将靠边的0变成1
        for i in range(0, len(grid)):
            dfs(grid, i, 0)
            dfs(grid, i, len(grid[0])-1)
        for j in range(0, len(grid[0])):
            dfs(grid, 0, j)
            dfs(grid, len(grid)-1, j)
        total_num = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == 1:
                    total_num += 1  # 是网格数量，不是岛屿数量，所以不用淹没
                    # dfs(grid, i, j)
        return total_num

def dfs(grid, i, j):
    if i < 0 or j < 0 or i >= len(grid) or j >= len(grid[0]):
        return
    if grid[i][j] == 0:
        return

    grid[i][j] = 0
    dfs(grid, i + 1, j)
    dfs(grid, i - 1, j)
    dfs(grid, i, j - 1)
    dfs(grid, i, j + 1)

if __name__ == '__main__':
    grid = [[0, 0, 0, 0], [1, 0, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]
    result = Solution().numEnclaves(grid)
    print(result)


"""
875. Koko Eating Bananas
Medium

Koko loves to eat bananas. There are n piles of bananas, the ith pile has piles[i] bananas. The guards have gone and will come back in h hours.

Koko can decide her bananas-per-hour eating speed of k. Each hour, she chooses some pile of bananas and eats k bananas from that pile. If the pile has less than k bananas, she eats all of them instead and will not eat any more bananas during this hour.

Koko likes to eat slowly but still wants to finish eating all the bananas before the guards return.

Return the minimum integer k such that she can eat all the bananas within h hours.

Example 1:

Input: piles = [3,6,7,11], h = 8
Output: 4
Example 2:

Input: piles = [30,11,23,4,20], h = 5
Output: 30
Example 3:

Input: piles = [30,11,23,4,20], h = 6
Output: 23

Constraints:

1 <= piles.length <= 104
piles.length <= h <= 109
1 <= piles[i] <= 109

"""
from typing import List

"""
Binary Search

min of k is 1, largest of k is max(piles) since if he finishes at least one pile per hour, piles.length <=h, he will always be able to finish within h hour

Why binary search?
if he cannot finish at speed k, then he cannot finish with any speed x<k
if he can finish at speed k, then he can finish with any speed x > k
i.e., there's some k such that if he can finish if and only if his speed x >= k
so we can do binary search to find this value k

time O(Nlog(N))

mistakes:
1 calculating hours needed for pile of size p>0 at speed k, it is math.ceil(p/k)=((p-1)//k+1)
"""

class Solution:
    def minEatingSpeed(self, piles: List[int], h: int) -> int:

        left, right = 1, max(piles)
        while left < right:
            mid = left + (right - left) // 2
            # print('left=%s right=%s mid=%s' % (left, right, mid))
            # can he finish with speed k per hour
            # for each pile of size p>0, the hours he need would be math.ceil(p/k) = ((p-1)//k)+1 hours
            if sum([((p - 1) // mid + 1) for p in piles]) <= h:
                right = mid
            else:
                left = mid + 1

        return left

def main():
    sol = Solution()
    assert sol.minEatingSpeed(piles = [3,6,7,11], h = 8) == 4, 'fails'

    assert sol.minEatingSpeed(piles = [30,11,23,4,20], h = 5) == 30, 'fails'

    assert sol.minEatingSpeed(piles = [30,11,23,4,20], h = 6) == 23, 'fails'

    assert sol.minEatingSpeed([312884470], 312884469) == 2, 'fails'

if __name__ == '__main__':
   main()


import sqlite3

def add_task(name: str, task_type: str):
  # open the connection to the database file
  connection = sqlite3.connect('task_db')
  cursor = connection.cursor()
  # on the cursor object we execute our command(s)
  cursor.execute("INSERT INTO tasks (name, type) VALUES ('"
                 + name + "', '" + task_type + "')")
  # commit == save to file
  connection.commit()
  connection.close()

def get_tasks():
  connection = sqlite3.connect('task_db')
  cursor = connection.cursor()

  cursor.execute("SELECT * FROM tasks")
  tasks = cursor.fetchall()
  connection.close()
  dict = [{'name': x[0], 'type': x[1]} for x in tasks]
  return dict

def delete_task(name: str):
  connection = sqlite3.connect('task_db')
  cursor = connection.cursor()

  cursor.execute("DELETE FROM tasks WHERE name='" + name + "'")
  connection.commit()
  connection.close()

if __name__ == "__main__":
  # add_task('buy fruits', 'cooking')
  delete_task('clean the house')
  print(get_tasks())


import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np

device = torch.device("cuda" if torch.cuda.is_available() else 'cpu')

class creat_model(nn.Module):
    def __init__(self, batch_size, vocab_size, embedding_matrix,
                 nb_filters, embed_size=300, dropout_rate=0.5, num_classes=2,
                 kernel_dim=100, kernel_sizes=(2, 3, 4)):
        super(creat_model, self).__init__()
        self.batch_size = batch_size
        self.dropout_rate = dropout_rate
        self.embedding_matrix = embedding_matrix
        self.vocab_size = vocab_size
        self.embed_size = embed_size
        self.nb_filters = nb_filters
        self.kernel_dim = kernel_dim
        self.kernel_sizes = kernel_sizes
        self.num_class = num_classes
        # 词嵌入层
        self.embedding_layer = self.add_embed_layer(self.embedding_matrix, self.vocab_size['word'], self.embed_size)
        # CNN编码层
        self.convs = nn.ModuleList([nn.Conv2d(1, kernel_dim, (k, self.embed_size)) for k in kernel_sizes])
        # 输出分类层
        self.dropout_layer = nn.Dropout(self.dropout_rate)
        self.fc = nn.Linear(len(kernel_sizes) * kernel_dim * 2, num_classes)
        nn.init.xavier_uniform_(self.fc.weight.data, gain=1)
        nn.init.constant_(self.fc.bias.data, 0.1)

    def add_embed_layer(self, vocab_emb, vocab_size, embed_size):
        if vocab_emb is not None:
            # 预训练词向量
            embed_layer = nn.Embedding(vocab_size, embed_size)
            pretrained_weight = np.array(vocab_emb)
            embed_layer.weight.data.copy_(torch.from_numpy(pretrained_weight))
            for p in embed_layer.parameters():
                p.requires_grad = False
        else:
            # 随机初始化
            print("Embedding with random weights")
            embed_layer = nn.Embedding(num_embeddings=vocab_size, embedding_dim=embed_size)
        return embed_layer

    def forward(self, query_word_input, doc_word_input):
        # 这里对视频中的代码做了修改，使用了多个并行的卷积
        # 经过词嵌入层，获得词向量
        query_word_emb = self.embedding_layer(query_word_input).unsqueeze(1)
        doc_word_emb = self.embedding_layer(doc_word_input).unsqueeze(1)
        # print(query_word_emb.size())
        # [batch_size, 1, seq_len, embedding_dim]
        # 经过卷积层，和最大池化层
        query_word_emb = [F.relu(conv(query_word_emb)).squeeze(3) for conv in self.convs]
        query_word_emb = [F.max_pool1d(i, i.size(2)).squeeze(2) for i in query_word_emb]
        doc_word_emb = [F.relu(conv(doc_word_emb)).squeeze(3) for conv in self.convs]
        doc_word_emb = [F.max_pool1d(i, i.size(2)).squeeze(2) for i in doc_word_emb]
        # 拼接不同卷积层的特征
        query_concated = torch.cat(query_word_emb, 1)
        query_concated = self.dropout_layer(query_concated)
        doc_concated = torch.cat(doc_word_emb, 1)
        doc_concated = self.dropout_layer(doc_concated)
        # 拼接query和doc
        concated = torch.cat([query_concated, doc_concated], dim=-1)
        prediction = self.fc(concated)
        return prediction


from __future__ import annotations

import atexit
import logging

import colorama

from .config import CfgOption

__all__ = ["log"]

# Config options
verbosity = CfgOption("verbosity", value="INFO",
                      typ=lambda val: logging._nameToLevel[val])
filename = CfgOption("filename", value="aware.log", typ=str)
filemode = CfgOption("filemode", value="w+", typ=str)

# Set logger
log = logging.getLogger("aware")
log.setLevel(verbosity.get_value())

def colored_message(msg: str, color: str) -> str:
    """
    Return colorized version of the message.

    Parameters
    ----------
    msg : str
        message to colorize
    color : str
        text color

    Returns
    -------
    str
        message with colorized text
    """
    return color + msg + colorama.Style.RESET_ALL

class ColorFormatter(logging.Formatter):
    """
    Colorful messages in console/terminal emulator via logging facility.
    """

    def format(self, record: logging.LogRecord) -> str:
        """
        Paint record message according to the logging level.
        """

        msg = super(ColorFormatter, self).format(record)

        lvl = record.levelno
        if lvl < logging.INFO:
            formatted_msg = colored_message(msg, colorama.Fore.BLUE)
        elif lvl < logging.WARN:
            formatted_msg = colored_message(msg, colorama.Fore.GREEN)
        elif lvl < logging.ERROR:
            formatted_msg = colored_message(msg, colorama.Fore.YELLOW)
        elif lvl < logging.CRITICAL:
            formatted_msg = colored_message(msg, colorama.Fore.LIGHTRED_EX)
        else:
            formatted_msg = colored_message(msg, colorama.Fore.RED)

        return formatted_msg

msg_format = "%(asctime)s.%(msecs)03d %(levelname)8s "
msg_format += "%(module)s.%(funcName)s(): %(message)s"

console = logging.StreamHandler()
console.setFormatter(ColorFormatter())

def _remove_handlers() -> None:
    if log.hasHandlers():
        log.handlers = []

# Remove handlers to prevent double message emmiting
_remove_handlers()

log.addHandler(console)

logfile = logging.FileHandler(filename.get_value(), mode=filemode.get_value())
logfile.setLevel(verbosity.get_value())
logfile.setFormatter(logging.Formatter(msg_format, "%Y-%m-%d %H:%M:%S"))
log.addHandler(logfile)

colorama.init()
atexit.register(colorama.deinit)
atexit.register(_remove_handlers)


import os
import numpy as np
import json
from utils import NumpyEncoder
import time

class Runner:
    def __init__(self, agent, frequency, env, save_frequency=3000, logging=100, total_episode=1e10, curriculum=None,
                 frequency_mode='episodes', random_actions=None,
                 # IRL
                 reward_model=None, fixed_reward_model=False, dems_name='', reward_frequency=30,
                 **kwargs):

        # Runner objects and parameters
        self.agent = agent
        self.curriculum = curriculum
        self.total_episode = total_episode
        self.frequency = frequency
        self.frequency_mode = frequency_mode
        self.random_actions = random_actions
        self.logging = logging
        self.save_frequency = save_frequency
        self.env = env

        # Recurrent
        self.recurrent = self.agent.recurrent

        # Objects and parameters for IRL
        self.reward_model = reward_model
        self.fixed_reward_model = fixed_reward_model
        self.dems_name = dems_name
        self.reward_frequency = reward_frequency

        # Initialize reward model
        if self.reward_model is not None:
            if not self.fixed_reward_model:
                # Ask for demonstrations
                answer = None
                while answer != 'y' and answer != 'n':
                    answer = input('Do you want to create new demonstrations? [y/n] ')
                if answer == 'y':
                    dems, vals = self.reward_model.create_demonstrations(env=self.env)
                elif answer == 'p':
                    dems, vals = self.reward_model.create_demonstrations(env=self.env, with_policy=True)
                else:
                    print('Loading demonstrations...')
                    dems, vals = self.reward_model.load_demonstrations(self.dems_name)

                print('Demonstrations loaded! We have ' + str(len(dems['obs'])) + " timesteps in these demonstrations")
                print('and ' + str(len(vals['obs'])) + " timesteps in these validations.")

                # Getting initial experience from the environment to do the first training epoch of the reward model
                self.get_experience(env, self.reward_frequency, random=True)
                self.reward_model.train()

        # Global runner statistics
        # total episode
        self.ep = 0
        # total steps
        self.total_step = 0
        # Initialize history
        # History to save model statistics
        self.history = {
            "episode_rewards": [],
            "episode_timesteps": [],
            "mean_entropies": [],
            "std_entropies": [],
            "reward_model_loss": [],
            "env_rewards": []
        }

        # For curriculum training
        self.start_training = 0
        self.current_curriculum_step = 0

        # If a saved model with the model_name already exists, load it (and the history attached to it)
        if os.path.exists('{}/{}.meta'.format('saved', agent.model_name)):
            answer = None
            while answer != 'y' and answer != 'n':
                answer = input("There's already an agent saved with name {}, "
                               "do you want to continue training? [y/n] ".format(agent.model_name))

            if answer == 'y':
                self.history = self.load_model(agent.model_name, agent)
                self.ep = len(self.history['episode_timesteps'])
                self.total_step = np.sum(self.history['episode_timesteps'])

    def run(self):

        # Trainin loop
        # Start training
        start_time = time.time()
        while self.ep <= self.total_episode:
            # Reset the episode
            self.ep += 1
            step = 0

            # Set actual curriculum
            config = self.set_curriculum(self.curriculum, np.sum(self.history['episode_timesteps']))
            if self.start_training == 0:
                print(config)
            self.start_training = 1
            self.env.set_config(config)

            state = self.env.reset()
            done = False
            # Total reward of the episode
            episode_reward = 0
            # Total reward of the environment, in case of IRL it can be different from the actual reward of the agent
            env_episode_reward = 0

            # Save local entropies
            local_entropies = []

            # If recurrent, initialize hidden state
            if self.recurrent:
                internal = (np.zeros([1, self.agent.recurrent_size]), np.zeros([1, self.agent.recurrent_size]))

            # Episode loop
            while True:

                # Evaluation - Execute step
                if not self.recurrent:
                    action, logprob, probs = self.agent.eval([state])
                else:
                    action, logprob, probs, internal_n = self.agent.eval_recurrent([state], internal)

                # Do a first run of random actions if specified
                if self.random_actions is not None and self.total_step < self.random_actions:
                    action = [np.random.randint(self.agent.action_size)]

                action = action[0]
                # Save probabilities for entropy
                local_entropies.append(self.env.entropy(probs[0]))

                # Execute in the environment
                state_n, done, reward, _ = self.env.execute(action)

                # If exists a reward model, use it instead of the env reward
                if self.reward_model is not None:
                    env_episode_reward += reward
                    # If we use a trained reward model, use a simple eval without updating it
                    if self.fixed_reward_model:
                        reward = self.reward_model.eval([state], [state_n], [action])  # , probs=[probs[actions]])
                    # If not, eval with discriminator and update its buffer for training it
                    else:
                        reward = self.reward_model.eval_discriminator([state], [state_n], [probs[0][action]], [action])
                        self.reward_model.add_to_buffer(state, state_n, action)

                # If step is equal than max timesteps, terminate the episode
                if step >= self.env._max_episode_timesteps - 1:
                    done = True

                # Get the cumulative reward
                episode_reward += reward

                # Update PPO memory
                if not self.recurrent:
                    self.agent.add_to_buffer(state, state_n, action, reward, logprob, done)
                else:
                    # If we use a recurrent network, we need to store aso the internal state of the recurrent layer
                    try:
                        self.agent.add_to_buffer(state, state_n, action, reward, logprob, done,
                                                 internal.c[0], internal.h[0])
                    except Exception as e:
                        zero_state = np.reshape(internal[0], [-1,])
                        self.agent.add_to_buffer(state, state_n, action, reward, logprob, done,
                                                 zero_state, zero_state)
                    internal = internal_n
                state = state_n

                step += 1
                self.total_step += 1

                # If frequency timesteps are passed, update the policy
                if self.frequency_mode == 'timesteps' and \
                        self.total_step > 0 and self.total_step % self.frequency == 0:
                    if self.random_actions is not None:
                        if self.total_step > self.random_actions:
                            self.agent.train()
                    else:
                        self.agent.train()

                # If done, end the episode and save statistics
                if done:
                    self.history['episode_rewards'].append(episode_reward)
                    self.history['episode_timesteps'].append(step)
                    self.history['mean_entropies'].append(np.mean(local_entropies))
                    self.history['std_entropies'].append(np.std(local_entropies))
                    self.history['env_rewards'].append(env_episode_reward)
                    break

            # Logging information
            if self.ep > 0 and self.ep % self.logging == 0:
                print('Mean of {} episode reward after {} episodes: {}'.
                      format(self.logging, self.ep, np.mean(self.history['episode_rewards'][-self.logging:])))

                if self.reward_model is not None:
                    print('Mean of {} environment episode reward after {} episodes: {}'.
                            format(self.logging, self.ep, np.mean(self.history['env_rewards'][-self.logging:])))

                print('The agent made a total of {} steps'.format(self.total_step))

                self.timer(start_time, time.time())

            # If frequency episodes are passed, update the policy
            if self.frequency_mode == 'episodes' and self.ep > 0 and self.ep % self.frequency == 0:
                self.agent.train()

            # If IRL, update the reward model after reward_frequency episode
            if self.reward_model is not None:
                if not self.fixed_reward_model and self.ep > 0 and self.ep % self.reward_frequency == 0:
                    self.reward_model.train()

            # Save model and statistics
            if self.ep > 0 and self.ep % self.save_frequency == 0:
                self.save_model(self.history, self.agent.model_name, self.curriculum, self.agent)
                if self.reward_model is not None:
                    if not self.fixed_reward_model:
                        self.reward_model.save_model('{}_{}'.format(self.agent.model_name, self.ep))

    def save_model(self, history, model_name, curriculum, agent):

        # Save statistics as json
        json_str = json.dumps(history, cls=NumpyEncoder)
        f = open("arrays/{}.json".format(model_name), "w")
        f.write(json_str)
        f.close()

        # Save curriculum as json
        json_str = json.dumps(curriculum, cls=NumpyEncoder)
        f = open("arrays/{}_curriculum.json".format(model_name), "w")
        f.write(json_str)
        f.close()

        # Save the tf model
        agent.save_model(name=model_name, folder='saved')
        print('Model saved with name: {}'.format(model_name))

    def load_model(self, model_name, agent):
        agent.load_model(name=model_name, folder='saved')
        with open("arrays/{}.json".format(model_name)) as f:
            history = json.load(f)

        return history

    # Update curriculum for DeepCrawl
    def set_curriculum(self, curriculum, total_timesteps, mode='steps'):

        if curriculum == None:
            return None

        if mode == 'steps':
            lessons = np.cumsum(curriculum['thresholds'])

            curriculum_step = 0

            for (index, l) in enumerate(lessons):

                if total_timesteps > l:
                    curriculum_step = index + 1

        parameters = curriculum['parameters']
        config = {}

        for (par, value) in parameters.items():
            config[par] = value[curriculum_step]

        self.current_curriculum_step = curriculum_step

        return config

    # For IRL, get initial experience from environment, the agent act in the env without update itself
    def get_experience(self, env, num_discriminator_exp=None, verbose=False, random=False):

        if num_discriminator_exp == None:
            num_discriminator_exp = self.frequency

        # For policy update number
        for ep in range(num_discriminator_exp):
            states = []
            state = env.reset()
            step = 0
            # While the episode si not finished
            reward = 0
            while True:
                step += 1
                action, _, c_probs = self.agent.eval([state])
                if random:
                    num_actions = env.actions()['num_values']
                    action = np.random.randint(0, num_actions)
                state_n, terminal, step_reward, _ = env.execute(actions=action)
                self.reward_model.add_to_buffer(state, state_n, action)

                state = state_n
                reward += step_reward
                if terminal or step >= env._max_episode_timesteps:
                    break

            if verbose:
                print("Reward at the end of episode " + str(ep + 1) + ": " + str(reward))

    # Method for count time after each episode
    def timer(self, start, end):
        hours, rem = divmod(end - start, 3600)
        minutes, seconds = divmod(rem, 60)
        print("Time passed: {:0>2}:{:0>2}:{:05.2f}".format(int(hours), int(minutes), seconds))


import datetime
import re
import rfc822
from urllib2 import URLError

from django.conf import settings
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.views.decorators.csrf import csrf_exempt

from mitnkcom.common.utils import get_soup_by_url
from mitnkcom.twitcn.tools import getPrivateApi
from mitnkcom.webapps.notes.models import Note, Word

ASCII_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

def index(request):
    book = request.GET.get('book')
    if book:
        notes = Note.objects.filter(book=book)
    else:
        notes = Note.objects.all()
    return render_to_response("webapps/notes.html",
        {'notes': notes},
        context_instance=RequestContext(request))

@csrf_exempt
def check_notes(request):
    if request.method != "POST" or request.POST.get("action") != "notes":
        return HttpResponse(":)")

    try:
        info = fetch_latest_urls()
    except URLError:
        return HttpResponse("URLError occurred!")

    count = 0
    for url, added in info:
        notes = Note.objects.filter(url=url)
        words = Word.objects.filter(url=url)
        if notes.count() > 0 or words.count() > 0:
            continue
        save_note(url, added)
        count +=  1
    return HttpResponse("%s\n" % count)

def fetch_latest_urls():
    token = settings.TWITCN_PRIVATE_TOKEN
    api = getPrivateApi(token)
    messages = api.GetUserTimeline(user='miaoju')

    info = []
    for msg in messages:
        if "#Kindle" not in msg.text or 'http' not in msg.text:
            continue
        url = re.search(r'(http[^ ]+)', msg.text).group(1)
        added = datetime.datetime(*rfc822.parsedate(msg.created_at)[:6])
        info.append((url, added))
    return info

def save_note(url, date=None):
    soup = get_soup_by_url(url)
    tag = soup.find("div", {'class': 'highlightText'})
    text = ''.join(tag.findAll(text=True)).strip()

    remark = ''
    tag = soup.find("div", {'class': 'note'})
    if tag:
        remark = ''.join(tag.findAll(text=True)).replace('Note:', '').replace('@zzrt', '').strip()

    cover_tag = soup.find('div', {'class': 'cover'})
    tag = cover_tag.find("span", {'class': 'title'})
    if tag:
        book = ''.join(tag.findAll(text=True)).strip()
        if 'Personal Document' in book:
            book = ''
    else:
        book = ''

    tag = cover_tag.find("span", {'class': 'author'})
    if tag:
        author = ''.join(tag.findAll(text=True)).replace(' by ', '').strip()
    else:
        author = ''

    if ' ' not in text \
        and text[0] in ASCII_CHARS \
        and len(text) <= 64:
        if Word.objects.filter(word=text).count() == 0:
            Word.objects.create(url=url, word=text)
    else:
        note = Note()
        note.url = url
        note.text = text
        note.added = date or datetime.datetime.now()
        if remark:
            note.remark = remark
        if book:
            note.book = book
        if author:
            note.author = author
        note.save()


#!flask/bin/python
from flask import Flask, jsonify, abort
from timeit import time

app = Flask(__name__)

sys_config = {
    #cam list must has the same length as window list
    'min_update_period': 120,
    'cam_list': [0, 1, 2, 3],
    'window_list': [
	#canteenID: windowID
        (0, 0),
	(0, 1),
	(1, 0),
	(1, 1)
    ]
}

now = time.time()
cached_data = {
    '0': { #canteen id
	'0' : { #window id
	    'queue_len': 10,
	    'unit_time': 5, #in seconds
	    'timestamp': now
	}
    }
}

@app.route('/')
def index():
    print("visiting index")
    return "Hello, World!"

@app.route('/query/<int:canteenID>/<int:windowID>', methods=['GET'])
def query_api_window(canteenID, windowID):
    print(canteenID, windowID)
    if canteenID >= 0 and windowID >= 0:
        if canteenID in cached_data.keys():
            if windowID in cached_data[canteenID].keys():
                now = time.time()
                if int(now - cached_data[canteenID][windowID]['timestamp']) <= sys_config['min_update_period']:
                    return cached_data[canteenID][windowID]
    return jsonify({'data': 0})

@app.route('/query/<int:canteenID>', methods=['GET'])
def query_api_canteen(canteenID):
    print(canteenID)
    return jsonify({'data': 0})

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


#!/usr/bin/env python3
#- *- coding:utf-8 -*-
"""This module contains functions for Token Access Web API

The API simulates a management canal to :
- Request a HOTP token to send a message to a recipient managed by this system
- (Re-)generate a HOTP seed
"""
__author__='Charles Dubos'
__license__='GNUv3'
__credits__='Charles Dubos'
__version__="0.1.0"
__maintainer__='Charles Dubos'
__email__='charles.dubos@telecom-paris.fr'
__status__='Development'

# Built-in

from logging import getLogger

# Other libs

from fastapi import FastAPI, HTTPException, Form

# Owned libs

from lib.LibTAServer import *
from lib.LibTACrypto import getHotp, PreSharedKey
import lib.LibTADatabase as dbManage
from lib.LibTAPolicy import policy

# Module directives

## Load logger
logger=getLogger('tknAcsServers')
logger.debug(f'Logger loaded in {__name__}')

## Load database
database=context.loadDatabase()

## Definition of API
app = FastAPI()

# API functions

## Global-level API points (all-public accessibles)
@app.get("/")
async def root():
    """Only returns a welcoming message.
    Used for connection-testing sake.
    """
    return {
        "message": "Welcome to Token access: a HOTP email validator.",
        "help":"See '/docs' for API documentation",
        "version":__version__,
        "status":__status__
    }

@app.get("/requestToken/")
async def requestToken(sender: str, recipient: str):
    """Requests a HOTP token for external sender to recipient (user).

    Args:
        sender (str): email address of sender
        recipient (str): email adress of recipient

    Raises:
        ValueError (HTTP/418): Bad email address
        PermissionError (HTTP/406): Policy not allowing the connection

    Returns:
        json: formatted with {"token","allowed_for": {"from", "to"}}
    """
    try:
        recipientAddr = EmailAddress().parser(recipient)
        if not database.isInDatabase(userEmail=recipientAddr.getEmailAddr()):
            raise PermissionError

        if not policy(sender, recipient):
            raise PermissionError

        preSharedKey, count = database.getHotpData(
            userEmail=recipientAddr.getEmailAddr(),
        )

        hotp = getHotp(
            preSharedKey=preSharedKey,
            count=count,
            **{**context.hash, **context.hotp},
        )

        ## Adding the record to token database
        database.setSenderTokenUser(
            userEmail=recipientAddr.getEmailAddr(),
            sender=sender,
            counter= count,
            token=hotp,
        )

        return {
            "token": hotp,
            "allowed_for": {
                "from": sender,
                "to": recipient,
                }
            }
    except ValueError:
        raise HTTPException(
            status_code=418,
            detail="Bad email address"
        )
    except PermissionError:
        raise HTTPException(
            status_code=406,
            detail="Policy not allowing this connection."
        )

## User-level API points requesting authentication
def auth(func):
    print("TODO: AUTH decorator")
    return func

@app.get("/{username}/")
@auth
async def home(username:str):
    """Only returns a welcoming message.
    Used for connection-testing sake.

    Args:
        username (str): user email address
    """
    if not database.isInDatabase(userEmail=username):
        raise HTTPException(
            status_code=406,
            detail="Policy not allowing this connection."
        )
    return {
        "message": "Welcome " + username,
        "help":"See '/docs' for API documentation"
    }

@app.get("/{username}/getConfiguration")
@auth
async def home(username:str):
    """Returns server configurations useful for the client
    Including:
    - Cryptography configurations
    - Default configurations

    Args:
        username (str): user email address

    Returns:
        json: The json of configuration fields
    """

    return {
        'window':int(context.GLOBAL['window']),
        'context':{
            'elliptic':context.elliptic,
            'hash':context.hash,
            'hotp':context.hotp,
        },
    }

@app.post("/{username}/generateHotpSeed")
@auth
async def generateHotpSeed(username:str, pubKey:str=Form()):
    """Regenerate seed (PSK) for Hotp generation from the user public key &
    returns the generated PSK seed, the reinitialized counter and the server
    public key.
    ! The previous token generated with the elder seed become lapsed !

    Args:
        username (str): user email address.
        pubKey (str): user EC pubkey to generate ECDH PSK, given by POST form.

    Returns:
        json: formatted with {"user", "pubKey", "counter"}
    """

    logger.info(f'Request PSK for {username} with pubKey {pubKey}')

    logger.debug('Generating server private key.')
    serverPSK = PreSharedKey(
        **{**context.hash, **context.elliptic}
    )
    logger.debug('Generating PSK.')
    serverPSK.generate(
        user=username,
        recipientPubKey=pubKey,
    )
    counter = 0

    logger.debug('Saving PSK to database.')
    database.updatePsk(
        userEmail=username,
        psk=serverPSK.PSK,
        count=counter,
    )

    logger.debug('Returning public key and counter.')
    return {
        "user": username,
        "pubKey": serverPSK.exportPubKey(),
        "counter": counter,
    }

@app.get("/{username}/getCount")
@auth
async def getCount(username:str):
    """Returns the counter value of user.

    Args:
        username (str): user email address

    Returns:
        json: formatted with {"username", "counter"}
    """

    (_, counter) = database.getHotpData(
        userEmail=username,
    )

    return {
        "username": username,
        "counter": counter,
    }

@app.get("/{username}/getAllTokens")
@auth
async def getAllTokens(username:str):
    """Returns all tokens for a specific user

    Args:
        username (str): user email address

    Returns:
        json: formatted with {"username",{"token":"sender"}}
    """

    tokens = database.getAllTokensUser(
        userEmail=username,
    )

    return {
        "username": username,
        "tokens": dict((token, sender) for token, sender in tokens),
    }


import csv
import sys
import json
import pickle

class Plik:
    def __init__(self, nazwa):
        self.nazwa = nazwa
        self.rozszerzenie = nazwa.split(".")[-1]  # wyodrębnij rozszerzenie pliku

    def odczytaj(self):
        if self.rozszerzenie == "csv":
            plik = PlikCSV(self.nazwa)
            return plik.odczytaj()
        elif self.rozszerzenie == "json":
            plik = PlikJSON(self.nazwa)
            return plik.odczytaj()
        elif self.rozszerzenie == "txt":
            plik = PlikTXT(self.nazwa)
            return plik.odczytaj()
        elif self.rozszerzenie == "pickle":
            plik = PlikPICKLE(self.nazwa)
            return plik.odczytaj()

        else:
            raise ValueError("Nieobsługiwane rozszerzenie pliku")

    def zapisz(self, dane):
        if self.rozszerzenie == "csv":
            plik = PlikCSV(self.nazwa)
            plik.zapisz(dane)
        elif self.rozszerzenie == "json":
            plik = PlikJSON(self.nazwa)
            plik.zapisz(dane)
        elif self.rozszerzenie == "txt":
            plik = PlikTXT(self.nazwa)
            plik.zapisz(dane)
        elif self.rozszerzenie == "pickle":
            plik = PlikPICKLE(self.nazwa)
            plik.zapisz(dane)
        else:
            raise ValueError("Nieobsługiwane rozszerzenie pliku")

class Zmieniacz(Plik):
    def zmien_wartosci(self, dane, zmiany):
        for zmiana in zmiany:
            z = zmiana.split(",")
            if len(z) != 3:
                print("Blad!!!!!!")
                quit()
            x, y, wartosc = z
            x = int(x) - 1
            y = int(y) - 1
            if x < 0 or y < 0:
                print("Blad, x i y musza byc wieksze od 0.")
                quit()
            dane[x][y] = wartosc
        return dane

class PlikCSV(Zmieniacz):
    def odczytaj(self):
        dane = []
        with open(self.nazwa, "r") as PlikCSV:
            czytnik = csv.reader(PlikCSV)
            for wiersz in czytnik:
                dane.append(wiersz)
        return dane

    def zapisz(self, dane):
        with open(self.nazwa, "w", newline="") as PlikCSV:
            zapis = csv.writer(PlikCSV)
            for wiersz in dane:
                zapis.writerow(wiersz)

class PlikJSON(Zmieniacz):
    def odczytaj(self):
        print(self.nazwa)
        with open(self.nazwa, "r") as plikjson:
            dane = json.load(plikjson)
        return dane

    def zapisz(self, dane):
        with open(self.nazwa, "w") as plikjson:
            json.dump(dane, plikjson)

class PlikTXT(Zmieniacz):
    def odczytaj(self):
        with open(self.nazwa, "r") as pliktxt:
            dane = pliktxt.read()
        return dane

    def zapisz(self, dane):
        with open(self.nazwa, "w") as pliktxt:
            dane_str = "\n".join(str(element) for element in dane)
            pliktxt.write(dane_str)

# Funkcje do odczytu i zapisu pliku PICKLE
class PlikPICKLE(Zmieniacz):
    def odczytaj(self):
        with open(self.nazwa, "rb") as plikpickle:
            dane = pickle.load(plikpickle)
        return dane

    def zapisz(self, dane):
        with open(self.nazwa, "wb") as plikpickle:
            pickle.dump(dane, plikpickle)

def stworz_klase_obslugi_pliku(plik_wejsciowy):
    if plik_wejsciowy.endswith(".csv"):
        plik = PlikCSV(plik_wejsciowy)
    elif plik_wejsciowy.endswith(".json"):
        plik = PlikJSON(plik_wejsciowy)
    elif plik_wejsciowy.endswith(".txt"):
        plik = PlikTXT(plik_wejsciowy)
    elif plik_wejsciowy.endswith(".pickle"):
        plik = PlikPICKLE(plik_wejsciowy)
    else:
        print("Nieobsługiwany format pliku!")
        sys.exit(1)
    return plik

# Główna funkcja programu
if __name__ == "__main__":
    # Sprawdzenie poprawności argumentów wywołania programu
    if len(sys.argv) < 3:
        print(
            "Sposób użycia: python reader.py <plik_wejsciowy> <plik_wyjsciowy> <zmiana_1> <zmiana_2> ... <zmiana_n>"
        )
        print(
            '<zmiana_x> - Zmiana w postaci "x,y,wartosc" - x (kolumna) oraz y (wiersz) są współrzędnymi liczonymi od 0, natomiast "wartosc" to zmiana, która ma trafić na podane miejsce.'
        )
        sys.exit(1)

    # Odczytanie nazw plików oraz zmian z argumentów wywołania programu
    plik_wejsciowy = sys.argv[1]
    plik_wyjsciowy = sys.argv[2]
    zmiany = sys.argv[3:]

    # # Odczytanie danych z pliku wejściowego
    # dane = odczytaj_csv(plik_wejsciowy)
    # Odczytanie danych z pliku wejściowego

    plik = stworz_klase_obslugi_pliku(plik_wejsciowy)
    plik_zapis = stworz_klase_obslugi_pliku(plik_wyjsciowy)

    dane = plik.odczytaj()

    # Przetworzenie zmian
    dane = plik.zmien_wartosci(dane, zmiany)

    # Wyświetlenie danych w terminalu
    for wiersz in dane:
        print(",".join(wiersz))

    # # Zapisanie danych do pliku wyjściowego
    # zapisz_csv(plik_wyjsciowy, dane)
    # Zapisanie danych do pliku wyjściowego
    plik_zapis.zapisz(dane)