import streamlit as st
import pandas as pd
import numpy as np
import joblib
import pandas as pd
import matplotlib.pyplot as plt
import altair as alt
from sklearn.preprocessing import *

from sqlcnx import *
from AITF import *

def on_active(key):
    st.session_state[key] = True
    return

def p0():
    st.title("AI Catalyst Response System")
    st.tabs(["AI Catalyst Response System", ">>","Introduction"])
    st.write("""
            The development of material science has long faced the problem of uncertainty.
            Since material science is mostly empirical, large amounts of trials and experiments are needed.
            Researchers usually have no idea of the performance of a catalyst until it is tested.
            To solve this problem, we present the AI Catalyst Response System, which consists of four parts based on the question type:
            True or False question, Choice question, Completion question, and Response question.
            The system utilizes natural language processing (NLP) and machine learning (ML) to analyze tens of thousands of published papers.
            """)

    return

def p1():
    st.title("True or False Question")
    st.tabs(["AI Catalyst Response System", ">>","True or False Question"])
    st.write("""
            In the True or False question part, we simply categorize the catalysts into groups of “good” and “bad” based on their predicted performance.
            In this way, we hope to provide some references for researchers before they conduct their experiments and save valuable time and resources.
            """)

    Catalyst = st.text_input("Chemical formula of your catalyst",
        help = "Please enter the chemical formula of your catalyst, such as Ag, Pt3Cu, NiCo2O4, or NiCo2O4@Pt.")
    Reaction = st.selectbox(
        'Applied Reaction',
        ('HER', 'OER', 'ORR'))
    NanoBulk = st.selectbox(
        'Is your material nano or bulk?',
        ('nano', 'bulk'))
    if NanoBulk == "bulk":
        Nanostructure = st.selectbox(
            'Nanostructure of your material',
            ('bulk',))
    else:
        Nanostructure = st.selectbox(
            'Nanostructure of your material',
            ('bulk', 'nanoarray','nanobar','nanocluster','nanofiber','nanofilm',
            'nanopolyhedron','nanoporous','nanoribbon','nanorod','nanosheet','nanosphere',
            'nanovesicle','nanotube','others'))
    Acidity = st.selectbox(
        'Acidity of the environment',
        ('acidic', 'neutral','alkaline'))

    b1 = st.button("Click the button to see the result")
    sc3, sc4 = st.columns((1,4))
    if b1:
        try:
            predict = AITF(Catalyst,Reaction,NanoBulk,Nanostructure,Acidity)
            #st.write("The performance of this reaction is predicted to be: ",predict)
            sc3.metric("Reaction performance",predict)
            sc4.warning("Please note that the result is for reference only.")
        except:
            sc3.metric("Reaction performance","Null")
            sc4.error("Invalid catalyst: please check your input and try again.")
    else:
        sc3.metric("Reaction performance","Null")
        sc4.warning("Please note that the result is for reference only.")
        #predict_result = model.predict(predict_data)

    return

def p2():
    st.title("Completion Question")
    st.tabs(["AI Catalyst Response System", ">>","Completion Question"])
    st.write("In this part, we will output the most suited reaction or catalyst based on your input.")
    st.selectbox("Input datatype",["Catalyst","Reaction"])
    st.text_area("Output suggestions")
    return

def p3():
    st.title("Response Question")
    st.tabs(["AI Catalyst Response System", ">>","Response Qustion"])
    st.write("In the response question, we want to explain any question that a catalyst research may encounter.")
    st.text_input("Input the question")
    st.button("Result")
    st.text_area("Result provided")
    st.text_area("Result related")
    return

def p4():
    st.title("Choice Question")
    st.tabs(["AI Catalyst Response System", ">>","Choice Question"])
    st.write("In the choice question, we wish to select the best catalyst for a given reaction among the given candidates.")
    st.button("Add Catalyst")
    Catalyst = st.text_input("Chemical formula of your catalyst",
        help = "Please enter the chemical formula of your catalyst, such as Ag, Pt3Cu, NiCo2O4, or NiCo2O4@Pt.")
    Reaction = st.selectbox(
        'Applied Reaction',
        ('HER', 'OER', 'ORR'))
    NanoBulk = st.selectbox(
        'Is your material nano or bulk?',
        ('nano', 'bulk'))
    if NanoBulk == "bulk":
        Nanostructure = st.selectbox(
            'Nanostructure of your material',
            ('bulk',))
    else:
        Nanostructure = st.selectbox(
            'Nanostructure of your material',
            ('bulk', 'nanoarray','nanobar','nanocluster','nanofiber','nanofilm',
            'nanopolyhedron','nanoporous','nanoribbon','nanorod','nanosheet','nanosphere',
            'nanovesicle','nanotube','others'))
    Acidity = st.selectbox(
        'Acidity of the environment',
        ('acidic', 'neutral','alkaline'))
    st.button("Go")
    st.write("Result")
    return

def p5():
    st.title("Research Recommendation")
    st.tabs(["AI Catalyst Response System", ">>","Research Recommendation"])
    st.file_uploader("Upload a txt file")
    sc1, sc2, sc3, sc4, sc5 = st.columns((1,1,1,1,1))
    sc1.metric("Overall Rating", 9.5, delta="13%")
    sc2.metric("Material", 8.1, delta="7%" )
    sc3.metric("Method", 9.2, delta="11%")
    sc4.metric("Application", 9.1, delta="9%")
    sc5.metric("Characterization", 5.9, delta="-7%", delta_color="normal")
    st.text_area(label="Improvement Points",
                value= '''
                It’s compulsory to demonstrate personal ideas and ways to investigate,
                solve a specific issue, or develop strategies to expand the scope of examinations.
                A chemistry research proposal is an extremely important paper
                that promotes a student’s candidacy when applying to the advanced course.
                To succeed in the application process to the chemistry PhD program,
                a student should do their best to impress the admission committee
                and persuade it of their high competence level in the chemistry area.
                ''',
                height=300)
    return

