from torch_geometric.data import Data
import matplotlib.pyplot as plt
from borders import Point, convexHull
import openmesh
import numpy as np
from functions import area, f1, f2, f3, read_obj, write_obj
from problem import Problem
from evolution import Evolution

#Leer archivo .obj
vertices, faces=read_obj("/Users/isabella/Desktop/Universidad/QuintoSemestre/Optimizacion_II/Proyecto/Caras 3D/Final/Hombre.obj")

#Buscar puntos del borde
points=[]
x=[]
y=[]
z=[]

for i in range(len(vertices)):
    vertices[i][1], vertices[i][2] = vertices[i][2], vertices[i][1]
    points.append(Point(vertices[i][0], vertices[i][1]))
    x.append(vertices[i][0])
    y.append(vertices[i][1])
    z.append(vertices[i][2])

#Encontrar los puntos que están en el borde
border=convexHull(points,len(points))

xb=[]
yb=[]
for i in range(len(border)):
    xb.append(points[border[i]].x)
    yb.append(points[border[i]].y)
    #print(border[i], points[border[i]].x, points[border[i]].y)

#BORDE: 9786 9787 9725 4094 9892 9688 9909 9935 9990 9697 9953 9860 2389 9666

p1=x.index(max(x))
p2=x.index(min(x))
p3=y.index(max(y))
p4=y.index(min(y))

#Area malla original
initial_area=0
for i in range(len(faces)):
    t=[vertices[faces[i][0]], vertices[faces[i][1]], vertices[faces[i][2]]]
    initial_area+=area(t)

print(initial_area)

#Agregar puntos fijos al final
fp=[9786, 9787, 9725, 4094, 9892, 9688, 9909, 9935, 9990, 9697, 9953, 9860, 2389, 9666]
fixed_vertices=vertices[fp]
new_vertices=np.delete(vertices, fp, 0)
vertices=np.concatenate((new_vertices, fixed_vertices))

#NSGA-II función 2: error en el área superficial
problem1 = Problem(num_of_variables=2, objectives=[f1, f2], variables_range=vertices, initial_area=initial_area)
evo1 = Evolution(problem1, num_of_generations=100, num_of_individuals=50, crossover_param=0.5, mutation_prob=0.01, mutation_param=0.05)
evol1 = evo1.evolve()

for i in range(len(evol1)-1):
    func=[j.objectives for j in evol1[i]]

    function1=[k[0] for k in func]
    function2=[k[1] for k in func]

    plt.scatter(function1, function2, label="Frente "+str(i+1))

plt.xlabel('Cantidad de triángulos', fontsize=15)
plt.ylabel('Error del área superficial', fontsize=15)
plt.legend()
plt.title('Frontera de Pareto', fontsize=20)

plt.show()

print('vert', len(evol1[0][0].features[0]), 'triang', len(evol1[0][0].features[1].simplices))
print('f1', evol1[0][0].objectives[0], 'f2', evol1[0][0].objectives[1])

write_obj(evol1[0][0].features[0], evol1[0][0].features[1].simplices, '/Users/mariajosebernal/Documents/EAFIT/2022-2/Optimización/Proyecto/Caras 3D/Final/HombreNuevo1.obj')

#NSGA-II función 3: error en los valores de las alturas
problem2 = Problem(num_of_variables=2, objectives=[f1, f3], variables_range=vertices, initial_area=initial_area)
evo2 = Evolution(problem2, num_of_generations=100, num_of_individuals=50, crossover_param=0.5, mutation_prob=0.01, mutation_param=0.05)
evol2 = evo2.evolve()

for i in range(len(evol2)-1):
    func=[j.objectives for j in evol2[i]]

    function1=[k[0] for k in func]
    function2=[k[1] for k in func]

    plt.scatter(function1, function2, label="Frente "+str(i+1))

plt.xlabel('Cantidad de triángulos', fontsize=15)
plt.ylabel('Error', fontsize=15)
plt.legend()
plt.title('Frontera de Pareto', fontsize=20)

plt.show()

print('vert', len(evol2[0][0].features[0]), 'triang', len(evol2[0][0].features[1].simplices))
print('f1', evol2[0][0].objectives[0], 'f2', evol2[0][0].objectives[1])

write_obj(evol2[0][0].features[0], evol2[0][0].features[1].simplices, '/Users/mariajosebernal/Documents/EAFIT/2022-2/Optimización/Proyecto/Caras 3D/Final/HombreNuevo2.obj')

Simplificación de mallas 3D con algoritmos genéticos/Código/main.py


from datetime import datetime
import numpy as np
import pickle;

from flask import Flask, request, jsonify
from flask import render_template
app = Flask(__name__)

def hello():
    return "Hello, World!"

@app.route("/")
@app.route('/home')
def home():
    return render_template(
        'index.html',
        title = '''Shu's Home Page''',
        year = datetime.now().year,
    )

@app.route('/calculation')
def calculation():
    return render_template(
        'calculation.html',
        title = '''Calculation''',
        year = datetime.now().year,
    )

@app.route('/knn')
def knn():
    return render_template(
        'knn.html',
        title = '''KNN''',
        year = datetime.now().year,
    )

@app.route('/about')
def about():
    return render_template(
        'about.html',
        title = '''About Shu''',
        year = datetime.now().year,
    )

@app.route('/add_model')
def add_model():
   value1 = request.args.get('val1', type = float);
   value2 = request.args.get('val2', type = float);
   return jsonify(data = value1 + value2);

@app.route('/multi_model')
def multi_model():
   value1 = request.args.get('val1', type = float);
   value2 = request.args.get('val2', type = float);
   return jsonify(data = value1 * value2);

@app.route('/knn_model')
def knn_model():
   value1 = request.args.get('val1', type = float);
   value2 = request.args.get('val2', type = float);

   data = np.ndarray(shape = (1, 2), dtype = float);
   data[0, 0] = value1;
   data[0, 1] = value2;

   print(data);

   knn_model = pickle.load(open('static/model/knn_model.pkl', 'rb'));
   result = knn_model.predict(data);

   if result[0] == 1:
       class_color = 'Yellow';
   elif result[0] == 0:
        class_color = 'Purple';

   del knn_model;

   return jsonify(data = class_color);


from mech.actuator import *
from lib.utils import *
from datetime import datetime

"""
Defines functions to control, calibrate, and monitor actuators.
One layer up from direct actuator functions

"""

def current_readings(sensor=None, rate_units=['s', 'sec']):

    """
    current_readings -  provides current state of system.
      scale mass (g), pump rate (steps/s), time (__), pressure (atm)

    :param sensor: specifies which sensor to read
         must be one of ['mass', 'rate', 'time', 'pressure', 'valve']
         if None, returns all readings as dict
    :return: dict of readings if sensor=None,
             else returns float
    """

    current_data = dict()

    sensors = {'mass': scale,
               'rate': lambda: pump()/60, #(60 for min->s)
               'time': datetime.now,
               'pressure': pressure,
               'valve': valve}

    for s, actuator in sensors.items():
        current_data[s] = actuator()

    if sensor:
        # provide measured value single sensor specfied
        if sensor in sensors.keys():
             current_data = sensors[sensor]()
        else:
            # invalid sensor specified; raise error/report in log
            current_data = None

    # if steps/second not desired pump rate units, convert accordingly:
    if (rate_units != ['s', 'sec'] and sensor is None) \
        or (rate_units != ['s', 'sec'] and sensor == 'rate'):

        # unpack pump rate
        if sensor:
            rate_0 = current_data
        else:
            rate_0 = current_data['rate']

        # convert pump rate from steps/sec
        rate = convert_rate(rate_0, ['s', rate_units[0]], ['sec',rate_units[1]])

        # repack pump rate
        if sensor:
            current_data = rate
        else:
            current_data['rate'] = rate

    return current_data

def attenuate_pump_rate(rate, stop_rate=None, is_lowerbound=False):

    """
    attenuate_pump_rate - checks if pump adjustment will exceed engineering limits
       or recipe stage boundaries. Attenuates rate by reducing to boundary value.
    :param rate: int - current pump rate in steps/s
    :param stop_rate: int - recipe end rate for pump in steps/s
    :param is_lowerbound" bool - indicates rate decreasing e.g. lower bound threshold
    :return: 2-list
      :rate: float cleaned up rate value
      :rate_limit_hit: bool - Indicates attenuation so stage not stuck in infinite loop trying to reach
        out of bounds stop value
    """

    # Indicates if stop_value exceeded
    rate_limit_hit = False

    # Clean up pump rate if zero (e.g.stopped) or negative (e.g. pumping in reverse)
    if rate < MIN_PUMP_RATE:

        if rate < 0:
            #if in reverse, stop pump
            rate=0
        else:

            # if non-negative but lower than minimum readjust to nominal rate
            rate = MIN_PUMP_RATE
        rate_limit_hit = True

        #raise mass recipe discrepency error and note in log
        #...

    # Reduce pump rate if exceeds mechanical pump speed threshold
    if rate > MAX_PUMP_RATE:

        rate = MAX_PUMP_RATE
        rate_limit_hit = True

        #raise mass recipe discrepency error and note in log
        #...

    if stop_rate:
        # If new rate exceeds stop rate, go with max rate
        #  (or if negative rate and min)
        if (rate > stop_rate \
             and not is_lowerbound) or \
           (rate < stop_rate \
            and is_lowerbound):

            # replace rate with stop value
            rate = stop_rate
            rate_limit_hit = True

    rate_j = [rate, rate_limit_hit]

    return rate_j

def pump_calibration():

    """
    Calibrate constant to calculate pump mass/step ratio
      using range of pump speeds to for feed solution viscocity
    """
    #...

    return step_constant

def max_pressure(bioreactor_type=DEFAULT_REACTOR_MODEL):

    """
    max_pressure - returns maximum pressure (atm) safely allowed by vessle

    :return: maximum safe pressure for given reactor.

    """

    bioreactor_specs = {'ficticfeed100':{'p_max':100}}

    specs = bioreactor_specs[bioreactor_type]
    p_max  = specs['p_max']

    return p_max

def pump_prime(prime_duration=5):
    """
     Fill dead volume of pump with glucose feedstock
      by running pump at max rate offline for set number of seconds (prime_duration)

    :param prime_duration: int time (seconds) to run pump at max speed
    :return: None
    """

    #  Priming program will depend on type of pump:
    #    peristaltic: high speed until stock starts losing weight. Continue for remainder of tubing
    #    diaphragm: high speed for several seconds.
    #    syringe: Fill to capacaity of pump.

    valve(0)
    pump(MAX_PUMP_RATE)
    sleep(prime_duration)
    pump(0)
    valve(1)

    return None

def is_feedempty(sensor_data):

    """
    Checks if glucose feed ran out.
      If scale stops decreasing while pump is going, attempts prime
      monitors if scale starts going down.
    """

    # take derivative of scale readings wrt time

    # compare to pump readings

    # if pump rate >> 0 and scale == 0 then prime

        # check scale again

        # if scale still unchanging, return True

    pass

def check_feed_contamination(sensor_data):

    """
    Checks if outgassing or foam from over-pressured vessle
    is traveling up feedstock tubing and contaminating glucose container

    """

    pass

def compare_scale_pump_pressure(sensor_data):

    """
    Checks if mass scale change, pump rate, and pressure data make physical sense
    Comparing rates of change with eachother at given times
    """

    pass

def vessle_conditions_good( maxpressure=True,
                            sensor_consistency=False,
                            feedempty=False,
                            contamination=False,
                            sensor_readings=None):

    """
    Checks multiple experimental conditions and egnineering controls at once
    Returns True if all pass, False if any fail
    """

    # Instantate list
    checks = []

    # Check if max pressure exceeded
    if maxpressure:
        goodpressure = pressure() < max_pressure()
        checks.append(goodpressure)

    # Check if atm, pump, and mass rate of changes are in agreement w/ eachother
    if sensor_consistency:
        consistent = compare_scale_pump_pressure(sensor_readings)
        checks.append(consistent)

    # Check if feedstock ran out
    if feedempty:
        feed = is_feedempty(sensor_readings)
        checks.append(feed)

    # Check if feedstock has evidence of contamination
    if contamination:
        contam = check_feed_contamination(sensor_readings)
        checks.append(contam)

    return all(checks)


"""メインモジュール."""

import argparse

from base_solver import BaseSolver
from chat_gpt3_solver import ChatGPT3Solver
from environment import NormalMachine
from epsilon_greedy_solver import EpsilonGreedySolver
from random_solver import RandomSolver
from stablelm_solver import StableLMSolver

def parse_args() -> argparse.Namespace:
    """コマンドライン引数を解析する.

    Returns:
        argparse.Namespace: 解析された引数オブジェクト
    """
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "solver_type",
        type=str,
        choices=["random", "epsilon_greedy", "chat_gpt3", "stable_lm"],
    )
    return parser.parse_args()

if __name__ == "__main__":
    args = parse_args()
    solver_type = args.solver_type
    machine_list = [
        NormalMachine(mean=10, stddev=5),
        NormalMachine(mean=20, stddev=5),
        NormalMachine(mean=30, stddev=5),
    ]
    TRIAL_NUM = 100
    solver: BaseSolver
    if solver_type == "random":
        solver = RandomSolver(len(machine_list))
    elif solver_type == "epsilon_greedy":
        solver = EpsilonGreedySolver(len(machine_list))
    elif solver_type == "chat_gpt3":
        solver = ChatGPT3Solver(len(machine_list), TRIAL_NUM)
    elif solver_type == "stable_lm":
        solver = StableLMSolver(len(machine_list), TRIAL_NUM)
    else:
        raise ValueError(f"Unknown solver_type: {solver_type}")
    reward_sum = 0
    for _ in range(TRIAL_NUM):
        selected = solver.select()
        reward = machine_list[selected].sample()
        solver.update(selected, reward)
        print(f"selected: {selected}, reward: {reward}")
        reward_sum += reward

    reward_average = reward_sum / TRIAL_NUM
    print(f"reward_average: {reward_average:.1f}")


from vector_math import *
from collections import OrderedDict
from pyquaternion import Quaternion
from datetime import datetime

import numpy
import pandas as pd
import warnings
import logging
import time

warnings.filterwarnings("ignore")
GLOBAL_LOGGING_LEVEL = logging.INFO

class KeyT:
    def __init__(self):
        self.value = ''

    def on_press(self, key):
        self.value = str(key).replace('\'', '')

    def on_release(self, _):
        self.value = ''

def get_date_time():
    return datetime.now().strftime('%Y_%m_%d_%H_%M_%S')

def create_console_logger(name, level=None):
    level = GLOBAL_LOGGING_LEVEL if level is None else level

    logger = logging.getLogger(name)
    logger.setLevel(level)
    ch = logging.StreamHandler()
    ch.setLevel(level)

    formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(funcName)s @%(name)s : %(message)s')
    ch.setFormatter(formatter)
    logger.addHandler(ch)
    logger.propagate = False

    return logger

def truncate_float(number, decimal_places):
    return ('{0:.%sf}' % decimal_places).format(number)

def get_average_rates_body(df, limit, frequency):
    shape = (limit, 3)
    linear_velocities, angular_velocities = numpy.zeros(shape), numpy.zeros(shape)

    # get average linear and angular velocities (EARTH)
    for i in range(1, limit):
        p1 = df.loc[i - 1, ['x', 'y', 'z']].values.astype(numpy.float64)
        p2 = df.loc[i, ['x', 'y', 'z']].values.astype(numpy.float64)

        q1 = Quaternion(df.loc[i - 1, ['scalar', 'i', 'j', 'k']].values)
        q2 = Quaternion(df.loc[i, ['scalar', 'i', 'j', 'k']].values)

        linear_velocities[i] = get_average_linear_velocity(p2, p1, frequency)

        axis, angle = get_average_angular_velocity(q2, q1, frequency)
        angular_velocities[i] = axis * angle

    return linear_velocities, angular_velocities

def get_xy_velocity_model(df, frequency, limit=500):
    v, w, = get_average_rates_body(df, limit, frequency=frequency)

    input_shape = (limit, 15)
    output_shape = (limit, 6)

    X, y = numpy.zeros(input_shape), numpy.zeros(output_shape)
    action_names = ['move_forward', 'yaw_ccw', 'yaw_cw', 'hover', 'move_backward', 'move_left', 'move_right']

    limit = limit - 2
    for t0, t1 in zip(range(limit), range(1, limit)):
        selected_action = [0 if a != df.loc[t1, 'aName'] else 1 for a in action_names]

        q = Quaternion(df.loc[t0, ['scalar', 'i', 'j', 'k']].values)
        roll, pitch, yaw = to_euler_angles(q)

        X[t0] = numpy.concatenate((transform_to_body_frame(v[t0], q),
                                   transform_euler_rates_to_body(w[t0], q),
                                   [roll, pitch], selected_action))

        y[t0] = numpy.concatenate((transform_to_body_frame(v[t1], q),
                                   transform_euler_rates_to_body(w[t1], q)))

    x_columns = ['dXB', 'dYB', 'dZB', 'dRoll', 'dPitch', 'dYaw', 'roll', 'pitch'] + [i for i in action_names]
    y_columns = ['dXB', 'dYB', 'dZB', 'dRoll', 'dPitch', 'dYaw']

    return pd.DataFrame(X[:-5], columns=x_columns), pd.DataFrame(y[:-5], columns=y_columns)

class StateT:
    # if update is set to True, the environment will be able to update state whenever is needed.
    def __init__(self, update, **kwargs):
        self.prevState = None

        if 'callbacks' in kwargs:
            self.callbacks = kwargs['callbacks']
        else:
            self.callbacks = OrderedDict()
            for key in kwargs:
                self.callbacks[key] = kwargs[key]
                setattr(self, key, None if update is True else kwargs[key])

    def are_equal(self, state, margins):
        for key in state.callbacks:
            diff = abs(getattr(self, key) - getattr(state, key))
            if (numpy.greater(diff, getattr(margins, key))).any():
                return False
        return True

    # States are immutable by design, each update creates a new StateT object
    def update_state(self, agent):
        temp = StateT(update=True, callbacks=self.callbacks)
        # keep track of previous state
        temp.prevState = self

        i, keys = 0, [i for i in temp.callbacks]

        while i < len(keys):
            key = keys[i]
            try:
                setattr(temp, key, self.callbacks[key](agent=agent, partialUpdate=temp))
                i += 1
            except Exception as e:  # sanity check
                raise Exception(key + " " + str(e))

        # signal garbage collector
        temp.prevState.prevState = None

        # add a time stamp to state to indicate freshness
        temp.lastUpdate = time.time()

        return temp

    def get_keys(self):
        return [i for i in self.callbacks]

    def get_key_value_pairs(self):
        return {key: getattr(self, key) for key in self.get_keys()}

    def __hash__(self):
        return hash(tuple(tuple(getattr(self, c)) for c in self.get_keys()))


import os
from zipfile import ZipFile
from os import path
from os.path import basename
from configure import Config
config = Config()

folders_for_zipping = []

train_path = config.train_orig
folders_for_zipping.append(train_path)

train_masks_path = config.train_orig + "_masks"
folders_for_zipping.append(train_masks_path)

validation_path = config.valid_orig
folders_for_zipping.append(validation_path)

validation_masks_path = config.valid_orig + "_masks"
folders_for_zipping.append(validation_masks_path)

def add_folder_to_zip(zipObj, folderPath):
	zipObj.write(folderPath, basename(folderPath))
	for filename in os.listdir(folderPath):
		filePath = os.path.join(folderPath, filename)
		if path.isfile(filePath):
			#print("Adding file to zip: {}".format(filename))
			zipObj.write(filePath, os.path.join(basename(folderPath),basename(filePath)))

print("Zipping files... The following folders and their contents will be zipped:")
with ZipFile ("preprocessed_images.zip", 'w') as zipObj:
	for folder_to_zip in folders_for_zipping:
		print("- {}".format(folder_to_zip))
		add_folder_to_zip(zipObj, folder_to_zip)
print("Zipping files complete.")


from django.db import models

class Global(models.Model):
    name = models.CharField(max_length=200)
    projection_period = models.IntegerField(null=True, blank=True)

    def __str__(self):
        return self.name