def p6():
    st.title("View our database")
    st.tabs(["AI Catalyst Response System", ">>","View our database"])
    st.header("1. Retrieve Papers")
    doi = st.text_input(label="Seach by DOI",value="https://doi.org/10.1016/j.chs.2003.09.018")
    title, year, journal, abstract = retrieve_paper_info(doi)
    st.subheader(title)
    sc1, sc2 = st.columns((1,2.8))
    sc2.text_area("Abstract", value=abstract,height=130)
    sc1.metric("Journal", value= journal)
    sc1.metric("Year", value= year)
    df_paper = count_paper()
    df_journal = count_journal()
    df_paper_journal = count_journal_paper()
    st.write("   ")
    st.write("   ")
    st.write("   ")

    st.header("2. Visualize Database")
    sc1, sc2 = st.columns((3,1))
    sc2.bar_chart(df_journal, x="journal", height=280)
    sc2.area_chart(df_paper, x="year", height=140)
    sc1.line_chart(df_paper_journal,height=450)
    #st.table(df_paper_journal)
    return


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 22 23:14:59 2019

@author: tom
"""
import RPi.GPIO as GPIO
import asyncio
import time

class ultrasonic_sensor():
    def __init__(self, trigger_pin = 18, echo_pin = 25):
        GPIO.setmode(GPIO.BCM)
        #set GPIO Pins
        self.GPIO_TRIGGER = trigger_pin
        self.GPIO_ECHO = echo_pin
        #set GPIO direction (IN / OUT)
        GPIO.setup(self.GPIO_TRIGGER, GPIO.OUT)
        GPIO.setup(self.GPIO_ECHO, GPIO.IN)
        self.obj_distance = 999
        self.power_on = True

    async def determine_obj_distance(self):
        while self.power_on:
            # set Trigger to HIGH
            GPIO.output(self.GPIO_TRIGGER, True)
            # set Trigger after 0.01ms to LOW
            time.sleep(0.00001)
            GPIO.output(self.GPIO_TRIGGER, False)
            StartTime = time.time()
            StopTime = time.time()
            # save StartTime
            while GPIO.input(self.GPIO_ECHO) == 0:
                 StartTime = time.time()
            # save time of arrival
            while GPIO.input(self.GPIO_ECHO) == 1:
                StopTime = time.time()
            # time difference between start and arrival
            TimeElapsed = StopTime - StartTime
            # multiply with the sonic speed (34300 cm/s)
            # and divide by 2, because there and back
            self.obj_distance = (TimeElapsed * 34300) / 2
            await asyncio.sleep(0.2)

if __name__ == "__main__":

    async def test():
        run = 0
        while True:
            print("distance to next object is = ", distance_sensor.obj_distance)
            run += 1
            if run > 10:
                distance_sensor.power_on = False
                break
            await asyncio.sleep(0.5)

    GPIO.setmode(GPIO.BCM)
    distance_sensor = ultrasonic_sensor(trigger_pin = 18, echo_pin = 25)
    futures = [distance_sensor.determine_obj_distance(), test()]
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(futures))
    loop.close()
    GPIO.cleanup()


import sqlite3
from flask import Flask, jsonify, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

DATABASE = "pruebas.db"

def conectar():
    conn = sqlite3.connect(DATABASE)
    conn.row_factory = sqlite3.Row
    return conn

def crear_tabla():
    conn = conectar()
    cursor = conn.cursor()
    cursor.execute("""
                CREATE TABLE IF NOT EXISTS productos (
                    codigo INT PRIMARY KEY,
                    descripcion VARCHAR(255),
                    stock INT,
                    precio FLOAT)
            """)
    cursor.execute("""
                CREATE TABLE IF NOT EXISTS carrito (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    codigo INT,
                    descripcion VARCHAR(255),
                    cantidad INT,
                    precio FLOAT)
            """)
    conn.commit()
    cursor.close()
    conn.close()

@app.route('/productos', methods=['POST'])
def alta_producto():
    data = request.get_json()
    if 'codigo' not in data or 'descripcion' not in data or 'stock' not in data or 'precio' not in data:
        return jsonify({'error': 'Falta uno o más campos requeridos'}), 400
    try:
        conn = conectar()
        cursor = conn.cursor()
        cursor.execute("""
                    INSERT INTO productos(codigo, descripcion, stock, precio)
                    VALUES(?,?,?,?) """,
                    (data['codigo'], data['descripcion'], data['stock'], data['precio']))
        conn.commit()
        cursor.close()
        conn.close()
        return jsonify({'mensaje': 'Alta efectuada correctamente'}), 201
    except:
        return jsonify({'error': 'Error al dar de alta el producto'}), 500

@app.route('/productos/<int:codigo>', methods=['GET'])
def consultar_producto(codigo):
    try:
        conn = conectar()
        cursor = conn.cursor()
        cursor.execute("""SELECT * FROM productos
                            WHERE codigo=?""", (codigo,))
        producto = cursor.fetchone()
        if producto is None:
            return jsonify({'error': 'Producto no encontrado'}), 404
        else:
            return jsonify({
                'codigo': producto['codigo'],
                'descripcion': producto['descripcion'],
                'stock': producto['stock'],
                'precio': producto['precio']
            })
    except:
        return jsonify({'error': 'Error al consultar el producto'}), 500

@app.route('/productos/<int:codigo>', methods=['PUT'])
def modificar_producto(codigo):
    data = request.get_json()
    if 'descripcion' not in data or 'stock' not in data or 'precio' not in data:
        return jsonify({'error': 'Falta uno o más campos requeridos'}), 400
    try:
        conn = conectar()
        cursor = conn.cursor()
        cursor.execute("""SELECT * FROM productos WHERE codigo=?""", (codigo,))
        producto = cursor.fetchone()
        if producto is None:
            return jsonify({'error': 'Producto no encontrado'}), 404
        else:
            cursor.execute("""UPDATE productos SET descripcion=?, stock=?, precio=?
                                WHERE codigo=?""", (data['descripcion'], data['stock'], data['precio'], codigo))
            conn.commit()
            cursor.close()
            conn.close()
            return jsonify({'mensaje': 'Producto modificado correctamente'}), 200
    except:
        return jsonify({'error': 'Error al modificar el producto'}), 500

@app.route('/productos', methods=['GET'])
def listar_productos():
    try:
        conn = conectar()
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM productos")
        productos = cursor.fetchall()
        response = []
        for producto in productos:
            response.append({
                'codigo': producto['codigo'],
                'descripcion': producto['descripcion'],
                'stock': producto['stock'],
                'precio': producto['precio']
            })
        return jsonify(response)
    except:
        return jsonify({'error': 'Error al listar los productos'}), 500

@app.route('/carrito', methods=['POST'])
def agregar_al_carrito():
    data = request.get_json()
    if 'codigo' not in data or 'cantidad' not in data:
        return jsonify({'error': 'Falta uno o más campos requeridos'}), 400
    try:
        conn = conectar()
        cursor = conn.cursor()
        cursor.execute("""SELECT * FROM productos WHERE codigo=?""", (data['codigo'],))
        producto = cursor.fetchone()
        if producto is None:
            return jsonify({'error': 'Producto no encontrado'}), 404

        cantidad = int(data['cantidad'])
        if cantidad <= 0:
            return jsonify({'error': 'La cantidad debe ser mayor a cero'}), 400

        if producto['stock'] < cantidad:
            return jsonify({'error': 'No hay suficiente stock disponible'}), 400

        cursor.execute("""SELECT * FROM carrito WHERE codigo=?""", (data['codigo'],))
        item_carrito = cursor.fetchone()
        if item_carrito is None:
            cursor.execute("""INSERT INTO carrito(codigo, descripcion, cantidad, precio)
                              VALUES(?,?,?,?)""",
                           (producto['codigo'], producto['descripcion'], cantidad, producto['precio']))
        else:
            nueva_cantidad = item_carrito['cantidad'] + cantidad
            cursor.execute("""UPDATE carrito SET cantidad=? WHERE codigo=?""",
                           (nueva_cantidad, data['codigo']))

        nuevo_stock = producto['stock'] - cantidad
        cursor.execute("""UPDATE productos SET stock=? WHERE codigo=?""",
                       (nuevo_stock, data['codigo']))

        conn.commit()
        cursor.close()
        conn.close()
        return jsonify({'mensaje': 'Producto agregado al carrito correctamente'}), 201
    except:
        return jsonify({'error': 'Error al agregar el producto al carrito'}), 500

@app.route('/carrito', methods=['GET'])
def obtener_carrito():
    try:
        conn = conectar()
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM carrito")
        productos_carrito = cursor.fetchall()
        response = []
        for producto in productos_carrito:
            response.append({
                'id': producto['id'],
                'codigo': producto['codigo'],
                'descripcion': producto['descripcion'],
                'cantidad': producto['cantidad'],
                'precio': producto['precio']
            })
        return jsonify(response)
    except:
        return jsonify({'error': 'Error al obtener el carrito de compras'}), 500

@app.route('/carrito/<int:id>', methods=['DELETE'])
def eliminar_del_carrito(id):
    try:
        conn = conectar()
        cursor = conn.cursor()
        cursor.execute("""SELECT * FROM carrito WHERE id=?""", (id,))
        producto = cursor.fetchone()
        if producto is None:
            return jsonify({'error': 'Producto no encontrado en el carrito'}), 404

        cursor.execute("""DELETE FROM carrito WHERE id=?""", (id,))
        conn.commit()

        cursor.execute("""SELECT * FROM productos WHERE codigo=?""", (producto['codigo'],))
        producto_stock = cursor.fetchone()
        nuevo_stock = producto_stock['stock'] + producto['cantidad']
        cursor.execute("""UPDATE productos SET stock=? WHERE codigo=?""", (nuevo_stock, producto['codigo']))
        conn.commit()

        cursor.close()
        conn.close()
        return jsonify({'mensaje': 'Producto eliminado del carrito correctamente'}), 200
    except:
        return jsonify({'error': 'Error al eliminar el producto del carrito'}), 500

@app.route('/productos/<int:codigo>', methods=['DELETE'])
def eliminar_producto(codigo):
    try:
        conn = conectar()
        cursor = conn.cursor()
        cursor.execute("""SELECT * FROM productos WHERE codigo=?""", (codigo,))
        producto = cursor.fetchone()
        if producto is None:
            return jsonify({'error': 'Producto no encontrado'}), 404

        cursor.execute("""DELETE FROM productos WHERE codigo=?""", (codigo,))
        conn.commit()
        cursor.close()
        conn.close()
        return jsonify({'mensaje': 'Producto eliminado correctamente'}), 200
    except:
        return jsonify({'error': 'Error al eliminar el producto'}), 500

@app.route('/', methods=['GET'])
def inicio():
    return "Hola Codo a Codo"

if __name__ == '__main__':
    crear_tabla()
    app.run()


from pandas import read_csv
from IPython.display import display
import numpy as np
import sys
import math

###############################
 ####Maria Eugenia Lopez #####
###############################

def fully_grown_depuration(number_to_remove=0.50):
	 return plants.loc[plants.height_m > number_to_remove]

def convert_GPS_lat_long(df):
	for index, row in df.iterrows():
		lat_viejo = row["GPS_lat"]
		latVal = (40008000*row["GPS_lat"])/360
		#res= div*0.001#to convert to Klm
		df.loc[index,"GPS_lat"] = latVal

		lat_radians = math.radians(lat_viejo)
		lonVal = (40075160*row["GPS_lon"])/360
		lonVal = lonVal*math.cos(lat_radians)
		#res = res*0.001
		df.loc[index,"GPS_lon"] = lonVal

##----------------------------------------
##Part A Assembling a Data Set
##----------------------------------------

##----------------------------------------
##Input and Output: Data Frames

plants = read_csv('environmental_survey/plants2017.csv',
	index_col=0)

plants.reset_index(level=0,inplace=True)

plants.drop(plants.index[plants.Plant == 'tree'], inplace=True)
#display(plants.head(n=50))

plants.reset_index(drop=True,inplace=True)

##----------------------------------------
##Functions
convert_GPS_lat_long(	plants)
plants.rename(columns={'GPS_lon':'Meters_lon',
						'GPS_lat':'Meters_lat'}, inplace=True)

##----------------------------------------
##Functions and Data Structures: Boolean Indexing
heiht_set_by_user = float(input("Set the height that you want: ") or "0.5")
plants = fully_grown_depuration(float(heiht_set_by_user))

#reseting the index after the depuration
plants.reset_index(drop=True,inplace=True)

display(plants)


# K-Means Clustering

# Importing the libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# Importing the dataset
dataset = pd.read_csv('Mall_Customers.csv')
# Seletion Annual Income (k$) and Spending Score (1-100) columns
X = dataset.iloc[:, [3, 4]].values

# Using the elbow method to find the optimal number of clusters
from sklearn.cluster import KMeans
wcss = []
for i in range(1, 11): # 10 clusters
	# k-means++ : selects initial cluster centers for k-mean clustering in a smart way to speed up convergence.
    kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 0)
    # Fit Annual Income (k$) X Spending Score (1-100)
    # The fit method returns for each observation which cluster it belongs to
    kmeans.fit(X)
    # kmeans.inertia_ = Sum of squared distances of samples to their closest cluster center.
    wcss.append(kmeans.inertia_)
plt.plot(range(1, 11), wcss)
# The Elbow method is a heuristic method of interpretation and validation of consistency within cluster analysis designed
# to help finding the appropriate number of clusters in a dataset.
'''
More precisely, if one plots the percentage of variance explained by the clusters against the number of clusters,
the first clusters will add much information (explain a lot of variance), but at some point the marginal gain will drop,
giving an angle in the graph. The number of clusters is chosen at this point, hence the "elbow criterion".
'''
# ==> According to the Elbow Method the best number of cluster is 5
plt.title('The Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('WCSS')
plt.show()

# Fitting K-Means to the dataset
kmeans = KMeans(n_clusters = 5, init = 'k-means++', random_state = 0)
y_kmeans = kmeans.fit_predict(X)
print("Fitting K-Means to the dataset:", y_kmeans)

# Visualising the clusters
# Cluster 1 has high income and low spending score. A better name for this cluster of clients as "Careful clients"
plt.scatter(X[y_kmeans == 0, 0], X[y_kmeans == 0, 1], s = 100, c = 'red', label = 'Cluster 1')
# Cluster 2 has average income and average spending score. A better name for this cluster of clients as "Standard clients"
plt.scatter(X[y_kmeans == 1, 0], X[y_kmeans == 1, 1], s = 100, c = 'blue', label = 'Cluster 2')
# Cluster 3 has high income and high spending score. A better name for this cluster of clients as "Target clients"
# So, cluster 3 is the cluster of clients that would be the main potential target of the mall marketing campaigns
# and it would be very insighful for them all to understand what kind of products are bought by the clients in this cluster
plt.scatter(X[y_kmeans == 2, 0], X[y_kmeans == 2, 1], s = 100, c = 'green', label = 'Cluster 3')
# Cluster 4 has low income and high spending score. A better name for this cluster of clients as "Careless clients"
plt.scatter(X[y_kmeans == 3, 0], X[y_kmeans == 3, 1], s = 100, c = 'cyan', label = 'Cluster 4')
# Cluster 5 has low income and low spending score. A better name for this cluster of clients as "Sensible clients"
plt.scatter(X[y_kmeans == 4, 0], X[y_kmeans == 4, 1], s = 100, c = 'magenta', label = 'Cluster 5')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s = 300, c = 'yellow', label = 'Centroids')
plt.title('Clusters of customers')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.legend()
plt.show()


import torch
import matplotlib.pyplot as plt
from utils import update_weights_rates
from sklearn.datasets import make_blobs
from ControlledModules import ControlledNetwork
from tqdm import tqdm
import numpy as np

v_th = 1
target_rates = [-1, 2]
C_precision = 0.01
timesteps = 2
initial_steps_plot = 5
neuron_noise = 0.

plot_path = "./plots/"
plot = True

dynamic_plot_idxs = [1, 501, 2001, 9001]

data_noise = 0.1
total_points = 10000
X, y = make_blobs(total_points, n_features=3, centers=[[0, 1, 0], [1, 0, 0]], cluster_std=data_noise)
X[:, 2] = 1.

net = ControlledNetwork((3, 1), mode="rate", tau_mem=1., tau_stdp=2.54)
layer = net.layers[0]

w_evol = []
control_evol = []
FF_output_evol = []
time_to_targ_evol = []
DW_DH_list = []
DW_STDP_list = []
list_output_dynamics = []
list_controller_dynamics = []

count_1 = 0
next_dyn_plot_idx = 0
X = torch.from_numpy(X).float()

lr = 0.01
optim = torch.optim.SGD(
    net.parameters(),
    lr=lr,
    momentum=0.0,
    weight_decay=0.0
)

# loop over datapoints
for idx in tqdm(range(len(y))):
    target_rate = y[idx]
    x = X[idx]
    control_target_rate = target_rates[target_rate]
    optim.zero_grad()

    # FORWARD, with controller controlling
    output, input_C = net.evolve_to_convergence(
        x, target_rate, control_target_rate, precision=C_precision)

    R = len(output) - 1  # number of timesteps the controller had to act
    if R > 0:  # avoids learning if the feedback is already good
        DW_STDP_list.append(-lr * layer.ff.weight.grad.clone().numpy())
        optim.step()

        # Calculate (but not use) DH update using Pau's functions
        presynaptic_rates = torch.sigmoid(x).unsqueeze(0).expand((R, -1)).numpy()
        Dw_DH = update_weights_rates(output[:-1], presynaptic_rates)
        DW_DH_list.append(Dw_DH)

        # # Pau's version of STDP
        # Dw_STDP = update_weights_poisson(output[:-1], presynaptic_rates)
        # DW_STDP_list.append(Dw_STDP)

    count_1 += y[idx]
    if count_1 == dynamic_plot_idxs[next_dyn_plot_idx]:
        list_output_dynamics.append(output[1:])
        list_controller_dynamics.append(input_C)
        next_dyn_plot_idx = (next_dyn_plot_idx + 1) % len(dynamic_plot_idxs)

    w_evol.append(layer.ff.weight.data.squeeze().clone().numpy())
    FF_output_evol.append(output[0])
    time_to_targ_evol.append(len(input_C))

    if len(input_C) > 1:
        control_evol.append(input_C[-1])
    else:
        control_evol.append(0)

DW_DH_list = np.asarray(DW_DH_list)
DW_STDP_list = np.asarray(DW_STDP_list)

if plot:
    plt.figure(figsize=(10, 6))
    plt.subplot(231)
    plt.scatter(X[:, 0], X[:, 1], s=2, c=y)
    plt.title("Input Data")

    plt.subplot(232)
    plt.plot(w_evol)
    plt.legend(["$w_{A->C}$", "$w_{B->C}$", "$w_{bias}$"])
    plt.xlabel("Example")
    plt.ylabel("Weights")

    plt.subplot(233)
    max_C = max(control_evol)
    max_T = max(time_to_targ_evol)
    control_evol_norm = [c / max_C for (c, s) in zip(control_evol, y) if s == 1]
    FF_output_evol_norm = [(1 - f) ** 2 for (f, s) in zip(FF_output_evol, y) if s == 1]
    time_to_output_evol_norm = [t / max_T for (t, s) in zip(time_to_targ_evol, y) if s == 1]
    plt.plot(control_evol_norm, label="Feedback")
    plt.plot(FF_output_evol_norm, label="MSE Error")
    plt.plot(time_to_output_evol_norm, label="Time to target output")
    plt.xlabel("Example")
    plt.ylabel("Loss")
    plt.title("Loss functions for class 1")
    plt.legend()

    plt.subplot(234)
    for i in range(len(list_output_dynamics)):
        str_dynamics = "Dynamics at example " + str(dynamic_plot_idxs[i] - 1)
        plt.plot(list_output_dynamics[i], label=str_dynamics)
    plt.ylim([0.0, 1])
    plt.xlabel("Time")
    plt.ylabel("Output rate")
    plt.legend()

    plt.subplot(235)
    for i in range(len(list_output_dynamics)):
        str_dynamics = "Feedback at example " + str(dynamic_plot_idxs[i] - 1)
        plt.plot(list_controller_dynamics[i], label=str_dynamics)

    plt.xlabel("Time")
    plt.ylabel("Feedback strength")
    plt.legend()

    plt.subplot(236)
    # STDP vs dendritic error update
    L_errors = int(len(DW_DH_list) / 2)  # when plotting errors after learning we get noise
    plt.scatter(DW_STDP_list[:L_errors], DW_DH_list[:L_errors], s=2)
    plt.xlabel("STDP weight update")
    plt.ylabel("Dendritic error update")

    plt.savefig(plot_path + "all_plots.pdf", bbox_inches="tight", format="eps")
    plt.show()


# -*- coding: utf-8 -*-
from dateutil import parser
import calendar
import configparser

config = configparser.ConfigParser()
config.read('settings.ini')

YEAR = int(config['DATES']['YEAR'])
HOLIDAYS = config['DATES']['HOLIDAYS']
HOLIDAYS = [i.strip(',') for i in HOLIDAYS.split()]
WORKING_DATES = config['DATES']['WORKING_DATES']
WORKING_DATES = [i.strip(',') for i in WORKING_DATES.split()]

def convert_to_seconds(hours, minutes):
    return hours * 3600 + minutes * 60

def compute_working_time(_start, _end, dayfirst=False, result_in_hours=True):
    end = parser.parse(_end, dayfirst=dayfirst)
    start = parser.parse(_start, dayfirst=dayfirst)
    result = 0
    for month in range(start.month, end.month + 1):
        days = end.day + 1
        first_day = start.day
        if month != end.month:
            days = calendar.monthrange(YEAR, month)[1] + 1
        if month != start.month:
            first_day = 1
        for day in range(first_day, days):
            next_date = str(day) + '.' + str(month) + '.' + str(YEAR)
            next_date = parser.parse(next_date, dayfirst=True).date()
            if ((next_date.weekday() < 5) or
               (next_date in [parser.parse(i, dayfirst=True).date() for i in WORKING_DATES])) and \
               (next_date not in [parser.parse(i, dayfirst=True).date() for i in HOLIDAYS]):
                start_hour = 0
                start_minute = 0
                end_hour = 24
                end_minute = 0
                if next_date == start.date():
                    if convert_to_seconds(start.hour, start.minute) >= \
                       convert_to_seconds(start_hour, start_minute):
                        start_hour = start.hour
                        start_minute = start.minute
                    if convert_to_seconds(start.hour, start.minute) >= \
                       convert_to_seconds(end_hour, end_minute):
                           start_hour = end_hour
                           start_minute = end_minute

                if next_date == end.date():
                    if convert_to_seconds(end.hour, end.minute) <= \
                       convert_to_seconds(end_hour, end_minute):
                        end_hour = end.hour
                        end_minute = end.minute
                    if convert_to_seconds(end_hour, end_minute) <= \
                       convert_to_seconds(start_hour, start_minute):
                           start_hour = end_hour
                           start_minute = end_minute

                converted_start = convert_to_seconds(start_hour, start_minute)
                converted_end = convert_to_seconds(end_hour, end_minute)
                result += converted_end - converted_start
    if result_in_hours:
        result /= 3600
    return result
#
# time = compute_working_time('2019-08-19 09:10:00', '2019-08-26 09:00:00')
# print(time)


import os
import shutil
import animation
from venv import EnvBuilder
from subprocess import call
from sys import exit
from click import echo
from termcolor import colored

"""Long running functions"""

@animation.wait('spinner')
def create_venv(dir: str):

    virtualenv = EnvBuilder(with_pip=True)
    virtualenv.create(f"./{dir}")

"""helper functions"""

def error_exit(message: str):
    """Prints error message and exits the app with exit code 1."""
    echo()
    echo(colored(message, 'red'))
    echo()
    exit(1)

def create_file(file_name: str):
    open(file_name, 'w').close()

def create_folder(folder_name: str):
    os.mkdir(folder_name)

def shell(command: str):
    command = command.split()
    call(command)

def copy_filetree(source: str, destination: str, symlinks=True, ignore=None):
    if not os.path.exists(destination):
        os.makedirs(destination)
    for item in os.listdir(source):
        s = os.path.join(source, item)
        d = os.path.join(destination, item)
        if os.path.isdir(s):
            copy_filetree(s, d, symlinks, ignore)
        else:
            if not os.path.exists(d) or os.stat(s).st_mtime - os.stat(d).st_mtime > 1:
                shutil.copy2(s, d)

def print_command(command: str, description: str):
    echo('\t' + colored(command, 'cyan'))
    echo('\t'*2 + description)
    echo('\n')


class Solution:
    # @param n, an integer
    # @return an integer
    def __init__(self):
        self.dic = dict()

    def reverseBits(self, n):
        if self.dic.has_key(n):
            return self.dic[n]
        bits = []
        tmp = n
        for _ in xrange(32):
            bits.append(n&1)
            n >>= 1
        ret = 0
        for i in bits:
            ret <<= 1
            ret += i
        self.dic[tmp] = ret
        self.dic[ret] = tmp
        return ret


# -*- coding: utf-8 -*-

"""
Package: iads
File: utils.py
Année: LU3IN026 - semestre 2 - 2022-2023, Sorbonne Université
"""

# Fonctions utiles pour les TDTME de LU3IN026
# Version de départ : Février 2023

# import externe
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.utils import shuffle
from sklearn.metrics import accuracy_score

# ------------------------ REPRENDRE ICI LES FONCTIONS SUIVANTES DU TME 2:
#  genere_dataset_uniform:
def genere_dataset_uniform(p, n, binf=-1, bsup=1):
    d1 = np.random.uniform(binf, bsup, (2 * n, p))
    d2 = np.asarray([-1 for i in range(0, n)] + [1 for i in range(0, n)])
    np.random.shuffle(d2)
    return (d1, d2)
    raise NotImplementedError("Please Implement this method")

# genere_dataset_gaussian:
def genere_dataset_gaussian(positive_center, positive_sigma, negative_center, negative_sigma, nb_points):
    n_pos = np.random.multivariate_normal(positive_center, positive_sigma, nb_points)
    n_neg = np.random.multivariate_normal(negative_center, negative_sigma, nb_points)
    n_tout = np.concatenate([n_pos, n_neg])
    data_label = np.asarray([-1 for i in range(0, nb_points)] + [1 for i in range(0, nb_points)])
    n_tout, data_label = shuffle(n_tout, data_label)
    return (n_tout, data_label)
    raise NotImplementedError("Please Implement this method")

# plot2DSet:
def plot2DSet(desc, labels):
    desc_negatifs = desc[labels == -1]
    desc_positifs = desc[labels == +1]
    plt.scatter(desc_negatifs[:, 0], desc_negatifs[:, 1], marker='o', color="red")  # 'o' rouge pour la classe -1
    plt.scatter(desc_positifs[:, 0], desc_positifs[:, 1], marker='x', color="blue")  # 'x' bleu pour la classe +1

#  plot_frontiere:
def plot_frontiere(desc_set, label_set, classifier, step=30):
    mmax = desc_set.max(0)
    mmin = desc_set.min(0)
    x1grid, x2grid = np.meshgrid(np.linspace(mmin[0], mmax[0], step), np.linspace(mmin[1], mmax[1], step))
    grid = np.hstack((x1grid.reshape(x1grid.size, 1), x2grid.reshape(x2grid.size, 1)))

    # calcul de la prediction pour chaque point de la grille
    res = np.array([classifier.predict(grid[i, :]) for i in range(len(grid))])
    res = res.reshape(x1grid.shape)
    # tracer des frontieres
    #  colors[0] est la couleur des -1 et colors[1] est la couleur des +1
    plt.contourf(x1grid, x2grid, res, colors=["darksalmon", "skyblue"], levels=[-1000, 0, 1000])


from tkinter import*

class Screen:
    def __init__(self, w, h, del_x, del_y, col):
        self.root = Tk()
        self.width = w
        self.color = col
        self.height = h
        self.del_x = del_x
        self.del_y = del_y
        self.root.title("Snake")
        self.root.resizable(height=False,width=False)
        self.root.geometry(str(self.width)+"x"+str(self.height)+"+"+str(self.del_x)+"+"+str(self.del_y))
        self.root.attributes('-toolwindow', True)
        self.Create_Canvas()

    def Canvas_Pack(self):
        self.canvas.pack()

    def Destroy_Canvas(self):
        self.canvas.destroy()

    def Create_Canvas(self):
        self.canvas = Canvas(self.root, width=self.width, height=self.height, bg= self.color)
        self.Canvas_Pack()


from . import interface
from . import manager

class DataFinderTest(interface.BaseEndToEndTest):
    """End to end tests for data finder functionality."""

    NAME = "data_finder_test"

    def setup(self):
        """Import test timeline."""
        self.import_timeline("evtx_part.csv")

    def test_data_finder(self):
        """Test the data finder."""
        results = self.sketch.run_data_finder(
            start_date="2010-01-01T00:00:00",
            end_date="2010-06-30T12:00:00",
            rule_names=["test_data_finder"],
        )

        result_dict = results[0]
        self.assertions.assertFalse(result_dict.get("test_data_finder")[0])

        results = self.sketch.run_data_finder(
            start_date="2012-03-10T00:00:00",
            end_date="2012-03-30T12:00:00",
            rule_names=["test_data_finder"],
        )

        result_dict = results[0]
        self.assertions.assertTrue(result_dict.get("test_data_finder")[0])
        self.assertions.assertTrue(
            result_dict.get("test_data_finder")[1].startswith("Data disc")
        )

manager.EndToEndTestManager.register_test(DataFinderTest)


import unittest
from selenium import webdriver

# import sys
#
# sys.path.append('./page/admin/goods')
from DF.page.admin.goods.PublishGoods import PublishGoods

class CasePublishGoods(unittest.TestCase):

    @classmethod
    def setUpClass(self):

        self.driver = webdriver.Chrome()

        self.publishGoods = PublishGoods(self.driver)

        self.url1 = 'http://admin.joy.qa.psf-dev.com/admin/goods/delivery'

    def testPublishGoods(self):
        self.publishGoods.open(self.url1)

        self.publishGoods.select_publish_status()

        self.publishGoods.click_search_btn()

        self.publishGoods.select_goods()

        self.assertEqual(self.publishGoods.geturl(),'http://admin.joy.qa.psf-dev.com/admin/goods/delivery')

    @classmethod
    def tearDownClass(self):
        self.driver.quit()

if __name__ == '__main__':

    unittest.main()


import kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from collections import namedtuple

kivy.require("1.11.1")  # replace with your current kivy version !
UserTuple = namedtuple("UserTuple", ["text", "value"])

class UserTypes:
    X = UserTuple("X", 1)
    O = UserTuple("O", -1)

class User:
    def __init__(self, user_tuple):
        self.text = user_tuple.text
        self.value = user_tuple.value

class Square(Button):
    def __init__(self, row, column, *args, **kwargs):
        self.value = 0
        self.row = row
        self.column = column
        super().__init__(*args, **kwargs)

class MyApp(App):
    def __init__(self, *args, **kwargs):
        self._gamestate = []
        self._first_user = User(UserTypes.X)
        self._second_user = User(UserTypes.O)
        self._currentuserIndex = 0
        self._users = [self._first_user, self._second_user]
        self.winner = False
        super().__init__(*args, **kwargs)

    def build(self):
        layout = self.generate_layout()
        return layout

    def generate_layout(self):
        layout = GridLayout(cols=3)
        for i in range(3):
            self._gamestate.append([])
            for j in range(3):
                square = Square(row=i, column=j)
                self._gamestate[i].append(square)
                layout.add_widget(square)
                square.bind(on_press=self.click_button)
        return layout

    def click_button(self, instance):
        # if this square has already been clicked
        if instance.value:
            return
        # If there is already a winner
        if self.winner:
            self.stop()
            return

        instance.text = self.get_current_user().text
        instance.value = self.get_current_user().value
        print(f"r,c: {instance.row}, {instance.column}")
        # switch user
        self._switch_users()
        self.print_state()
        self.win_check()

    def _switch_users(self):
        self._currentuserIndex += 1
        self._currentuserIndex %= len(self._users)

    def get_current_user(self):
        return self._users[self._currentuserIndex]

    def print_state(self):
        for i in self._gamestate:
            for j in i:
                print(f"{j.value:>3}", end=" ")
            print()

    def sum_squares(self, squares):
        total = 0
        for s in squares:
            total += s.value
        return total

    ### Make a list that is the first item from 3 lists
    def multilist_getter(self, lists, offset, step):
        for sublist in lists:
            yield sublist[offset]
            offset += step

    def win_check(self):
        gs = self._gamestate
        results = []

        # row results
        for i in range(3):
            results.append(self.sum_squares(gs[i]))

        # column results
        for i in range(3):
            results.append(self.sum_squares(self.multilist_getter(gs, i, 0)))

        # diagonal results
        results.append(self.sum_squares(self.multilist_getter(gs, 0, 1)))
        results.append(self.sum_squares(self.multilist_getter(gs, 2, -1)))

        if 3 in results:
            print('-- x wins')
            self.winner = True
        elif -3 in results:
            print('-- o wins')
            self.winner = True
        else:
            print('-- no winner')

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


import sys
from os import listdir
from os.path import isfile, join

import numpy as np
import matplotlib.pylab as plt

if __name__ == "__main__":
    data_path = sys.argv[1]
    image_width = int(sys.argv[2])
    image_height = int(sys.argv[3])

    data_files = []
    for f in listdir(data_path):
        if isfile(join(data_path, f)):
            data_files.append(join(data_path, f))

    fig, ax = plt.subplots()
    for data_file in data_files:
        data = np.loadtxt(open(data_file, "r"), delimiter=",")
        track = np.array([data[:, 0], data[:, 1]]).T
        plt.plot(track[:, 0], track[:, 1])

    # ax.suptitle("Feature Track")
    ax.set_xlim([0, image_width])
    ax.set_ylim([image_height, 0])
    ax.xaxis.tick_top()
    plt.show()


import os
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from matplotlib import pyplot as plt
from sklearn.metrics import confusion_matrix
import numpy as np

def augment(points, label):
    # jitter points
    points += tf.random.uniform(points.shape, -0.005, 0.005, dtype=tf.float64)
    # shuffle points
    points = tf.random.shuffle(points)
    return points, label

def save_prediction_image(model, test_dataset, class_map, log_dir):
    print('Saving prediction image...')

    data = test_dataset.take(1)

    points, labels = list(data)[0]
    points = points[:8, ...]
    labels = labels[:8, ...]

    # run test data through model
    preds = model.predict(points)
    preds = tf.math.argmax(preds, -1)

    points = points.numpy()

    # plot points with predicted class and label
    fig = plt.figure(figsize=(15, 10))
    for i in range(8):
        ax = fig.add_subplot(2, 4, i + 1, projection="3d")
        ax.scatter(points[i, :, 0], points[i, :, 1], points[i, :, 2])
        ax.set_title(
            "pred: {:}, label: {:}".format(
                class_map[preds[i].numpy()], class_map[labels.numpy()[i]]
            )
        )
        ax.set_axis_off()
    plt.savefig(log_dir+'prediction.png')
    plt.close()

def save_confusion_matrix(model, validation_points, validation_label, log_dir):
    pred_scores = model.predict(validation_points)
    preds = tf.math.argmax(pred_scores, -1)
    mat = confusion_matrix(validation_label, preds)
    np.savetxt(log_dir+'confusion_matrix.txt', mat, fmt='%d', delimiter='\t')


from binarytree import BinaryTreeNode

def get_next_node(node):
    """ Find the next node (in respect of in-order) of `node`  """

    if node.right_child is not None:
        # First case: ``node`` has right child, the next node is in the subtree
        # rooted at the right child, and it is leftmost node in this subtree.
        current_node = node.right_child
        while current_node.left_child is not None:
            current_node = current_node.left_child
        return current_node
    else:
        # Second case: The next node is (grand)parent, which is the first node
        # to the right of `node`
        current_node = node
        while current_node.parent is not None:
            if current_node.parent.left_child == current_node:
                return current_node.parent
            current_node = current_node.parent

def test_1():
    from operator import attrgetter
    tree = BinaryTreeNode(3,
                   BinaryTreeNode(1, BinaryTreeNode(0), BinaryTreeNode(2)),
                   BinaryTreeNode(6,
                                  BinaryTreeNode(4, None, BinaryTreeNode(5)),
                                  BinaryTreeNode(7)))
    nodes = list(tree.inorder())
    assert nodes == sorted(nodes, key=attrgetter('data'))

    expected_next_nodes = nodes[1:] + [None]

    for node, next_node in zip(nodes, expected_next_nodes):
        assert get_next_node(node) is next_node


from django.conf import settings
import thriftpy

# Caches modules for faster multi-loading
_cached_modules = {}

def load_module(key='default'):
    """Loads a Python module to use Thrift defined structures and types

    :param key: The MANIFOLD settings key to use for configuration loading
    :return: A Python module that has the Thrift types/structs defined within it
    """
    thrift = settings.MANIFOLD[key]
    if key in _cached_modules:
        return _cached_modules[key]
    module = thriftpy.load(
        thrift['file'],
        module_name=thrift['file'].replace('.', '_')
    )
    _cached_modules[key] = module
    return module

def load_service(key='default'):
    """Load a service using a MANIFOLD settings config

    :param key: which MANIFOLD settings config key to use
    :return: Python class of Thrift service desired
    """
    module = load_module(key)
    return getattr(module, settings.MANIFOLD[key]['service'])