VARIABLE_TYPES = [("Input","Input"), ("Table","Table"), ("Variable","Variable"),]
class Variable(models.Model):
    name = models.CharField(max_length=200)
    formula = models.TextField(null=True, blank=True)
    level = models.IntegerField(null=True, blank=True)
    round = models.IntegerField(default=0)
    type = models.CharField(max_length=200, choices=VARIABLE_TYPES)

    def __str__(self):
        return self.name

    def values_round(self):
        rounding = self.round
        values = self.values()
        values_rounded = []
        for x in values:
            values_rounded.append(round(x,rounding))
        return values_rounded

    def values(self):
        values = []
        for t in range(10):
            values.append(self.value(t))
        return values

    def value(self, t):
        formula = self.formula.strip()
        formula = self.remove_if(formula, t).strip()
        formula = self.replace_variables(formula, t)
        formula = self.replace_t(formula, t)
        try:
            result = eval(formula)
        except:
            result = formula
        return result

    def replace_t(self, formula, t):
        if formula[0:5] == "Error": return formula
        formula = formula.replace("t", str(t))
        return formula

    def replace_variables(self, formula, t):
        for x in self.referenced_variables():
            start = formula.find(x.name)
            if start != -1:
                start_t = formula.find("(", start)
                end_t = formula.find(")", start)
                if start_t == -1 or end_t == -1:
                    return("Error - brackets not found")
                variable_str = formula[start:end_t+1]
                time_str = formula[start_t+1:end_t]
                time_str = time_str.replace("t", str(t))
                try:
                    t = eval(time_str)
                except:
                    return(f"Error - 'Time String' couldn't be evaluated: 'Time String': '{time_str}'")
                formula = formula.replace(variable_str, str(x.value(t)))
        return formula

    def remove_if(self, formula, t):
        found = formula.find("if")
        if found == -1:
            return formula
        else:
            # Get Logic Statement
            start = found + 2
            end = formula.find(":")
            logic_statement = formula[start:end]
            logic_statement_str = logic_statement.strip()
            logic_statement_str = self.replace_t(logic_statement_str, t)
            logic_statement_result = eval_logic(logic_statement_str)
            # Get True Statement
            start = end + 2
            end = formula.find("else")
            true_statement = formula[start:end].strip()
            # Get False Statement
            start = end + 5
            end = None
            false_statement = formula[start:end]
            if logic_statement_result:
                return true_statement
            else:
                return false_statement

    def referenced_variables(self):
        referenced_variables = []
        variables = Variable.objects.all()
        for y in variables:
            found = self.formula.find(y.name)
            if found != -1: referenced_variables.append(y)
        return referenced_variables

def eval_logic(formula):
    if formula == 'True': return True
    equals = formula.find("=")
    lhs = float(formula[0:equals])
    rhs = float(formula[equals+1:])
    return lhs == rhs


from fastapi import APIRouter
from api.api_v1.endpoints import analysis, validation, inventory

## File to include all routers

api_router = APIRouter()

# Add analysis endpoints
api_router.include_router(
    analysis.router,
    prefix="/analysis",
    tags=["analysis"],
    responses={404: {"description": "Not found"}},
)

# Add validation endpoints
api_router.include_router(
    validation.router,
    prefix="/validation",
    tags=["validation"],
    responses={404: {"description": "Not found"}},
)

# Add inventory endpoints
api_router.include_router(
    inventory.router,
    prefix="/inventory",
    tags=["inventory"],
    responses={404: {"description": "Not found"}},
)


import json
from data_jps import web_scrapping, filter_status

async def Perlis_command(update, context):
    await update.message.reply_text('''Ini senarai daerah dalam /Perlis
1. /Arau
2. /Kangar
3. /Padang_Besar
''')

async def send_data(update, district):
    web_scrapping('PLS', district)
    status = ["Cetek","Normal","Waspada","Amaran","Bahaya"]
    for data in status:
        df_noti = filter_status().loc[filter_status()['Status'].isin([data])]
        result = df_noti.to_json(orient='index')
        parsed = json.loads(result)
        for p_id, p_info in parsed.items():
            print("Index ID:", p_id)
            data_to_push =f'''
ID Stesen: {parsed[p_id]['ID Stesen']}
Nama Stesen: {parsed[p_id]['Nama Stesen']}
Daerah: {parsed[p_id]['Daerah']}
Lembangan: {parsed[p_id]['Lembangan']}
Sub Lembangan: {parsed[p_id]['Sub Lembangan']}
Update sekarang: {parsed[p_id]['Update sekarang']}
Aras Air: {parsed[p_id]['Aras Air']}
Status: {parsed[p_id]['Status']}'''
            await update.message.reply_text(data_to_push)

async def Arau_command(update, context):
    await send_data(update, 'Arau')

async def Kangar_command(update, context):
    await send_data(update, 'Kangar')

async def Padang_Besar_command(update, context):
    await send_data(update, 'Padang Besar')


from callback_functions.custom_helpers import main_app,decode_token
from dash.dependencies import Output, Input, State
from pages.home_page import layout as home_page
from pages.login_page import layout as login_page
from pages.page_not_found import layout as page_not_found
import time

# app = main_app.app

c = 0

# This function updates the following
# 1 -> url2 component's pathname
# 2 -> app_output component's children
# 3 -> token component's clear_data
# It takes 2 inpiuts (1 input and 1 state)
# Input -> url1 components pathname
# State -> token components data
@main_app.app.callback(
    Output("url2","pathname"),
    Output("app_output","children"),
    Output("token","clear_data"),
    Input("url1","pathname"),
    State("token","data"))
def validate_token_and_update_screen(pathname,token):
    global c
    c+=1
    print(f'''----------------------
            Loop number = {c}
            pathname =========== {pathname}
            ---------------------------''')
    try:
        payload = decode_token(token)
        session_not_over = payload['session_end_time'] > int(time.time())
        if session_not_over:
            main_app.current_url = pathname
            if(pathname == main_app.environment_details['home_page_link'] or pathname == main_app.environment_details['login_page_link']):
                print("1.1--------------------")
                print(f"=========> {main_app.current_url}")
                return main_app.environment_details['home_page_link'],home_page,False
            elif(pathname == main_app.environment_details['logout_page_link']):
                print("1.2--------------------")
                main_app.connector = ""
                return main_app.environment_details['logout_page_link'],login_page,True
            else:
                print("1.3--------------------")
                return pathname,page_not_found,False
        else:
            print("1.4-------------------- Session over login again")
            return main_app.environment_details['login_page_link'],login_page,False
    except Exception as e:
        print("1.5 ---------------------Not a valid Token")
        # return login_page, False
        return main_app.environment_details['login_page_link'],login_page, False


from typing import Tuple
from primitives import *

# Game settings
screen_size: tuple = (100, 100)
screen_title: str = "JorCademy Engine"
background_color: tuple = (0, 0, 0)
__draw_buffer: list = []
audio_channel_count: int = 0
screen = pygame.display.set_mode((100, 100))

# Initialize audio component
pygame.mixer.init()

# Create type aliases
color = Tuple[int, int, int]

# ==== Keyboard input ====

__key_status = {}

# Get whether a specific key is down
def is_key_down(key: str) -> bool:
    if key in __key_status:
        return __key_status[key]
    else:
        return False

# ==== Mouse input ====

__mouse_status = {}
__scroll_up: bool = False
__scroll_down: bool = False
mouse_position: (int, int) = (0, 0)

# Get whether a specific mouse button is down
def is_mouse_button_down(button: str) -> bool:
    if button in __mouse_status:
        return __mouse_status[button]
    else:
        return False

def is_scrolling_up() -> bool:
    return __scroll_up

# Get whether the player is scrolling down
def is_scrolling_down() -> bool:
    return __scroll_down

# Change screen size
def screen(width: int, height: int) -> None:
    global screen_size
    screen_size = (width, height)

# Change screen title
def title(t: str) -> None:
    global screen_title
    screen_title = t

# Change app icon
def icon(name: str) -> None:
    app_icon = pygame.image.load("./assets/" + name)
    pygame.display.set_icon(app_icon)

# Change screen background color
def backdrop(c: color) -> None:
    global background_color
    __draw_buffer.clear()
    background_color = c

# Draw a circle
def ellipse(c: color, x: float, y: float, w: float, h: float, rotation=0) -> None:
    e = Ellipse(c, x, y, w, h, rotation)
    __draw_buffer.append(e)

# Draw a rectangle
def rect(c: color, x: float, y: float, w: float, h: float, rotation=0) -> None:
    r = Rectangle(c, x, y, w, h, rotation)
    __draw_buffer.append(r)

# Draw a string of text
def text(content: str, size: int, c: color, x: float, y: float, font="Nunito", rotation=0) -> None:
    # Fetch font
    try:
        font = pygame.font.Font("./assets/" + font, size)
    except:
        font = pygame.font.SysFont(font, size)

    # Draw font
    text_surface = font.render(content, True, c)
    w, h = font.size(content)
    t = Text(content, text_surface, c, x, y, w, h, size, font, rotation)
    __draw_buffer.append(t)

# Load an image
def load_image(path: str) -> Image:
    full_path = "assets/" + path
    try:
        return Image(pygame.image.load(full_path).convert_alpha())
    except pygame.error as e:
        print(f"Error loading image {full_path}: {e}")

# Draw an image
def image(img: Image, x: float, y: float, scale=1.0, flipped=False, rotation=0) -> None:
    surface = img.image
    i = Image(surface, scale, x, y, flipped, rotation)
    __draw_buffer.append(i)

# Load new sound
def load_sound(path: str):
    sound = Exception
    try:
        sound = pygame.mixer.Sound(path)
    except:
        print("Error: Audio could not be loaded.")
    return sound

# Wait for new action
def sleep(msec: int):
    pygame.time.wait(msec)


from django.urls import path, re_path
from . import views
from users import views as user

urlpatterns = [
    path("index/", views.index, name="index"),

    # API Routes
    path("tracker_dashboard/<str:board>/<str:search>/", views.tracker_dashboard, name="board"),
    path("tracker_dashboard/<str:board>/<str:search>/<str:search_value>", views.tracker_dashboard, name="search_board"),
    path("tracker_dashboard/<str:client_id>", views.tracker_dashboard, name="client"),
    path("product_view/<str:product_id>", views.product_view, name="product"),
    path("client_view/<str:client_id>", views.client_view, name="client_view"),
    path("usecase_view/<str:usecase_id>", views.usecase_view, name="usecase"),
    path("create_product", views.create_product, name="create_product"),
    path("create_client", views.create_client, name="create_client"),
    path("create_usecase", views.create_usecase, name="create_usecase"),
    path("get_status/<str:board>", views.get_status, name="get_status"),
    path("delete_product", views.delete_product, name="delete_product"),
    path("delete_client", views.delete_client, name="delete_client"),
    path("delete_usecase", views.delete_usecase, name="delete_usecase"),
    path("logout", user.logout_user, name="logout")
]


import tempfile
import shutil

from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.cache import cache
from django.test import Client, TestCase, override_settings
from django.urls import reverse
from posts.models import Group, Post, User, Comment, Follow
from posts.forms import PostForm

User = get_user_model()
TEMP_MEDIA_ROOT = tempfile.mkdtemp(dir=settings.BASE_DIR)

@override_settings(MEDIA_ROOT=TEMP_MEDIA_ROOT)
class PostPagesTests(TestCase):
    @classmethod
    def setUpClass(cls):
        """Создание записи в БД"""
        super().setUpClass()
        cls.user = User.objects.create_user(username='authorized')
        cls.group = Group.objects.create(
            title='Тестовая группа',
            slug='test_slug',
            description='Тестовое описание',
        )
        cls.post = Post.objects.create(
            author=cls.user,
            group=cls.group,
            text='Тестовый пост',
        )

    @classmethod
    def tearDownClass(cls):
        super().tearDownClass()
        # Метод shutil.rmtree удаляет директорию и всё её содержимое
        shutil.rmtree(TEMP_MEDIA_ROOT, ignore_errors=True)

    def setUp(self):
        cache.clear()
        self.authorized_client = Client()
        self.authorized_client.force_login(self.user)

    def test_pages_uses_correct_template(self):
        """URL-адрес использует соответствующий шаблон"""
        templates_pages_names = {
            reverse('posts:index'): 'posts/index.html',
            reverse('posts:group',
                    kwargs={'slug': self.group.slug}): 'posts/group_list.html',
            reverse('posts:profile',
                    kwargs={'username':
                            self.user.username}): 'posts/profile.html',
            reverse('posts:post_detail',
                    kwargs={'post_id':
                            self.post.pk}): 'posts/post_detail.html',
            reverse('posts:post_edit',
                    kwargs={'post_id':
                            self.post.id}): 'posts/create_post.html',
            reverse('posts:post_create'): 'posts/create_post.html',
        }

        for reverse_name, template in templates_pages_names.items():
            """типы полей формы в словаре context соответствуют ожиданиям"""
            with self.subTest(reverse_name=reverse_name):
                response = self.authorized_client.get(reverse_name)
                self.assertTemplateUsed(response, template)

    def test_cache_context(self):
        '''Проверка кэширования страницы index'''
        before_create_post = self.authorized_client.get(
            reverse('posts:index'))
        first_item_before = before_create_post.content
        Post.objects.create(
            author=self.user,
            text='Проверка кэша',
            group=self.group)
        after_create_post = self.authorized_client.get(reverse('posts:index'))
        first_item_after = after_create_post.content
        self.assertEqual(first_item_after, first_item_before)
        cache.clear()
        after_clear = self.authorized_client.get(reverse('posts:index'))
        self.assertNotEqual(first_item_after, after_clear)

    def test_profile_page_show_correct_context(self):
        """Шаблон profile сформирован с правильным контекстом."""
        response = self.authorized_client.get(
            reverse('posts:profile',
                    kwargs={'username': PostPagesTests.user}))
        self.assertEqual(response.context['page_obj'][0],
                         PostPagesTests.post)
        context_author = response.context.get('author')
        self.assertEqual(context_author, self.post.author)

    def test_post_detail_page_show_correct_context(self):
        """Шаблон post_detail сформирован с правильным контекстом."""
        response = self.authorized_client.get(
            reverse('posts:post_detail', kwargs={'post_id': self.post.id}))
        post_text_0 = {response.context['post'].text: 'Тестовый пост',
                       response.context['post'].group: self.group,
                       response.context['post'].author: self.user.username}
        for value, expected in post_text_0.items():
            self.assertEqual(post_text_0[value], expected)

    def test_post_create_page_show_correct_context(self):
        """Шаблон post_create сформирован с правильным контекстом."""
        response = testing_pages = (
            f'/posts/{PostPagesTests.post.pk}/edit/',
            '/create/',
        )
        for url in testing_pages:
            with self.subTest(url=url):
                response = self.authorized_client.get(url)
                self.assertIsInstance(
                    response.context['form'],
                    PostForm
                )
                if 'edit' in url:
                    self.assertEqual(
                        response.context['is_edit'],
                        True
                    )
                    self.assertEqual(
                        response.context['post'],
                        PostPagesTests.post
                    )

    def test_paginator(self):
        bulk_posts = []
        for i in range(12):
            bulk_posts.append(Post(
                text=f'Тестовый пост {i}',
                author=PostPagesTests.user,
                group=PostPagesTests.group)
            )
        Post.objects.bulk_create(bulk_posts)

        reverse_name_posts = [
            reverse('posts:index'),
            reverse('posts:profile',
                    kwargs={'username': f'{self.user.username}'}),
            reverse('posts:group',
                    kwargs={'slug': f'{self.group.slug}'}),
        ]

        for reverse_name in reverse_name_posts:
            with self.subTest(reverse_name=reverse_name):
                response = self.client.get(reverse_name)
                self.assertEqual(
                    len(response.context['page_obj']), 10,
                    'Количество постов на первой странице не равно десяти'
                )

class CommentTest(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.user = User.objects.create_user(username='auth1')
        cls.user2 = User.objects.create_user(username='auth2')

    def setUp(self):
        self.guest_client = Client()
        self.authorized_client = Client()
        self.authorized_client.force_login(self.user)
        self.group = Group.objects.create(title='Тестовая группа',
                                          slug='test_group')
        self.post = Post.objects.create(text='Тестовый текст',
                                        group=self.group,
                                        author=self.user)

    def test_post_detail_page_show_correct_context(self):
        """Шаблон post_detail сформирован с
           правильным контекстом комментария."""
        self.comment = Comment.objects.create(post_id=self.post.id,
                                              author=self.user,
                                              text='Тестовый коммент')
        response = self.authorized_client.get(
            reverse('posts:post_detail', kwargs={'post_id': self.post.id}))
        comments = {response.context['comments'][0].text: 'Тестовый коммент',
                    response.context['comments'][0].author: self.user.username
                    }
        for value, expected in comments.items():
            self.assertEqual(comments[value], expected)
            self.assertTrue(response.context['form'], 'форма получена')

class FollowViewsTest(TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.user = User.objects.create_user(username='auth1')
        cls.user2 = User.objects.create_user(username='auth2')
        cls.author = User.objects.create_user(username='someauthor')

    def setUp(self):
        self.guest_client = Client()
        self.authorized_client = Client()
        self.authorized_client.force_login(FollowViewsTest.user)
        self.authorized_client2 = Client()
        self.authorized_client2.force_login(FollowViewsTest.user2)

    def test_user_follower_authors(self):
        '''Посты доступны подписчику'''
        count_follow = Follow.objects.filter(user=FollowViewsTest.user).count()
        data_follow = {'user': FollowViewsTest.user,
                       'author': FollowViewsTest.author}
        url_redirect = reverse(
            'posts:profile',
            kwargs={'username': FollowViewsTest.author.username})
        response = self.authorized_client.post(
            reverse('posts:profile_follow', kwargs={
                'username': FollowViewsTest.author.username}),
            data=data_follow, follow=True)
        new_count_follow = Follow.objects.filter(
            user=FollowViewsTest.user).count()
        self.assertTrue(Follow.objects.filter(
                        user=FollowViewsTest.user,
                        author=FollowViewsTest.author).exists())
        self.assertRedirects(response, url_redirect)
        self.assertEqual(count_follow + 1, new_count_follow)

    def test_user_unfollower_authors(self):
        '''Посты не доступны не подписчику '''
        count_follow = Follow.objects.filter(
            user=FollowViewsTest.user).count()
        data_follow = {'user': FollowViewsTest.user,
                       'author': FollowViewsTest.author}
        url_redirect = ('/auth/login/?next=/profile/'
                        f'{self.author.username}/unfollow/')
        response = self.guest_client.post(
            reverse('posts:profile_unfollow', kwargs={
                'username': FollowViewsTest.author}),
            data=data_follow, follow=True)
        new_count_follow = Follow.objects.filter(
            user=FollowViewsTest.user).count()
        self.assertFalse(Follow.objects.filter(
            user=FollowViewsTest.user,
            author=FollowViewsTest.author).exists())
        self.assertRedirects(response, url_redirect)
        self.assertEqual(count_follow, new_count_follow)

    def test_follower_see_new_post(self):
        '''У подписчика появляется новый пост избранного автора.
           А у не подписчика его нет'''
        new_post_follower = Post.objects.create(
            author=FollowViewsTest.author,
            text='Текстовый текст')
        Follow.objects.create(user=FollowViewsTest.user,
                              author=FollowViewsTest.author)
        response_follower = self.authorized_client.get(
            reverse('posts:follow_index'))
        new_posts = response_follower.context['page_obj']
        self.assertIn(new_post_follower, new_posts)

    def test_unfollower_no_see_new_post(self):
        '''У не подписчика поста нет'''
        new_post_follower = Post.objects.create(
            author=FollowViewsTest.author,
            text='Текстовый текст')
        Follow.objects.create(user=FollowViewsTest.user,
                              author=FollowViewsTest.author)
        response_unfollower = self.authorized_client2.get(
            reverse('posts:follow_index'))
        new_post_unfollower = response_unfollower.context['page_obj']
        self.assertNotIn(new_post_follower, new_post_unfollower)


#!/usr/bin/env python
# -*-coding:utf-8-*-
# Author: nomalocaris <nomalocaris.top>
""""""
from __future__ import (absolute_import, unicode_literals)
import numpy as np
from tools import plot_several_curve, convergence_judge

# set the parm
N = 500  # num of agents
sigma = 0.5
init_value_range = (-10, 10)
c = 10
beta = 0.5
# q in [1-sigma, 1]
q = np.random.uniform(1 - sigma, 1)

# cal the privacy budget
epsilon = q / (c * q + sigma - 1)
# init agant vector
theta_vec = np.random.randint(init_value_range[0], init_value_range[1], N)
tot_theta_vec = theta_vec.copy()
# init time
t = 0
t_seq = [t]

while not convergence_judge(theta_vec):
    # client send msg which added laplace noise
    eta_vec = np.random.laplace(0, c*q**t, N)
    x_vec = theta_vec + eta_vec
    print(eta_vec)
    # server cal and update itself
    y_vec = np.mean(x_vec)
    # client update itself
    theta_vec = (1 - sigma) * theta_vec + sigma * y_vec
    # record the variation of agent states
    tot_theta_vec = np.vstack((tot_theta_vec, theta_vec))

    # update t
    t += 1
    t_seq.append(t)

# set the num of curve which want to be plot
curve_num = 8
y = []
for i in range(curve_num):
    y.append(tot_theta_vec[:, i])
# plot the convergance curve
plot_several_curve(
    x=t_seq,
    y=y,
    line_num=curve_num,
    label_prefix='θ',
    title='Convergance curve(σ=%.3f, q=%.3f, ε=%.3f)' % (sigma, q, epsilon),
    xlabel='T',
    ylabel='θi(T)'
)


import gymnasium as gym
from stable_baselines3 import A2C, DQN, PPO

from envs.hmarl_central_env import CentralAgentEnv
from envs.hmarl_slice_env import ElasticSliceAgentEnv

slice_class = "C3"
algo = "PPO"
model_type = "agent"

if model_type == "central":
    env = CentralAgentEnv()
    models_dir = f"hmarl2/models/{model_type}_{algo}"
    log_file_name = f"central_{algo}"
else:
    env = ElasticSliceAgentEnv(slice_class=slice_class)
    models_dir = f"hmarl2/models/agent_{algo}_{slice_class}"
    log_file_name = f"{algo}_{slice_class}"

log_dir = "hmarl2/logs"

if algo == "PPO":
    model = PPO("MultiInputPolicy", env, verbose=1, tensorboard_log=log_dir)
elif algo == "A2C":
    model = A2C("MultiInputPolicy", env, verbose=1, tensorboard_log=log_dir)
else:
    model = DQN("MultiInputPolicy", env, verbose=1, tensorboard_log=log_dir)

TIMESTEPS = 100000

env.reset()
for i in range(1, 30):
    model.learn(total_timesteps=TIMESTEPS, reset_num_timesteps=False, tb_log_name=log_file_name)
    model.save(f"{models_dir}/{TIMESTEPS*i}")
env.close()


#!/usr/bin/env python
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os.path
import sys

from distutils.command.build import build

from setuptools import setup
from setuptools.command.install import install

CFFI_DEPENDENCY = "cffi>=0.8"

def get_ext_modules():
    original_sys_path = sys.path[:]
    sys.path.insert(
        0,
        os.path.join(os.path.dirname(os.path.abspath(__file__)), "src"),
    )
    import http11.c
    sys.path = original_sys_path
    return [http11.c.ffi.verifier.get_extension()]

class CFFIBuild(build):
    """
    This class exists, instead of just providing ``ext_modules=[...]`` directly
    in ``setup()`` because importing cryptography requires we have several
    packages installed first.

    By doing the imports here we ensure that packages listed in
    ``setup_requires`` are already installed.
    """

    def finalize_options(self):
        self.distribution.ext_modules = get_ext_modules()
        build.finalize_options(self)

class CFFIInstall(install):
    """
    As a consequence of CFFIBuild and it's late addition of ext_modules, we
    need the equivalent for the ``install`` command to install into platlib
    install-dir rather than purelib.
    """

    def finalize_options(self):
        self.distribution.ext_modules = get_ext_modules()
        install.finalize_options(self)

metafile = os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    "src",
    "http11",
    "__about__.py",
)
meta = {}
with open(metafile) as fp:
    exec(fp.read(), meta)

readmefile = os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    "README.rst",
)
with open(readmefile) as fp:
    long_description = fp.read()

setup(
    name=meta["__title__"],
    version=meta["__version__"],

    description=meta["__summary__"],
    long_description=long_description,
    license=meta["__license__"],
    url=meta["__url__"],

    author=meta["__author__"],
    author_email=meta["__email__"],

    classifiers=[
        "License :: OSI Approved :: Apache Software License",

        "Programming Language :: Python",
        "Programming Language :: Python :: 2",
        "Programming Language :: Python :: 2.6",
        "Programming Language :: Python :: 2.7",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.2",
        "Programming Language :: Python :: 3.3",
        "Programming Language :: Python :: 3.4",
        "Programming Language :: Python :: Implementation :: CPython",
        "Programming Language :: Python :: Implementation :: PyPy",
    ],

    package_dir={"": "src"},
    packages=[
        "http11",
        "http11.c",
    ],

    install_requires=[
        CFFI_DEPENDENCY,
        "enum34",
    ],

    setup_requires=[
        CFFI_DEPENDENCY,
    ],

    # These are needed so that CFFI can correctly function
    zip_safe=False,
    ext_package="http11",
    cmdclass={
        "build": CFFIBuild,
        "install": CFFIInstall,
    }
)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Nov 15 15:48:21 2021

With this script you can make a 3D plot of 2 ROIs and its overlap

@author: lindvoo
"""

# Import libraries
import matplotlib.pyplot as plt
import numpy as np
from nilearn.image import load_img, get_data

# Import 3D projection
from mpl_toolkits.mplot3d import Axes3D

# Read in images
img1 = load_img('XXX.nii')
img2 = load_img('XXX.nii')
voxels1 = get_data(img1)
voxels2 = get_data(img2)

# Remove slices that do not contain the ROI [reduce comp load and easy plotting]
whichslices=[]
for c,val in enumerate(voxels1[:,0,0]):

    if (np.sum(voxels1[c,:,:]))>0:
        whichslices.append(c)

voxels1 = voxels1[whichslices[0]:whichslices[-1],:,:]
voxels2 = voxels2[whichslices[0]:whichslices[-1],:,:]

whichslices=[]
for c,val in enumerate(voxels1[0,0,:]):

    if (np.sum(voxels1[:,:,c]))>0:
        whichslices.append(c)

voxels1 = voxels1[:,:,whichslices[0]:whichslices[-1]]
voxels2 = voxels2[:,:,whichslices[0]:whichslices[-1]]

whichslices=[]
for c,val in enumerate(voxels1[0,:,0]):

    if (np.sum(voxels1[:,c,:]))>0:
        whichslices.append(c)

voxels1 = voxels1[:,whichslices[0]:whichslices[-1],:]
voxels2 = voxels2[:,whichslices[0]:whichslices[-1],:]

# Make boolean to create a figure with both
bool_voxels1 = np.zeros(voxels1.shape, dtype=bool)
bool_voxels2 = np.zeros(voxels2.shape, dtype=bool)
for x,xval in enumerate(voxels1[:,0,0]):
    for y,yval in enumerate(voxels1[0,:,0]):
        for z,xval in enumerate(voxels1[0,0,:]):

            bool_voxels1[x,y,z] = voxels1[x,y,z]>0
            bool_voxels2[x,y,z] = voxels2[x,y,z]>0

# Create overlap
combined = bool_voxels1 | bool_voxels2
overlap = bool_voxels1 & bool_voxels2

# Set the colors of each object
colors = np.empty(overlap.shape, dtype=object)
colors[bool_voxels1] = 'blue'
colors[bool_voxels2] = 'green'
colors[overlap] = 'red'

# With np.transpose(overlap, (2, 1, 0)) you can transpose the array

# Plot
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.voxels(combined,
          facecolors=colors,
          alpha=.5)
plt.axis('off')
plt.show()


import threading
import time
import requests

import json
import os
import random

import cv2 as cv
import numpy as np
import scipy.io
import subprocess
from subprocess import Popen
import json

from utils_models import load_model

# Imports
import numpy as np
import os
import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfile
import cv2
import numpy as np
import csv
import time
from packaging import version

from collections import defaultdict
from io import StringIO
from PIL import Image

# Object detection imports
from utils import label_map_util
from utils import visualization_utils as vis_util
from pathlib import Path

class Process(threading.Thread):
    def __init__(self, video_path, context_id):
        threading.Thread.__init__(self)
        self.context_id = context_id
        self.video_path = video_path
        self.processing_percents = 0
        self.processing_path = 'Images/Processing/' + self.context_id
        self.images_path = self.processing_path + '/cars/{}'
        self.create_dir()
        print("init", context_id)

    def create_dir(self):
        Path(self.processing_path).mkdir(parents=True, exist_ok=True)
        Path(self.processing_path + '/cars/').mkdir(parents=True, exist_ok=True)

    def load_model_init(self):
        model = load_model()
        model.load_weights('models/model.96-0.89.hdf5')

        cars_meta = scipy.io.loadmat('devkit/cars_meta')
        class_names = cars_meta['class_names']  # shape=(1, 196)
        class_names = np.transpose(class_names)

        return model, cars_meta, class_names

    def get_detection_time(self, milliseconds):
        seconds = milliseconds / 1000.0
        return seconds

    def create_detections(self, results):
        objects_detection_format = []

        for result in results:
            objects_detection_format.append({
                "ContextId": self.context_id,
                "DetectionType": 0,
                "DetectionTime": result["frame_number"],
                "Description": "car detection",
                "Accuracy": float(result["prob"]),
                "Color": result["detection_car"][0],
                "Manufacturer": result["label"],
                "LicensePlate": result["license_car"]
            })

        response = requests.post('https://detections-api20210802233301.azurewebsites.net/Detections/CreateCars', json=objects_detection_format, verify=True)

        print("created cars on detection api: " + str(response.json()))

        return response.json()

    def detect_license_car(self, img_path):
        command = '''docker run -it --rm -v $(pwd):/data:ro openalpr/openalpr  -j -c eu ''' + img_path
        process = Popen(command,shell=True,stdout=subprocess.PIPE)
        result = process.communicate()
        a,b = result

        return json.loads(a)

    def write_detections_locally(self, responses, results):
        for index, response in enumerate(responses):
            img = results[index]["img"]
            detection_id = response["id"]
            path = self.images_path.format(detection_id) + '.png'
            print("path to save: " + str(path))
            cv2.imwrite(path.format(detection_id), img)

    def model_detect_car(self, car_to_detect, model, cars_meta, class_names):
        img_width, img_height = 224, 224

        results = []

        for car in car_to_detect:
            image_name = car["countercars"]
            print(image_name)
            filename = os.path.join(self.processing_path, str(image_name) + '.jpg')
            print('Start processing image: {}'.format(filename))
            try:
                bgr_img = cv.imread(filename)
                bgr_img = cv.resize(bgr_img, (img_width, img_height), cv.INTER_CUBIC)
                rgb_img = cv.cvtColor(bgr_img, cv.COLOR_BGR2RGB)
                rgb_img = np.expand_dims(rgb_img, 0)
                preds = model.predict(rgb_img)
                #license_car = self.detect_license_car(filename)
                license_plate = "N/A"
                # if license_car["results"]:
                #     license_plate = license_car["results"][0]["plate"]
                #     print("plate: " + str(license_plate))
                #     print("data: " + str(license_car["results"][0]))
                prob = np.max(preds)
                class_id = np.argmax(preds)
                results.append({'label': class_names[class_id][0][0], 'prob': '{:.4}'.format(prob), 'picture name': image_name, 'frame_number': car["detection_time"], 'detection_car': car["type"], 'license_car': license_plate, 'img': bgr_img})
                #text = ('Predict: {}, prob: {}'.format(class_names[class_id][0][0], prob))
                #cv.imwrite('Images/{}_out.png'.format(image_name), bgr_img)
                #cv2.imwrite(self.processing_path + "/" + str(i) + '.jpg', crop_img)

                print("successfully")
            except Exception as e:
                print(str(e))

        print(results)
        print("finished round of detetctions")

        responses = self.create_detections(results)

        self.write_detections_locally(responses, results)

        print("send it to the detection service")
        #K.clear_session()

    def crop_objects(self, width, height, image_np, output_dict, i):
        image = {}
        image["status"] = False

        global ymin, ymax, xmin, xmax
        #width, height = image.size

        #Coordinates of detected objects
        ymin = int(output_dict['detection_boxes'][0][0]*height)
        xmin = int(output_dict['detection_boxes'][0][1]*width)
        ymax = int(output_dict['detection_boxes'][0][2]*height)
        xmax = int(output_dict['detection_boxes'][0][3]*width)
        crop_img = image_np[ymin:ymax, xmin:xmax]

        # 1. Only crop objects that are detected with an accuracy above 50%,
        # images
        # with objects below 50% will be filled with zeros (black image)
        # This is something I need in my program
        # 2. Only crop the object with the highest score (Object Zero)

        if output_dict['detection_scores'][0] < 0.8:
            return image

        #print(crop_img.shape)

        if crop_img.shape[1] > 0 and crop_img.shape[0] > 0:
            #Save cropped object into image
            cv2.imwrite(self.processing_path + "/" + str(i) + '.jpg', crop_img)

        image["status"] = True
        image["crop_img"] = crop_img

        return image

    def print_length_video(self, cap):
        print("processing video: ")
        print(str(self.video_path))

         # print the length
        fps = cap.get(cv2.CAP_PROP_FPS)      # OpenCV2 version 2 used "CV_CAP_PROP_FPS"
        frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        self.frames_in_video = frame_count
        duration = frame_count/fps

        print('fps = ' + str(fps))
        print('number of frames = ' + str(frame_count))
        print('duration (S) = ' + str(duration))
        minutes = int(duration/60)
        seconds = duration%60
        print('duration (M:S) = ' + str(minutes) + ':' + str(seconds))

    def calc_processing_percents(self, video_capture):

        # get next frame number out of all the frames for video
        next_frame_no = video_capture.get(cv2.CAP_PROP_POS_FRAMES)
        # get total number of frames in the video
        total_frames = video_capture.get(cv2.CAP_PROP_FRAME_COUNT)

        complete = round(next_frame_no/total_frames, 4)

        self.processing_percents = format(complete * 90, ".2f")

        print(self.processing_percents, "%")

    def object_detection_function(self, source_video, command):
        # input video
        cap = cv2.VideoCapture(self.video_path)

        #print info about video length
        self.print_length_video(cap)

        # Variables
        height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
        width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        fps = int(cap.get(cv2.CAP_PROP_FPS))

        # By default I use an "SSD with Mobilenet" model here. See the detection model zoo (https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md) for a list of other models that can be run out-of-the-box with varying speeds and accuracies.
        # What model to download.
        MODEL_NAME = 'ssd_mobilenet_v1_coco_2018_01_28'
        MODEL_FILE = MODEL_NAME + '.tar.gz'
        DOWNLOAD_BASE = \
            'http://download.tensorflow.org/models/object_detection/'

        # Path to frozen detection graph. This is the actual model that is used for the object detection.
        PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb'

        # List of the strings that is used to add correct label for each box.
        PATH_TO_LABELS = os.path.join('data', 'mscoco_label_map.pbtxt')

        NUM_CLASSES = 90

        # Download Model
        # uncomment if you have not download the model yet
        # Load a (frozen) Tensorflow model into memory.
        detection_graph = tf.Graph()
        with detection_graph.as_default():
            od_graph_def = tf.compat.v1.GraphDef() # use this line to run it with TensorFlow version 2.x
            with tf.compat.v2.io.gfile.GFile(PATH_TO_CKPT, 'rb') as fid: # use this line to run it with TensorFlow version 2.x
                serialized_graph = fid.read()
                od_graph_def.ParseFromString(serialized_graph)
                tf.import_graph_def(od_graph_def, name='')

        # Loading label map
        # Label maps map indices to category names, so that when our convolution network predicts 5, we know that this corresponds to airplane. Here I use internal utility functions, but anything that returns a dictionary mapping integers to appropriate string labels would be fine
        label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
        categories = label_map_util.convert_label_map_to_categories(label_map,
                max_num_classes=NUM_CLASSES, use_display_name=True)
        category_index = label_map_util.create_category_index(categories)

        count_frames = 0
        car_to_detect = []
        counter_cars = 0

        if(command=="imwrite"):
            fourcc = cv2.VideoWriter_fourcc(*'XVID')
            output_movie = cv2.VideoWriter(source_video.split(".")[0]+'_output.avi', fourcc, fps, (width, height))

        with detection_graph.as_default():
            # with tf.Session(graph=detection_graph) as sess:
            with tf.compat.v1.Session(graph=detection_graph) as sess: # use this line to run it with TensorFlow version 2.x

                # Definite input and output Tensors for detection_graph
                image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')

                # Each box represents a part of the image where a particular object was detected.
                detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')

                # Each score represent how level of confidence for each of the objects.
                # Score is shown on the result image, together with the class label.
                detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
                detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
                num_detections = detection_graph.get_tensor_by_name('num_detections:0')

                # for all the frames that are extracted from input video
                while cap.isOpened():
                    (ret, frame) = cap.read()

                    if not ret:
                        print ('end of the video file...')
                        break

                    input_frame = frame
                    count_frames = count_frames + 1
                    self.calc_processing_percents(cap)

                    # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
                    image_np_expanded = np.expand_dims(input_frame, axis=0)

                    # Actual detection.
                    (boxes, scores, classes, num) = \
                        sess.run([detection_boxes, detection_scores,
                                detection_classes, num_detections],
                                feed_dict={image_tensor: image_np_expanded})

                    print("classes: " )
                    print(classes)

                    output_dict = {}

                    for box, score in zip(boxes, scores):
                        for box_inside, score_inside in zip(box, score):
                            counter_cars = counter_cars + 1
                            output_dict["detection_scores"] = []
                            output_dict["detection_scores"].append(score_inside)
                            output_dict["detection_boxes"] = []
                            output_dict["detection_boxes"].append([])

                            output_dict["detection_boxes"][0].append(box_inside[0])
                            output_dict["detection_boxes"][0].append(box_inside[1])
                            output_dict["detection_boxes"][0].append(box_inside[2])
                            output_dict["detection_boxes"][0].append(box_inside[3])
                            result_crop = self.crop_objects(width, height, frame, output_dict, counter_cars)

                            if result_crop["status"] != False:
                                result_crop["countercars"] = counter_cars
                                result_crop["box"] = box_inside
                                #get time of detection
                                milliseconds = cap.get(cv2.CAP_PROP_POS_MSEC)
                                detection_time = self.get_detection_time(milliseconds)
                                result_crop["detection_time"] = detection_time
                                car_to_detect.append(result_crop)

                    #Visualization of the results of a detection.
                    (counter, csv_line,  box_to_display_str_map, box_to_color_map) = \
                        vis_util.visualize_boxes_and_labels_on_image_array(
                        cap.get(1),
                        input_frame,
                        np.squeeze(boxes),
                        np.squeeze(classes).astype(np.int32),
                        np.squeeze(scores),
                        category_index,
                        use_normalized_coordinates=True,
                        line_thickness=4,
                        )

                    for type_box in box_to_display_str_map:
                        val_type_car = box_to_display_str_map[type_box]
                        for car in car_to_detect:
                            if (np.array_equal(car["box"], type_box, equal_nan=False)):
                                car["type"] = val_type_car

                    if len(car_to_detect) > 1000000:
                        new_list = list(car_to_detect)

                        print("try to process.....")
                        print("loading model for: " + str(self.context_id))
                        model, cars_meta, class_names = self.load_model_init()
                        print("finished loading model for: " + str(self.context_id))
                        self.model_detect_car(new_list, model, cars_meta, class_names)
                        car_to_detect = []

                    if(command=="imshow"):
                        x = "imshow"
                        # cv2.imshow('vehicle detection', input_frame)

                        # if cv2.waitKey(1) & 0xFF == ord('q'):
                        #     break
                    elif(command=="imwrite"):
                        output_movie.write(input_frame)
                        #print("writing frame...")

                    if csv_line != 'not_available':
                        with open('traffic_measurement.csv', 'a') as f:
                            writer = csv.writer(f)
                            (size, color, direction, speed) = \
                                csv_line.split(',')
                            writer.writerows([csv_line.split(',')])

                if len(car_to_detect) >= 1:
                    print("loading model for: " + str(self.context_id))
                    model, cars_meta, class_names = self.load_model_init()
                    print("finished loading model for: " + str(self.context_id))
                    new_list = list(car_to_detect)

                    print("try to process.....")
                    self.model_detect_car(new_list, model, cars_meta, class_names)
                    car_to_detect = []

                self.processing_percents = 100

                cap.release()
                #cv2.destroyAllWindows()

    def start_detection(self):
        print('start detections')
        self.object_detection_function(self.video_path, "imshow")

    def run(self):
        self.start_detection()


import pygame
import time, sys, os
sys.path.insert(0,"../")
from sound.SoundCte import *
'''
class GeneralSoundManager:

  def __init__(self, propertiesFile):
    # init all the submodules
    GAME_EFFECT =
    if propertiesFile is None
      propertiesFile = "DEFAULT_PROPERTIES_FILE.txt"
    effectSM = EffectSoundManager.init(propertiesFile)
    musicSM = MusicSoundManager.init(propertiesFile)
    menuSM = MenuSoundManager.init(propertiesFile)

  def manage(self, eventList):

    while True:
      for event in eventList:
        if event.type == GAME_EFFECT_EVENT: # o definir lista de eventos que corresponden a un efecto y ver si esta en ella
          effectSM.manage(event)
        if event.type == GAME_MUSIC_EVENT:
          musicSM.manage(event)
        if event.type == GAME_MENU_EVENT:
          menuSM.manage(event)
        if event.type == pygame.QUIT:
          pygame.quit()
          sys.exit()

  class EffectSoundManager
    def __init__(self, propertiesFile):
      #init sonidos de effectos
      # load sound files

      MAIN_CHARACTER_ATTACK_SOUND = pygame.mixer.Sound('test.ogg')
      # o para poder cargar desde archivo de texto
      MAIN_CHARACTER_ATTACK_SOUND = SoundResourceLoader.load(propertiesFile, "MAIN_CHARACTER_ATTACK")
      text_file = open("filename.dat", "r")
      lines = text_file.read().split(',')
      print lines
      print len(lines)
      text_file.close()

    def manage(event):
      if event.type == MAIN_CHARACTER_ATTACK:
          MAIN_CHARACTER_ATTACK_SOUND.play()
      if event.type == MAIN_CHARACTER_HIT:
          MAIN_CHARACTER_HIT_SOUND.play()
      if event.type == CURRENT_ENEMY_ATTACK:
          CURRENT_ENEMY_ATTACK_SOUND.play()
      if event.type == CURRENT_ENEMY_HIT:
          CURRENT_ENEMY_HIT_SOUND.play()
  class SoundResourceLoader
    def load(propertiesFile, soundName)
        properties = new Properties(propertiesFile)
        return pygame.mixer.Sound(properties.getPropertie(soundName))

'''
'''
import os
CONTEXT							= os.getcwd()
CONTEXT = '/home/miguel/Descargas/videojoco2d-master/'

EFFECT_PRIORITY = 1
MUSIC_PRIORITY = 1
MENU_PRIORITY = 1

EFFECT_CHANNEL = 0
EFFECT_CHANNEL2 = 4
MUSIC_CHANNEL = 1
MENU_CHANNEL = 2
MENU_CHANNEL2 = 3

if pygame.mixer.get_init() is None:
	pygame.mixer.init()

def load():

	#ambiente
	AMBIENTEAGUASPLASHS_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteAguaSplash.ogg'		)
	AMBIENTEANDARARENACORTO_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteAndarArenaCorto.ogg'	)
	AMBIENTEANDARRAMAS_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteAndarRamas.ogg'		)
	AMBIENTEBOSQUECORTO_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteBosqueCorto.ogg'		)
	AMBIENTECASCADA1_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteCascada1.ogg'			)
	AMBIENTECASCADA2_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteCascada2.ogg'			)
	AMBIENTECASCOTESCAIDA_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteCascotesCaida.ogg'		)
	AMBIENTECOLISEO_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteColiseo.ogg' 			)
	AMBIENTEFUEGO1_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteFuego1.ogg'			)
	AMBIENTEFUEGO2_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteFuego2.ogg'			)
	AMBIENTEFUEGONOLOOP_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteFuegoNoLoop.ogg'		)
	AMBIENTEGENTEPANICO_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteGentePanico.ogg'		)
	AMBIENTEGENTEPANICOCORTO_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteGentePanicoCorto.ogg'	)
	AMBIENTEGENTESUSURROS_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteGenteSusurros.ogg'		)
	AMBIENTEGRANJA_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteGranja.ogg'			)
	AMBIENTEHOJASMANIPULAR_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteHojasManipular.ogg'	)
	AMBIENTELLUVIA_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteLluvia.ogg'			)
	AMBIENTENOCHE_SOUND				= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteNoche.ogg'				)
	AMBIENTEPISARTIERRA_SOUND 		= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbientePisarTierra.ogg'		)
	AMBIENTERATA1_SOUND				= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteRata1.ogg'				)
	AMBIENTERATA2_SOUND				= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteRata2.ogg'				)
	AMBIENTERATA3_SOUND				= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteRata3.ogg'				)
	AMBIENTERATA4_SOUND				= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteRata4.ogg'				)
	AMBIENTERIO1_SOUND				= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteRio1.ogg'				)
	AMBIENTERIO2_SOUND				= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteRio2.ogg'				)
	AMBIENTEVIENTO_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Ambiente/AmbienteViento.ogg'			)

	#armas
	ARMADAGAIMPACTO_SOUND	 	= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaDagaImpacto.ogg'		)
	ARMAESPADAATAQUE1_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaEspadaAtaque1.ogg'	)
	ARMAESPADAATAQUE2_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaEspadaAtaque2.ogg'	)
	ARMAESPADAEQUIPAR_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaEspadaEquipar.ogg'	)
	ARMAESPADAIMPACTO_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaEspadaImpacto.ogg'	)
	ARMAFLECHAATAQUE1_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaFlechaAtaque1.ogg'	)
	ARMAFLECHAATAQUE2_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaFlechaAtaque2.ogg'	)
	ARMAFLECHAIMPACTO1_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaFlechaImpacto1.ogg'	)
	ARMAFLECHAIMPACTO2_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaFlechaImpacto2.ogg'	)
	ARMAHORCAATAQUE_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaHorcaAtaque.ogg' 		)
	ARMAHORCAIMPACTO_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaHorcaImpacto.ogg' 	)
	ARMAHORCAIMPACTO2_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaHorcaImpacto2.ogg' 	)
	ARMAMAGIAATAQUE_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaMagiaAtaque.ogg' 		)
	ARMAMANOTAZOIMPACTO_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaManotazoImpacto.ogg' 	)
	ARMAPUNHOIMPACTO_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Armas/ArmaPunhoImpacto.ogg' 	)

	#menu
	CLICK_SOUND 		= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/click.ogg'			)
	CLICK_2_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/click_2.ogg'		)
	LOAD_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/load.ogg'			)
	MISC_MENU_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/misc_menu.ogg'		)
	MISC_MENU_2_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/misc_menu_2.ogg'	)
	MISC_MENU_3_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/misc_menu_3.ogg'	)
	MISC_MENU_4_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/misc_menu_4.ogg'	)
	MISC_SOUND_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/misc_sound.ogg'	)
	NEGATIVE_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/negative.ogg'		)
	NEGATIVE_2_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/negative_2.ogg'	)
	POSITIVE_SOUND		= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/positive.ogg'		)
	SAVE_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/save.ogg'			)
	SHARP_ECHO_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Menu/sharp_echo.ogg'	)

	#musica

	MUSICA1_SOUND = pygame.mixer.music.load(CONTEXT+'res/sound/Musica/Musica1.ogg')
	MUSICA2_SOUND = pygame.mixer.music.load(CONTEXT+'res/sound/Musica/Musica2.ogg')
	MUSICA3_SOUND = pygame.mixer.music.load(CONTEXT+'res/sound/Musica/Musica3.ogg')

	MUSICA5_SOUND = pygame.mixer.music.load(CONTEXT+'res/sound/Musica/Musica5.ogg')

	MUSICA6_SOUND = pygame.mixer.music.load(CONTEXT+'res/sound/Musica/Musica6.ogg')

	MUSICA_PLAY = pygame.mixer.music.play()
	#personajes
	PERSONAJEGRITOSTANDARD_SOUND	= pygame.mixer.Sound(CONTEXT+'res/sound/Personajes/PersonajeGritoStandard.ogg'	)
	PERSONAJEVIDABAJA_SOUND			= pygame.mixer.Sound(CONTEXT+'res/sound/Personajes/PersonajeVidaBaja.ogg' 		)
	PERSONAJESGRITOHOMBRE_SOUND 	= pygame.mixer.Sound(CONTEXT+'res/sound/Personajes/PersonajesGritoHombre.ogg'	)
'''
class GeneralSoundManager():

	def __init__(self, context):

		self.CONTEXT	= context

		self.EFFECT_PRIORITY = 1
		self.MUSIC_PRIORITY = 1
		self.MENU_PRIORITY = 1

		if pygame.mixer.get_init() is None:
			pygame.mixer.init()

		#ambiente
		self.AMBIENTEAGUASPLASHS_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteAguaSplash.ogg'		)
		self.AMBIENTEANDARARENACORTO_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteAndarArenaCorto.ogg'	)
		self.AMBIENTEANDARRAMAS_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteAndarRamas.ogg'		)
		self.AMBIENTEBOSQUECORTO_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteBosqueCorto.ogg'		)
		self.AMBIENTECASCADA1_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteCascada1.ogg'			)
		self.AMBIENTECASCADA2_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteCascada2.ogg'			)
		self.AMBIENTECASCOTESCAIDA_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteCascotesCaida.ogg'		)
		self.AMBIENTECOLISEO_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteColiseo.ogg' 			)
		self.AMBIENTEFUEGO1_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteFuego1.ogg'			)
		self.AMBIENTEFUEGO2_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteFuego2.ogg'			)
		self.AMBIENTEFUEGONOLOOP_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteFuegoNoLoop.ogg'		)
		self.AMBIENTEGENTEPANICO_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteGentePanico.ogg'		)
		self.AMBIENTEGENTEPANICOCORTO_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteGentePanicoCorto.ogg'	)
		self.AMBIENTEGENTESUSURROS_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteGenteSusurros.ogg'		)
		self.AMBIENTEGRANJA_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteGranja.ogg'			)
		self.AMBIENTEHOJASMANIPULAR_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteHojasManipular.ogg'	)
		self.AMBIENTELLUVIA_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteLluvia.ogg'			)
		self.AMBIENTENOCHE_SOUND				= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteNoche.ogg'				)
		self.AMBIENTEPISARTIERRA_SOUND 		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbientePisarTierra.ogg'		)
		self.AMBIENTERATA1_SOUND				= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteRata1.ogg'				)
		self.AMBIENTERATA2_SOUND				= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteRata2.ogg'				)
		self.AMBIENTERATA3_SOUND				= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteRata3.ogg'				)
		self.AMBIENTERATA4_SOUND				= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteRata4.ogg'				)
		self.AMBIENTERIO1_SOUND				= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteRio1.ogg'				)
		self.AMBIENTERIO2_SOUND				= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteRio2.ogg'				)
		self.AMBIENTEVIENTO_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Ambiente/AmbienteViento.ogg'			)

		#armas
		self.ARMADAGAIMPACTO_SOUND	 	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaDagaImpacto.ogg'		)
		self.ARMAESPADAATAQUE1_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaEspadaAtaque1.ogg'	)
		self.ARMAESPADAATAQUE2_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaEspadaAtaque2.ogg'	)
		self.ARMAESPADAEQUIPAR_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaEspadaEquipar.ogg'	)
		self.ARMAESPADAIMPACTO_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaEspadaImpacto.ogg'	)
		self.ARMAFLECHAATAQUE1_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaFlechaAtaque1.ogg'	)
		self.ARMAFLECHAATAQUE2_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaFlechaAtaque2.ogg'	)
		self.ARMAFLECHAIMPACTO1_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaFlechaImpacto1.ogg'	)
		self.ARMAFLECHAIMPACTO2_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaFlechaImpacto2.ogg'	)
		self.ARMAHORCAATAQUE_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaHorcaAtaque.ogg' 		)
		self.ARMAHORCAIMPACTO_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaHorcaImpacto.ogg' 	)
		self.ARMAHORCAIMPACTO2_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaHorcaImpacto2.ogg' 	)
		self.ARMAMAGIAATAQUE_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaMagiaAtaque.ogg' 		)
		self.ARMAMANOTAZOIMPACTO_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaManotazoImpacto.ogg' 	)
		self.ARMAPUNHOIMPACTO_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Armas/ArmaPunhoImpacto.ogg' 	)

		#menu
		self.CLICK_SOUND 		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/click.ogg'			)
		self.CLICK_2_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/click_2.ogg'		)
		self.LOAD_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/load.ogg'			)
		self.MISC_MENU_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/misc_menu.ogg'		)
		self.MISC_MENU_2_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/misc_menu_2.ogg'	)
		self.MISC_MENU_3_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/misc_menu_3.ogg'	)
		self.MISC_MENU_4_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/misc_menu_4.ogg'	)
		self.MISC_SOUND_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/misc_sound.ogg'	)
		self.NEGATIVE_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/negative.ogg'		)
		self.NEGATIVE_2_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/negative_2.ogg'	)
		self.POSITIVE_SOUND		= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/positive.ogg'		)
		self.SAVE_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/save.ogg'			)
		self.SHARP_ECHO_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Menu/sharp_echo.ogg'	)

		#musica
		'''
		self.MUSICA1_SOUND = pygame.mixer.music.load(self.CONTEXT+'res/sound/Musica/Musica1.ogg')
		self.MUSICA2_SOUND = pygame.mixer.music.load(self.CONTEXT+'res/sound/Musica/Musica2.ogg')
		self.MUSICA3_SOUND = pygame.mixer.music.load(self.CONTEXT+'res/sound/Musica/Musica3.ogg')
		self.MUSICA4_SOUND = pygame.mixer.music.load(self.CONTEXT+'res/sound/Musica/Musica4.ogg')
		self.MUSICA5_SOUND = pygame.mixer.music.load(self.CONTEXT+'res/sound/Musica/Musica5.ogg')
		self.MUSICA6_SOUND = pygame.mixer.music.load(self.CONTEXT+'res/sound/Musica/Musica6.ogg')
		'''

		#personajes
		self.PERSONAJEGRITOSTANDARD_SOUND	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Personajes/PersonajeGritoStandard.ogg'	)
		self.PERSONAJEVIDABAJA_SOUND			= pygame.mixer.Sound(self.CONTEXT+'res/sound/Personajes/PersonajeVidaBaja.ogg' 		)
		self.PERSONAJESGRITOHOMBRE_SOUND 	= pygame.mixer.Sound(self.CONTEXT+'res/sound/Personajes/PersonajesGritoHombre.ogg'	)

	def generalSoundManage(self, event, repeat = 0):

		if event < GAME_SOUND_EFFECT_EVENT:
			self.effectManage(event, self.EFFECT_PRIORITY, repeat)
		elif event < GAME_SOUND_MUSIC_EVENT:
			self.musicManage(event, self.MUSIC_PRIORITY, repeat)
		elif event < GAME_SOUND_MENU_EVENT:
			self.menuManage(event, self.MENU_PRIORITY, repeat)
		else:
			print("evento desconocido")

	def effectManage(self, event, priority, repeat):

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEAGUASPLASHS:
			  self.AMBIENTEAGUASPLASHS_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEANDARARENACORTO:
			  self.AMBIENTEANDARARENACORTO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEANDARRAMAS:
			  self.AMBIENTEANDARRAMAS_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEBOSQUECORTO:
			  self.AMBIENTEBOSQUECORTO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTECASCADA1:
			  self.AMBIENTECASCADA1_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTECASCADA2:
			  self.AMBIENTECASCADA2_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTECASCOTESCAIDA:
			  self.AMBIENTECASCOTESCAIDA_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTECOLISEO:
			  self.AMBIENTECOLISEO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEFUEGO1:
			  self.AMBIENTEFUEGO1_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEFUEGO2:
			  self.AMBIENTEFUEGO2_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEFUEGONOLOOP:
			  self.AMBIENTEFUEGONOLOOP_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEGENTEPANICO:
			  self.AMBIENTEGENTEPANICO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEGENTEPANICOCORTO:
			  self.AMBIENTEGENTEPANICOCORTO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEGENTESUSURROS:
			  self.AMBIENTEGENTESUSURROS_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEGRANJA:
			  self.AMBIENTEGRANJA_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEHOJASMANIPULAR:
			  self.AMBIENTEHOJASMANIPULAR_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTELLUVIA:
			  self.AMBIENTELLUVIA_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTENOCHE:
			  self.AMBIENTENOCHE_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEPISARTIERRA:
			  self.AMBIENTEPISARTIERRA_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTERATA1:
			  self.AMBIENTERATA1_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTERATA2:
			  self.AMBIENTERATA2_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTERATA3:
			  self.AMBIENTERATA3_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTERATA4:
			  self.AMBIENTERATA4_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTERIO1:
			  self.AMBIENTERIO1_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTERIO2:
			  self.AMBIENTERIO2_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_AMBIENTEVIENTO:
			  self.AMBIENTEVIENTO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMADAGAIMPACTO:
			  self.ARMADAGAIMPACTO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAESPADAATAQUE1:
			  self.ARMAESPADAATAQUE1_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAESPADAATAQUE2:
			  self.ARMAESPADAATAQUE2_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAESPADAEQUIPAR:
			  self.ARMAESPADAEQUIPAR_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAESPADAIMPACTO:
			  self.ARMAESPADAIMPACTO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAFLECHAATAQUE1:
			  self.ARMAFLECHAATAQUE1_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAFLECHAATAQUE2:
			  self.ARMAFLECHAATAQUE2_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAFLECHAIMPACTO1:
			  self.ARMAFLECHAIMPACTO1_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAFLECHAIMPACTO2:
			  self.ARMAFLECHAIMPACTO2_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAHORCAATAQUE:
			  self.ARMAHORCAATAQUE_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAHORCAIMPACTO:
			  self.ARMAHORCAIMPACTO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAHORCAIMPACTO2:
			  self.ARMAHORCAIMPACTO2_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAMAGIAATAQUE:
			  self.ARMAMAGIAATAQUE_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAMANOTAZOIMPACTO:
			  self.ARMAMANOTAZOIMPACTO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_ARMAPUNHOIMPACTO:
			  self.ARMAPUNHOIMPACTO_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_PERSONAJEGRITOSTANDARD:
			  self.PERSONAJEGRITOSTANDARD_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_PERSONAJEVIDABAJA:
			  self.PERSONAJEVIDABAJA_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_PERSONAJESGRITOHOMBRE:
			  self.PERSONAJESGRITOHOMBRE_SOUND.play()

		if event == GAME_SOUND_EFFECT_EVENT_STOP:
			pygame.mixer.stop()
		if event == GAME_SOUND_EFFECT_EVENT_PAUSE:
			pygame.mixer.pause()
		if event == GAME_SOUND_EFFECT_EVENT_RESUME:
			pygame.mixer.unpause()

	def musicManage(self, event, priority, repeat):

		if event == GAME_SOUND_MUSIC_EVENT_MUSIC_1:
			self.loadMusic('Musica1')
			pygame.mixer.music.play(repeat)

		if event == GAME_SOUND_MUSIC_EVENT_MUSIC_2:
			self.loadMusic('Musica2')
			pygame.mixer.music.play(repeat)

		if event == GAME_SOUND_MUSIC_EVENT_MUSIC_3:
			self.loadMusic('Musica3')
			pygame.mixer.music.play(repeat)

		if event == GAME_SOUND_MUSIC_EVENT_MUSIC_4:
			self.loadMusic('Musica4')
			pygame.mixer.music.play(repeat)

		if event == GAME_SOUND_MUSIC_EVENT_MUSIC_5:
			self.loadMusic('Musica5')
			pygame.mixer.music.play(repeat)

		if event == GAME_SOUND_MUSIC_EVENT_MUSIC_6:
			self.loadMusic('Musica6')
			pygame.mixer.music.play(repeat)

		if event == GAME_SOUND_MUSIC_EVENT_MUSIC_STOP:
			pygame.mixer.music.stop()

		if event == GAME_SOUND_MUSIC_EVENT_MUSIC_PAUSE:
			pygame.mixer.music.pause()

		if event == GAME_SOUND_MUSIC_EVENT_MUSIC_RESUME:
			pygame.mixer.music.unpause()

	def menuManage(self, event, priority, repeat):

		if event == GAME_SOUND_MENU:
			self.LOAD_SOUND.play()

		if event == GAME_SOUND_MENU_EVENT_MOVE_UP:
			self.MISC_MENU_SOUND.play()

		if event == GAME_SOUND_MENU_EVENT_MOVE_DOWN:
			self.MISC_MENU_SOUND.play()

		if event == GAME_SOUND_MENU_EVENT_MOVE_LEFT:
			self.MISC_MENU_SOUND.play()

		if event == GAME_SOUND_MENU_EVENT_MOVE_RIGHT:
			self.MISC_MENU_SOUND.play()

		if event == GAME_SOUND_MENU_EVENT_OK:
			self.POSITIVE_SOUND.play()

		if event == GAME_SOUND_MENU_EVENT_CANCEL:
			self.NEGATIVE_SOUND.play()

		if event == GAME_SOUND_MENU_EVENT_EXIT:
			self.SAVE_SOUND.play()

	def loadMusic(self, filename):
		pygame.mixer.music.load(self.CONTEXT+'res/sound/Musica/'+filename+'.ogg')

def main():
	soundManager = main2()
	soundManager.generalSoundManage(GAME_SOUND_MENU_EVENT_OK)
	time.sleep(5)
	soundManager.generalSoundManage(GAME_SOUND_MENU_EVENT_CANCEL)
	time.sleep(5)
	soundManager.generalSoundManage(GAME_SOUND_MENU_EVENT_MOVE_LEFT)
	time.sleep(5)


from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import TfidfVectorizer

def find_similar_names(garbage_name, name_list, topn=10):
    vectorizer = TfidfVectorizer()
    name_vectors = vectorizer.fit_transform(name_list + [garbage_name])
    similarity_scores = cosine_similarity(name_vectors[:-1], name_vectors[-1])
    similar_names_indices = similarity_scores.argsort(axis=0)[-topn:].flatten()[::-1]
    similar_names = [(name_list[i], similarity_scores[i]) for i in similar_names_indices]
    return similar_names

def find_best_match(predicted_names, first_two_letters):
    best_match = None
    best_score = 0
    for name, score in predicted_names:
        if name[:2].lower() == first_two_letters.lower() and len(name) > 2 and score > best_score:
            best_match = name
            best_score = score
    return best_match

def thisistheway(word):
    # Example usage
    file_path = 'words_alpha.txt'
    garbage_name = word.lower()
    name_list=[]
    with open(file_path, 'r', encoding='utf-8') as file:
        for line in file:
            if(len(line.strip())>2 and line.strip()[:2]==garbage_name[:2]):
                name_list.append(line.strip())

    predicted_names = find_similar_names(garbage_name, name_list)

    if predicted_names:
        print(f"Similar names to '{garbage_name}':")
        #for name, score in predicted_names:
        #   print(f"{name} (Similarity Score: {score})")
        print(predicted_names[0][0])
    else:
        print(f"No similar names found for '{garbage_name}'.")


from django import forms
from django.forms import ModelForm

from schedules.models import Schedule

class TimePickerInput(forms.TimeInput):
    input_type = 'time'

class DatePickerInput(forms.TimeInput):
    input_type = 'date'

class ScheduleCreateForm(ModelForm):
    class Meta:
        model = Schedule
        fields = ['date','start_time', 'end_time', 'is_available']

        widgets = {
            'date' : DatePickerInput(),
            'start_time' : TimePickerInput(),
            'end_time': TimePickerInput(),
        }

class ScheduleChangeForm(ModelForm):
    class Meta:
        model = Schedule
        fields = ['date','start_time', 'end_time', 'is_available']

        widgets = {
            # 'date' : DatePickerInput(),
            'start_time' : TimePickerInput(),
            'end_time': TimePickerInput(),
        }