Código fuente para FuzzyHandler

""" 
Archivo para el manejo de la funcion de diseño de controladores difusos, sirve de intermediario entre la interfaz grafica y la clase creada para manejar el controlador difuso definida en rutinas_fuzzy.py 
"""


from handlers.modificadorMf import update_definicionmf, validacion_mf
from rutinas.rutinas_fuzzy import FuzzyController
from rutinas.rutinas_fuzzy import FISParser
from PySide2 import QtCore, QtGui, QtWidgets

import numpy as np

import copy
import json


[documentos]def FuzzyHandler(self): """ Funcion principal para el manejo de diseño de controladores difusos, se crean las señales a ejecutar cuando se interactua con los widgets """ self.EntradasTab = self.main.fuzzyTabWidget.widget(1) self.SalidasTab = self.main.fuzzyTabWidget.widget(2) self.ReglasTab = self.main.fuzzyTabWidget.widget(3) self.PruebaTab = self.main.fuzzyTabWidget.widget(4) self.RespuestaTab = self.main.fuzzyTabWidget.widget(5) self.main.guardarFuzzButton.setDisabled(True) self.main.guardarComoFuzzButton.setDisabled(True) self.main.exportarFuzzButton.setDisabled(True) # Ocultado de los tabs self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) self.main.fuzzyTabWidget.removeTab(3) self.main.fuzzyTabWidget.removeTab(2) self.main.fuzzyTabWidget.removeTab(1) # Listas que definen al controlador difuso self.InputList = [] self.OutputList = [] self.RuleList = [] self.RuleEtiquetas = [] # Lista para para contorlar un desplazamiento de ventana self.vector_rotacion = [-0.25, 0, 0.25, 0.5, 0.75, 1, 1.25] self.rotacion_windowIn = 2 self.rotacion_windowOut = 2 # Objeto de la clase FuzzyController self.fuzzInitController = FuzzyController # Objeto de la clase FISParser, para cargar y exportar .FIS self.parser = FISParser # Almacenado de widgets en listas para acceder a ellos por indices crear_vectores_de_widgets(self) # Ocultado de widgets for i_f, o_f, it_f, ot_f, f2d, f3d in zip( self.inframes, self.outframes, self.intestframes, self.outtestframes, self.respuesta2dframes, self.respuesta3dframes, ): i_f.hide() o_f.hide() it_f.hide() ot_f.hide() f2d.hide() f3d.hide() self.main.imagenEsquemas.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/sinEsquema.png") ) self.main.estrucNumberInputs.currentIndexChanged.connect( lambda: imagen_entradas(self) ) self.main.estrucNumberOutputs.currentIndexChanged.connect( lambda: imagen_salidas(self) ) self.main.fuzzyEsquemasCheck.clicked["bool"].connect(lambda: check_esquema_show(self)) self.main.fuzzyEsquemas.currentIndexChanged.connect(lambda: show_esquema(self)) self.main.generarFuzzyButton.clicked.connect(lambda: crear_tabs(self)) self.main.guardarFuzzButton.clicked.connect(lambda: guardar_controlador(self)) self.main.cargarFuzzButton.clicked.connect(lambda: cargar_controlador(self)) self.main.guardarComoFuzzButton.clicked.connect(lambda: guardarcomo_controlador(self)) self.main.exportarFuzzButton.clicked.connect(lambda: exportar_fis(self)) self.main.inputNumber.currentIndexChanged.connect(lambda: seleccion_entrada(self)) self.main.inputNombre.editingFinished.connect(lambda: nombre_entrada(self)) self.main.inputNombre.focusIn.connect(lambda: cerrar_prueba(self)) self.main.inputEtiquetasNum.editingFinished.connect( lambda: numero_de_etiquetas_in(self) ) self.main.inputEtiquetasNum.focusIn.connect(lambda: cerrar_prueba(self)) self.main.inputRange.editingFinished.connect(lambda: rango_in(self)) self.main.inputRange.focusIn.connect(lambda: cerrar_prueba(self)) self.main.etiquetaNumIn.currentIndexChanged.connect( lambda: seleccion_etiqueta_in(self) ) self.main.etiquetaNombreIn.editingFinished.connect(lambda: nombre_etiqueta_in(self)) self.main.etiquetaNombreIn.focusIn.connect(lambda: cerrar_prueba(self)) self.main.etiquetaMfIn.currentIndexChanged.connect(lambda: seleccion_mf_in(self)) self.main.etiquetaDefinicionIn.editingFinished.connect(lambda: definicion_in(self)) self.main.etiquetaDefinicionIn.focusIn.connect(lambda: cerrar_prueba(self)) self.main.outputNumber.currentIndexChanged.connect(lambda: seleccion_salida(self)) self.main.outputNombre.editingFinished.connect(lambda: nombre_salida(self)) self.main.outputNombre.focusIn.connect(lambda: cerrar_prueba(self)) self.main.outputEtiquetasNum.editingFinished.connect( lambda: numero_de_etiquetas_out(self) ) self.main.outputEtiquetasNum.focusIn.connect(lambda: cerrar_prueba(self)) self.main.outputRange.editingFinished.connect(lambda: rango_out(self)) self.main.outputRange.focusIn.connect(lambda: cerrar_prueba(self)) self.main.defuzzMethodOut.currentIndexChanged.connect(lambda: defuzz_metodo(self)) self.main.etiquetaNumOut.currentIndexChanged.connect( lambda: seleccion_etiqueta_out(self) ) self.main.etiquetaNombreOut.editingFinished.connect(lambda: nombre_etiqueta_out(self)) self.main.etiquetaNombreOut.focusIn.connect(lambda: cerrar_prueba(self)) self.main.etiquetaMfOut.currentIndexChanged.connect(lambda: seleccion_mf_out(self)) self.main.etiquetaDefinicionOut.editingFinished.connect(lambda: definicion_out(self)) self.main.etiquetaDefinicionOut.focusIn.connect(lambda: cerrar_prueba(self)) self.main.fuzzyTabWidget.currentChanged.connect(lambda: rule_list_visualizacion(self)) self.main.rulelistWidget.currentRowChanged.connect( lambda: seleccionar_etiquetas(self) ) self.main.ruleAgregarButton.clicked.connect(lambda: rule_list_agregar(self)) self.main.ruleEliminarButton.clicked.connect(lambda: rule_list_eliminar(self)) self.main.ruleCambiarButton.clicked.connect(lambda: rule_list_cambiar(self)) self.main.ruleCrearButton.clicked.connect(lambda: crear_controlador(self)) for slider in self.intestsliders: slider.valueChanged.connect(lambda: prueba_input(self))
[documentos]def cerrar_prueba(self): """ Funcion para cerrar las pestañas de pruebas ante cambios en el controlador difuso """ self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4)
[documentos]def imagen_entradas(self): """ Funcion para establecer la imagen del numero de entradas """ ni = self.main.estrucNumberInputs.currentIndex() + 1 self.main.imagenInputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/entrada" + str(ni) + ".png") )
[documentos]def imagen_salidas(self): """ Funcion para establecer la imagen del numero de salidas """ no = self.main.estrucNumberOutputs.currentIndex() + 1 self.main.imagenOutputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/salida" + str(no) + ".png") )
[documentos]def check_esquema_show(self): """ Funcion para mediar entre entradas y salidas genericas y esquemas de control """ if not self.main.fuzzyEsquemasCheck.isChecked(): self.main.imagenEsquemas.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/sinEsquema.png") ) imagen_entradas(self) imagen_salidas(self) else: show_esquema(self)
[documentos]def show_esquema(self): """ Funcion para establecer la imagen del esquema de control seleccionado """ if self.main.fuzzyEsquemas.currentIndex() == 0: self.main.imagenEsquemas.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/pidDifuso.png") ) self.main.imagenInputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/entrada3.png") ) self.main.imagenOutputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/salida1.png") ) elif self.main.fuzzyEsquemas.currentIndex() == 1: self.main.imagenEsquemas.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/piDifuso.png")) self.main.imagenInputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/entrada2.png") ) self.main.imagenOutputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/salida1.png") ) elif self.main.fuzzyEsquemas.currentIndex() == 2: self.main.imagenEsquemas.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/pdDifuso.png")) self.main.imagenInputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/entrada2.png") ) self.main.imagenOutputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/salida1.png") ) elif self.main.fuzzyEsquemas.currentIndex() == 3: self.main.imagenEsquemas.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/GainScheduler.png")) self.main.imagenInputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/entrada2.png") ) self.main.imagenOutputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/salida3.png") ) elif self.main.fuzzyEsquemas.currentIndex() == 4: self.main.imagenEsquemas.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/pidplusDifuso.png")) self.main.imagenInputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/entrada1.png") ) self.main.imagenOutputs.setPixmap( QtGui.QPixmap(":/imagenes/imagenes/salida1.png") )
[documentos]def crear_tabs(self): """ Funcion para iniciar el entorno de diseño para entradas y salidas genericas """ if not self.main.fuzzyEsquemasCheck.isChecked(): self.setWindowTitle( "Laboratorio Virtual - Nuevo controlador sin guardar*" ) self.main.inputNumber.blockSignals(True) self.main.outputNumber.blockSignals(True) self.main.inputNombre.setReadOnly(False) self.main.outputNombre.setReadOnly(False) # Vaciado de informacion previa self.current_file = "" self.InputList = [] self.OutputList = [] self.RuleList = [] self.RuleEtiquetas = [] # Habilitar guardado de archivos self.main.guardarFuzzButton.setEnabled(True) self.main.guardarComoFuzzButton.setEnabled(True) self.main.exportarFuzzButton.setEnabled(True) # Se ocultan todos los tabs y se muestran solo Entradas, Salidas y Reglas self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) self.main.fuzzyTabWidget.removeTab(3) self.main.fuzzyTabWidget.removeTab(2) self.main.fuzzyTabWidget.removeTab(1) self.main.fuzzyTabWidget.addTab(self.EntradasTab, "Entradas") self.main.fuzzyTabWidget.addTab(self.SalidasTab, "Salidas") self.main.fuzzyTabWidget.addTab(self.ReglasTab, "Reglas") NumeroEntradas = int(self.main.estrucNumberInputs.currentText()) NumeroSalidas = int(self.main.estrucNumberOutputs.currentText()) self.main.inputNumber.clear() self.main.outputNumber.clear() # Creacion de funciones de membresia genericas for i in range(NumeroEntradas): self.main.inputNumber.insertItem(i, str(i + 1)) temp_dic = inputDic_creator(self, i) self.InputList.append(temp_dic) ini_range_etiquetas = np.arange(-20, 21, 20 / 2).tolist() window = 0 for j in range(self.InputList[i]["numeroE"]): self.InputList[i]["etiquetas"][j] = EtiquetasDic_creator( self, j, ini_range_etiquetas[window:window + 3] ) window += 1 for i in range(NumeroSalidas): self.main.outputNumber.insertItem(i, str(i + 1)) temp_dic = outputDic_creator(self, i) self.OutputList.append(temp_dic) ini_range_etiquetas = np.arange(-20, 21, 20 / 2).tolist() window = 0 for j in range(self.OutputList[i]["numeroE"]): self.OutputList[i]["etiquetas"][j] = EtiquetasDic_creator( self, j, ini_range_etiquetas[window:window + 3] ) window += 1 self.main.inputNumber.blockSignals(False) self.main.outputNumber.blockSignals(False) # Se inicializa el controlador con la informacion actual self.fuzzController = self.fuzzInitController(self.InputList, self.OutputList) seleccion_entrada(self) seleccion_salida(self) self.fuzzController.graficar_mf_in(self, 0) self.fuzzController.graficar_mf_out(self, 0) else: # En caso de que se seleccione un esquema y no entradas y salidas genericas cargar_esquema(self)
[documentos]def inputDic_creator(self, i): """ Funcion para crear entradas genericas :param i: Numero de entrada :type i: int """ inputDic = { "nombre": "entrada" + str(i + 1), "numeroE": 3, "etiquetas": [0] * 3, "rango": [-10, 10], } return inputDic
[documentos]def outputDic_creator(self, i): """ Funcion para crear salidas genericas :param i: Numero de salida :type i: int """ outputDic = { "nombre": "salida" + str(i + 1), "numeroE": 3, "etiquetas": [0] * 3, "rango": [-10, 10], "metodo": "centroid", } return outputDic
[documentos]def EtiquetasDic_creator(self, j, erange): """ Funcion para crear etiquetas genericas :param j: Numero de etiqueta :type j: int :param erange: Definicio de la funcion de membresia :type erange: list """ etiquetaDic = { "nombre": "etiqueta" + str(j + 1), "mf": "trimf", "definicion": round_list(erange), } return etiquetaDic
[documentos]def cargar_esquema(self): """ Funcion para iniciar el entorno de diseño a partir de un esquema de control seleccionado """ # Carga del archivo correspondiente al esquema seleccionado path = self.resource_path( "Esquemas/" + self.main.fuzzyEsquemas.currentText() + ".json" ) with open(path, "r") as f: self.InputList, self.OutputList, self.RuleEtiquetas = json.load(f) self.main.inputNombre.setReadOnly(True) self.main.outputNombre.setReadOnly(True) self.current_file = "" # Habilitar guardado de archivos self.main.guardarFuzzButton.setEnabled(True) self.main.guardarComoFuzzButton.setEnabled(True) self.main.exportarFuzzButton.setEnabled(True) self.main.inputNumber.blockSignals(True) self.main.outputNumber.blockSignals(True) # Se ocultan todos los tabs y se muestran solo Entradas, Salidas y Reglas self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) self.main.fuzzyTabWidget.removeTab(3) self.main.fuzzyTabWidget.removeTab(2) self.main.fuzzyTabWidget.removeTab(1) self.main.fuzzyTabWidget.addTab(self.EntradasTab, "Entradas") self.main.fuzzyTabWidget.addTab(self.SalidasTab, "Salidas") self.main.fuzzyTabWidget.addTab(self.ReglasTab, "Reglas") self.main.inputNumber.clear() self.main.outputNumber.clear() for i in range(len(self.InputList)): self.main.inputNumber.insertItem(i, str(i + 1)) for i in range(len(self.OutputList)): self.main.outputNumber.insertItem(i, str(i + 1)) self.main.inputNumber.blockSignals(False) self.main.outputNumber.blockSignals(False) # Se inicializa el controlador con la informacion actual self.fuzzController = self.fuzzInitController(self.InputList, self.OutputList, self.RuleEtiquetas) self.RuleList = copy.deepcopy(self.fuzzController.rulelist) seleccion_entrada(self) seleccion_salida(self) self.fuzzController.graficar_mf_in(self, 0) self.fuzzController.graficar_mf_out(self, 0) self.setWindowTitle( "Laboratorio Virtual - Nuevo controlador sin guardar*" )
[documentos]def guardar_controlador(self): """ Funcion manejar el guardado del controlador diseñado """ if len(self.current_file) > 0 and not '.fis' in self.current_file: with open(self.current_file, "w") as f: json.dump([self.InputList, self.OutputList, self.RuleEtiquetas], f, indent=4) else: guardarcomo_controlador(self)
[documentos]def guardarcomo_controlador(self): """ Funcion manejar el guardado en un nuevo archivo del controlador diseñado """ path_guardar = QtWidgets.QFileDialog.getSaveFileName(filter="JSON (*.json)") if len(path_guardar[0]) > 1: self.current_file = path_guardar[0] with open(path_guardar[0], "w") as f: json.dump([self.InputList, self.OutputList, self.RuleEtiquetas], f, indent=4) self.setWindowTitle( "Laboratorio Virtual - " + path_guardar[0].split("/")[-1] )
[documentos]def exportar_fis(self): """ Funcion manejar el exportado del controlador diseñado a formato .FIS """ path_guardar = QtWidgets.QFileDialog.getSaveFileName(filter="FIS (*.fis)") if len(path_guardar[0]) > 1: self.current_file = path_guardar[0] temp_parser = self.parser(self.current_file, self.InputList, self.OutputList, self.RuleEtiquetas) temp_parser.json_to_fis() self.setWindowTitle("Laboratorio Virtual - " + path_guardar[0].split("/")[-1])
[documentos]def cargar_controlador(self): """ Funcion manejar el cargado de controaldores previamente diseñados, se aceptan formatos .JSON y .FIS """ self.path_cargar = QtWidgets.QFileDialog.getOpenFileName(filter="JSON/FIS (*.json *.fis)") if len(self.path_cargar[0]) > 1: if '.json' in self.path_cargar[0]: with open(self.path_cargar[0], "r") as f: self.InputList, self.OutputList, self.RuleEtiquetas = json.load(f) else: temp_parser = self.parser(self.path_cargar[0]) try: self.InputList, self.OutputList, self.RuleEtiquetas = temp_parser.fis_to_json() except TypeError: self.error_dialog.setInformativeText("No se permiten salidas negadas") self.error_dialog.exec_() return # Habilitar guardado de archivos self.main.guardarFuzzButton.setEnabled(True) self.main.guardarComoFuzzButton.setEnabled(True) self.main.exportarFuzzButton.setEnabled(True) self.main.inputNombre.setReadOnly(False) self.main.outputNombre.setReadOnly(False) self.current_file = copy.deepcopy(self.path_cargar[0]) self.main.inputNumber.blockSignals(True) self.main.outputNumber.blockSignals(True) # Se ocultan todos los tabs y se muestran solo Entradas, Salidas y Reglas self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) self.main.fuzzyTabWidget.removeTab(3) self.main.fuzzyTabWidget.removeTab(2) self.main.fuzzyTabWidget.removeTab(1) self.main.fuzzyTabWidget.addTab(self.EntradasTab, "Entradas") self.main.fuzzyTabWidget.addTab(self.SalidasTab, "Salidas") self.main.fuzzyTabWidget.addTab(self.ReglasTab, "Reglas") self.main.inputNumber.clear() self.main.outputNumber.clear() for i in range(len(self.InputList)): self.main.inputNumber.insertItem(i, str(i + 1)) for i in range(len(self.OutputList)): self.main.outputNumber.insertItem(i, str(i + 1)) self.main.inputNumber.blockSignals(False) self.main.outputNumber.blockSignals(False) # Se inicializa el controlador con la informacion actual self.fuzzController = self.fuzzInitController(self.InputList, self.OutputList, self.RuleEtiquetas) self.RuleList = copy.deepcopy(self.fuzzController.rulelist) seleccion_entrada(self) seleccion_salida(self) self.fuzzController.graficar_mf_in(self, 0) self.fuzzController.graficar_mf_out(self, 0) self.setWindowTitle( "Laboratorio Virtual - " + self.path_cargar[0].split("/")[-1] )
[documentos]def seleccion_entrada(self): """ Funcion para desplegar la informacion de la entrada seleccionada """ ni = self.main.inputNumber.currentIndex() self.main.inputNombre.setText(self.InputList[ni]["nombre"]) self.main.inputEtiquetasNum.setText(str(self.InputList[ni]["numeroE"])) self.main.inputRange.setText(str(self.InputList[ni]["rango"])) self.main.etiquetaNumIn.clear() for j in range(self.InputList[ni]["numeroE"]): self.main.etiquetaNumIn.insertItem(j, str(j + 1)) self.main.etiquetaNombreIn.setText(self.InputList[ni]["etiquetas"][0]["nombre"]) self.main.etiquetaMfIn.setCurrentText(self.InputList[ni]["etiquetas"][0]["mf"]) self.main.etiquetaDefinicionIn.setText( str(self.InputList[ni]["etiquetas"][0]["definicion"]) ) self.fuzzController.graficar_mf_in(self, ni)
[documentos]def seleccion_salida(self): """ Funcion para desplegar la informacion de la salida seleccionada """ no = self.main.outputNumber.currentIndex() self.main.outputNombre.setText(self.OutputList[no]["nombre"]) self.main.outputEtiquetasNum.setText(str(self.OutputList[no]["numeroE"])) self.main.outputRange.setText(str(self.OutputList[no]["rango"])) self.main.defuzzMethodOut.setCurrentText(self.OutputList[no]["metodo"]) self.main.etiquetaNumOut.clear() for j in range(self.OutputList[no]["numeroE"]): self.main.etiquetaNumOut.insertItem(j, str(j + 1)) self.main.etiquetaNombreOut.setText(self.OutputList[no]["etiquetas"][0]["nombre"]) self.main.etiquetaMfOut.setCurrentText(self.OutputList[no]["etiquetas"][0]["mf"]) self.main.etiquetaDefinicionOut.setText( str(self.OutputList[no]["etiquetas"][0]["definicion"]) ) self.fuzzController.graficar_mf_out(self, no)
[documentos]def nombre_entrada(self): """ Funcion para manejar el cambio de nombre de la entrada seleccionada """ if self.main.inputNombre.text().strip() == '': self.error_dialog.setInformativeText( "El nombre no puede estar vacio") self.error_dialog.exec_() self.main.inputNombre.setFocus() return ni = self.main.inputNumber.currentIndex() self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) old_name = self.InputList[ni]["nombre"] flag = 0 for i in self.InputList: if ( i["nombre"] == self.main.inputNombre.text() and old_name != self.main.inputNombre.text() ): flag = 1 # Chequeo en caso de nombre repetido, se concatena un "1" en caso positivo if not flag: self.InputList[ni]["nombre"] = self.main.inputNombre.text() else: self.InputList[ni]["nombre"] = self.main.inputNombre.text() + "1" self.main.inputNombre.setText(self.InputList[ni]["nombre"]) self.fuzzController.cambiar_nombre_input(self, ni, self.InputList[ni]["nombre"]) # Se actualizan la reglas con el nuevo nombre self.fuzzController.rulelist = [] self.RuleList = self.fuzzController.crear_reglas(self.RuleEtiquetas) self.main.inputNombre.clearFocus()
[documentos]def nombre_salida(self): """ Funcion para manejar el cambio de nombre de la salida seleccionada """ if self.main.outputNombre.text().strip() == '': self.error_dialog.setInformativeText( "El nombre no puede estar vacio") self.error_dialog.exec_() self.main.outputNombre.setFocus() return no = self.main.outputNumber.currentIndex() self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) old_name = self.OutputList[no]["nombre"] flag = 0 for o in self.OutputList: if ( o["nombre"] == self.main.outputNombre.text() and old_name != self.main.outputNombre.text() ): flag = 1 # Chequeo en caso de nombre repetido, se concatena un "1" en caso positivo if not flag: self.OutputList[no]["nombre"] = self.main.outputNombre.text() else: self.OutputList[no]["nombre"] = self.main.outputNombre.text() + "1" self.main.outputNombre.setText(self.OutputList[no]["nombre"]) self.fuzzController.cambiar_nombre_output(self, no, self.OutputList[no]["nombre"]) # Se actualizan la reglas con el nuevo nombre self.fuzzController.rulelist = [] self.RuleList = self.fuzzController.crear_reglas(self.RuleEtiquetas) self.main.outputNombre.clearFocus()
[documentos]def numero_de_etiquetas_in(self): """ Funcion para manejar el numero de etiquetas para la entrada seleccionada """ try: _ = int(self.main.inputEtiquetasNum.text()) if _ < 1: raise ValueError except ValueError: self.error_dialog.setInformativeText( "El numero de etiquetas debe ser un valor entero mayor o igual a 1") self.error_dialog.exec_() self.main.inputEtiquetasNum.setFocus() return self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) ni = self.main.inputNumber.currentIndex() ne = int(self.main.inputEtiquetasNum.text()) # En caso de que el nuevo numero de etiquetas sea menor que el actual se procede a eliminar un numero # de etiquetas igual a la diferencia entre el nuevo valor y el valor actual. if self.InputList[ni]["numeroE"] > ne: self.main.etiquetaNumIn.blockSignals(True) # Eliminacion de las reglas que dependian de las etiquetas a eliminar for n in range(self.InputList[ni]["numeroE"] - 1, ne - 1, -1): new_list = [] for i, sets in enumerate(copy.deepcopy(self.RuleEtiquetas)): for rule in sets[0]: if ( rule[0] == self.InputList[ni]["etiquetas"][n]["nombre"] and rule[1] == ni ): break else: new_list.append(self.RuleEtiquetas[i]) break self.RuleEtiquetas = copy.deepcopy(new_list) self.main.etiquetaNumIn.removeItem(n) # Eliminacion de las etiquetas for _ in range(ne, self.InputList[ni]["numeroE"]): self.InputList[ni]["etiquetas"].pop() self.InputList[ni]["numeroE"] = ne self.RuleEtiquetas = copy.deepcopy(new_list) self.main.etiquetaNumIn.setCurrentIndex(ne - 1) self.main.etiquetaNombreIn.setText( self.InputList[ni]["etiquetas"][ne - 1]["nombre"] ) self.main.etiquetaDefinicionIn.setText( str(self.InputList[ni]["etiquetas"][ne - 1]["definicion"]) ) self.main.etiquetaMfIn.setCurrentText( self.InputList[ni]["etiquetas"][ne - 1]["mf"] ) # En caso de que el nuevo numero de etiquetas sea mayor que el actual se procede a agregar un numero # de etiquetas igual a la diferencia entre el nuevo valor y el valor actual. if self.InputList[ni]["numeroE"] < ne: self.main.etiquetaNumIn.blockSignals(True) rmin, rmax = self.InputList[ni]["rango"] # Creacion de funciones de membresia trimf genericas if (ne - self.InputList[ni]["numeroE"]) == 1: ini_range_etiquetas = [ self.vector_rotacion[self.rotacion_windowIn] * (rmax-rmin) + rmin, self.vector_rotacion[self.rotacion_windowIn + 1] * (rmax-rmin) + rmin, self.vector_rotacion[self.rotacion_windowIn + 2] * (rmax-rmin) + rmin, ] self.rotacion_windowIn += 1 if self.rotacion_windowIn > 4: self.rotacion_windowIn = 0 else: step = (rmax-rmin) / ((ne - self.InputList[ni]["numeroE"]) - 1) ini_range_etiquetas = np.arange(rmin - step, rmax + step + 1, step).tolist() window = 0 for j in range(self.InputList[ni]["numeroE"], ne): self.main.etiquetaNumIn.insertItem(j, str(j + 1)) self.InputList[ni]["etiquetas"].append( EtiquetasDic_creator(self, j, ini_range_etiquetas[window:window + 3]) ) window += 1 self.InputList[ni]["numeroE"] = ne # Se actualizan las etiquetas en el controlador self.fuzzController.cambio_etiquetas_input(self, self.InputList, ni) # Se actualizan la reglas con las nuevas etiquetas o la falta de ellas self.fuzzController.rulelist = [] self.RuleList = self.fuzzController.crear_reglas(self.RuleEtiquetas) self.main.inputEtiquetasNum.clearFocus() self.main.etiquetaNumIn.blockSignals(False)
[documentos]def numero_de_etiquetas_out(self): """ Funcion para manejar el numero de etiquetas para la salida seleccionada """ try: _ = int(self.main.outputEtiquetasNum.text()) if _ < 1: raise ValueError except ValueError: self.error_dialog.setInformativeText( "El numero de etiquetas debe ser un valor entero mayor o igual a 1") self.error_dialog.exec_() self.main.outputEtiquetasNum.setFocus() return self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) no = self.main.outputNumber.currentIndex() ne = int(self.main.outputEtiquetasNum.text()) # En caso de que el nuevo numero de etiquetas sea menor que el actual se procede a eliminar un numero # de etiquetas igual a la diferencia entre el nuevo valor y el valor actual. if self.OutputList[no]["numeroE"] > ne: self.main.etiquetaNumOut.blockSignals(True) # Eliminacion de las reglas que dependian de las etiquetas a eliminar for n in range(self.OutputList[no]["numeroE"] - 1, ne - 1, -1): new_list = [] for o, sets in enumerate(copy.deepcopy(self.RuleEtiquetas)): for rule in sets[1]: if ( rule[0] == self.OutputList[no]["etiquetas"][n]["nombre"] and rule[1] == no ): break else: new_list.append(self.RuleEtiquetas[o]) break self.RuleEtiquetas = copy.deepcopy(new_list) self.main.etiquetaNumOut.removeItem(n) # Eliminacion de las etiquetas for _ in range(ne, self.OutputList[no]["numeroE"]): self.OutputList[no]["etiquetas"].pop() self.OutputList[no]["numeroE"] = ne self.RuleEtiquetas = copy.deepcopy(new_list) self.main.etiquetaNumOut.setCurrentIndex(ne - 1) self.main.etiquetaNombreOut.setText( self.OutputList[no]["etiquetas"][ne - 1]["nombre"] ) self.main.etiquetaDefinicionOut.setText( str(self.OutputList[no]["etiquetas"][ne - 1]["definicion"]) ) self.main.etiquetaMfOut.setCurrentText( self.OutputList[no]["etiquetas"][ne - 1]["mf"] ) # En caso de que el nuevo numero de etiquetas sea mayor que el actual se procede a agregar un numero # de etiquetas igual a la diferencia entre el nuevo valor y el valor actual. if self.OutputList[no]["numeroE"] < ne: self.main.etiquetaNumOut.blockSignals(True) rmin, rmax = self.OutputList[no]["rango"] # Creacion de funciones de membresia trimf genericas if (ne - self.OutputList[no]["numeroE"]) == 1: ini_range_etiquetas = [ self.vector_rotacion[self.rotacion_windowOut] * (rmax-rmin) + rmin, self.vector_rotacion[self.rotacion_windowOut + 1] * (rmax-rmin) + rmin, self.vector_rotacion[self.rotacion_windowOut + 2] * (rmax-rmin) + rmin, ] self.rotacion_windowOut += 1 if self.rotacion_windowOut > 4: self.rotacion_windowOut = 0 else: step = (rmax-rmin) / ((ne - self.OutputList[no]["numeroE"]) - 1) ini_range_etiquetas = np.arange(rmin - step, rmax + step + 1, step).tolist() window = 0 for j in range(self.OutputList[no]["numeroE"], ne): self.main.etiquetaNumOut.insertItem(j, str(j + 1)) self.OutputList[no]["etiquetas"].append( EtiquetasDic_creator(self, j, ini_range_etiquetas[window:window + 3]) ) window += 1 self.OutputList[no]["numeroE"] = ne # Se actualizan las etiquetas en el controlador self.fuzzController.cambio_etiquetas_output(self, self.OutputList, no) # Se actualizan la reglas con las nuevas etiquetas o la falta de ellas self.fuzzController.rulelist = [] self.RuleList = self.fuzzController.crear_reglas(self.RuleEtiquetas) self.main.outputEtiquetasNum.clearFocus() self.main.etiquetaNumOut.blockSignals(False)
[documentos]def rango_in(self): """ Funcion para manejar el rango para la entrada seleccionada """ try: _ = json.loads(self.main.inputRange.text()) if len(_) > 2 or len(_) < 2: raise ValueError except ValueError: self.error_dialog.setInformativeText( "Rango no valido, el rango debe estar entre corchetes y los valores separados por coma.\n i.g., [-10, 10]" ) self.error_dialog.exec_() self.main.inputRange.setFocus() return self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) ni = self.main.inputNumber.currentIndex() self.InputList[ni]["rango"] = json.loads(self.main.inputRange.text()) # Se actualiza el rango y las etiquetas self.fuzzController.update_rango_input(self, self.InputList, ni) self.fuzzController.cambio_etiquetas_input(self, self.InputList, ni) self.main.inputRange.clearFocus()
[documentos]def rango_out(self): """ Funcion para manejar el rango para la salida seleccionada """ try: _ = json.loads(self.main.outputRange.text()) if len(_) > 2 or len(_) < 2: raise ValueError except ValueError: self.error_dialog.setInformativeText( "Rango no valido, el rango debe estar entre corchetes y los valores separados por coma.\n i.g., [-10, 10]" ) self.error_dialog.exec_() self.main.outputRange.setFocus() return self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) no = self.main.outputNumber.currentIndex() self.OutputList[no]["rango"] = json.loads(self.main.outputRange.text()) # Se actualiza el rango y las etiquetas self.fuzzController.update_rango_output(self, self.OutputList, no) self.fuzzController.cambio_etiquetas_output(self, self.OutputList, no) self.main.outputRange.clearFocus()
[documentos]def defuzz_metodo(self): """ Funcion para manejar el metodo de defuzzificacion para la salida seleccionada """ self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) no = self.main.outputNumber.currentIndex() self.OutputList[no]["metodo"] = self.main.defuzzMethodOut.currentText() metodo = self.OutputList[no]["metodo"] # Se actualiza el metodo de defuzzificacion self.fuzzController.cambiar_metodo(self, no, metodo)
[documentos]def seleccion_etiqueta_in(self): """ Funcion para desplegar la informacion de la etiqueta seleccionada de la entrada actual """ ni = self.main.inputNumber.currentIndex() ne = self.main.etiquetaNumIn.currentIndex() self.main.etiquetaNombreIn.setText(self.InputList[ni]["etiquetas"][ne]["nombre"]) self.main.etiquetaMfIn.blockSignals(True) self.main.etiquetaMfIn.setCurrentText(self.InputList[ni]["etiquetas"][ne]["mf"]) self.main.etiquetaDefinicionIn.setText( str(self.InputList[ni]["etiquetas"][ne]["definicion"]) ) self.main.etiquetaMfIn.blockSignals(False)
[documentos]def seleccion_etiqueta_out(self): """ Funcion para desplegar la informacion de la etiqueta seleccionada de la salida actual """ no = self.main.outputNumber.currentIndex() ne = self.main.etiquetaNumOut.currentIndex() self.main.etiquetaNombreOut.setText(self.OutputList[no]["etiquetas"][ne]["nombre"]) self.main.etiquetaMfOut.blockSignals(True) self.main.etiquetaMfOut.setCurrentText(self.OutputList[no]["etiquetas"][ne]["mf"]) self.main.etiquetaDefinicionOut.setText( str(self.OutputList[no]["etiquetas"][ne]["definicion"]) ) self.main.etiquetaMfOut.blockSignals(False)
[documentos]def nombre_etiqueta_in(self): """ Funcion para manejar el cambio de nombre de la etiqueta seleccionada de la entrada actual """ if self.main.etiquetaNombreIn.text().strip() == '': self.error_dialog.setInformativeText( "El nombre no puede estar vacio") self.error_dialog.exec_() self.main.etiquetaNombreIn.setFocus() return ni = self.main.inputNumber.currentIndex() ne = self.main.etiquetaNumIn.currentIndex() self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) old_name = self.InputList[ni]["etiquetas"][ne]["nombre"] flag = 0 for i in self.InputList[ni]["etiquetas"]: if ( i["nombre"] == self.main.etiquetaNombreIn.text() and old_name != self.main.etiquetaNombreIn.text() ): flag = 1 # Chequeo en caso de nombre repetido, se concatena un "1" en caso positivo if not flag: self.InputList[ni]["etiquetas"][ne]["nombre"] = self.main.etiquetaNombreIn.text() else: self.InputList[ni]["etiquetas"][ne]["nombre"] = ( self.main.etiquetaNombreIn.text() + "1" ) self.main.etiquetaNombreIn.setText(self.InputList[ni]["etiquetas"][ne]["nombre"]) self.fuzzController.cambio_etinombre_input(self, self.InputList, ni, ne, old_name) # Se actualizan la reglas con el nuevo nombre de la etiqueta if len(self.RuleList) > 0: actualizar_RulesEtiquetas_in(self, ni, self.main.etiquetaNombreIn.text(), old_name) self.main.etiquetaNombreIn.clearFocus()
[documentos]def actualizar_RulesEtiquetas_in(self, ni, new_name, old_name): """ Funcion para actualizar el nombre en las reglas previamente creadas con el nuevo nombre de una etiqueta :param ni: Numero de entrada :type ni: int :param new_name: Nuevo nombre para la etiqueta a cambiar :type new_name: str :param old_name: Antiguo nombre de la etiqueta a cambiar :type old_name: str """ for sets in self.RuleEtiquetas: for rule in sets[0]: if rule[0] == old_name and rule[1] == ni: rule[0] = new_name self.fuzzController.rulelist = [] self.RuleList = self.fuzzController.crear_reglas(self.RuleEtiquetas)
[documentos]def nombre_etiqueta_out(self): """ Funcion para manejar el cambio de nombre de la etiqueta seleccionada de la salida actual """ if self.main.etiquetaNombreOut.text().strip() == '': self.error_dialog.setInformativeText( "El nombre no puede estar vacio") self.error_dialog.exec_() self.main.etiquetaNombreOut.setFocus() return no = self.main.outputNumber.currentIndex() ne = self.main.etiquetaNumOut.currentIndex() self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) old_name = self.OutputList[no]["etiquetas"][ne]["nombre"] flag = 0 for i in self.OutputList[no]["etiquetas"]: if ( i["nombre"] == self.main.etiquetaNombreOut.text() and old_name != self.main.etiquetaNombreOut.text() ): flag = 1 # Chequeo en caso de nombre repetido, se concatena un "1" en caso positivo if not flag: self.OutputList[no]["etiquetas"][ne]["nombre"] = self.main.etiquetaNombreOut.text( ) else: self.OutputList[no]["etiquetas"][ne]["nombre"] = ( self.main.etiquetaNombreOut.text() + "1" ) self.main.etiquetaNombreOut.setText( self.OutputList[no]["etiquetas"][ne]["nombre"] ) self.fuzzController.cambio_etinombre_output(self, self.OutputList, no, ne, old_name) # Se actualizan la reglas con el nuevo nombre if len(self.RuleList) > 0: actualizar_RulesEtiquetas_out( self, no, self.main.etiquetaNombreOut.text(), old_name ) self.main.etiquetaNombreOut.clearFocus()
[documentos]def actualizar_RulesEtiquetas_out(self, no, new_name, old_name): """ Funcion para actualizar el nombre en las reglas previamente creadas con el nuevo nombre de una etiqueta :param no: Numero de salida :type no: int :param new_name: Nuevo nombre para la etiqueta a cambiar :type new_name: str :param old_name: Antiguo nombre de la etiqueta a cambiar :type old_name: str """ for sets in self.RuleEtiquetas: for rule in sets[1]: if rule[0] == old_name and rule[1] == no: rule[0] = new_name self.fuzzController.rulelist = [] self.RuleList = self.fuzzController.crear_reglas(self.RuleEtiquetas)
[documentos]def seleccion_mf_in(self): """ Funcion para manejar el cambio de funcion de membresia para la etiqueta seleccionada """ self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) ni = self.main.inputNumber.currentIndex() ne = self.main.etiquetaNumIn.currentIndex() # Se guarda el nombre de la funcion de membresia anterior old_mf = self.InputList[ni]["etiquetas"][ne]["mf"] definicion = self.InputList[ni]["etiquetas"][ne]["definicion"] self.InputList[ni]["etiquetas"][ne]["mf"] = self.main.etiquetaMfIn.currentText() # Se guarda el nombre de la funcion de membresia seleccionada new_mf = self.InputList[ni]["etiquetas"][ne]["mf"] # Se obtiene una definicion aproximada entre la antigua funcion de membresia y la seleccionada new_definicion, tooltip = update_definicionmf(self, old_mf, definicion, 'trimf') new_definicion, tooltip = update_definicionmf(self, 'trimf', new_definicion, self.main.etiquetaMfIn.currentText()) new_definicion = round_list(new_definicion) self.main.etiquetaDefinicionIn.setText(str(new_definicion)) self.main.etiquetaDefinicionIn.setToolTip(tooltip) # Se actualiza la nueva definicion a mostrar definicion_in(self)
[documentos]def definicion_in(self): """ Funcion para manejar el cambio de definicion de la funcion de membresia correspondiente a la etiqueta actual """ try: deinificion_in_validator(self) except AssertionError: return self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) ni = self.main.inputNumber.currentIndex() ne = self.main.etiquetaNumIn.currentIndex() self.InputList[ni]["etiquetas"][ne]["definicion"] = json.loads( self.main.etiquetaDefinicionIn.text()) # Se actualiza la nueva definicion en el controlador self.fuzzController.update_definicion_input(self, self.InputList, ni, ne) self.main.etiquetaDefinicionIn.clearFocus()
[documentos]def deinificion_in_validator(self): """ Funcion para validar las definiciones de las funciones de membresia """ mf = self.main.etiquetaMfIn.currentText() try: _ = json.loads(self.main.etiquetaDefinicionIn.text()) try: # Funcion externa para la validacion validacion_mf(self, _, mf) except AssertionError: self.main.etiquetaDefinicionIn.setFocus() raise AssertionError except ValueError: self.error_dialog.setInformativeText( "Formato de definicion invalido para la funcion de membresia: " + mf + "\nDebe estar entre corchetes con valores separados por comas") self.error_dialog.exec_() self.main.etiquetaDefinicionIn.setFocus() raise AssertionError
[documentos]def seleccion_mf_out(self): """ Funcion para manejar el cambio de funcion de membresia para la etiqueta seleccionada """ self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) no = self.main.outputNumber.currentIndex() ne = self.main.etiquetaNumOut.currentIndex() # Se guarda el nombre de la funcion de membresia anterior old_mf = self.OutputList[no]["etiquetas"][ne]["mf"] definicion = self.OutputList[no]["etiquetas"][ne]["definicion"] self.OutputList[no]["etiquetas"][ne]["mf"] = self.main.etiquetaMfOut.currentText() # Se guarda el nombre de la funcion de membresia seleccionada new_mf = self.OutputList[no]["etiquetas"][ne]["mf"] # Se obtiene una definicion aproximada entre la antigua funcion de membresia y la seleccionada new_definicion, tooltip = update_definicionmf(self, old_mf, definicion, 'trimf') new_definicion, tooltip = update_definicionmf(self, 'trimf', new_definicion, self.main.etiquetaMfOut.currentText()) new_definicion = round_list(new_definicion) self.main.etiquetaDefinicionOut.setText(str(new_definicion)) self.main.etiquetaDefinicionOut.setToolTip(tooltip) # Se actualiza la nueva definicion a mostrar definicion_out(self)
[documentos]def definicion_out(self): """ Funcion para manejar el cambio de definicion de la funcion de membresia correspondiente a la etiqueta actual """ try: deinificion_out_validator(self) except AssertionError: return self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) no = self.main.outputNumber.currentIndex() ne = self.main.etiquetaNumOut.currentIndex() self.OutputList[no]["etiquetas"][ne]["definicion"] = json.loads( self.main.etiquetaDefinicionOut.text()) # Se actualiza la nueva definicion en el controlador self.fuzzController.update_definicion_output(self, self.OutputList, no, ne) self.main.etiquetaDefinicionOut.clearFocus()
[documentos]def deinificion_out_validator(self): """ Funcion para validar las definiciones de las funciones de membresia """ mf = self.main.etiquetaMfOut.currentText() try: _ = json.loads(self.main.etiquetaDefinicionOut.text()) try: # Funcion externa para la validacion validacion_mf(self, _, mf) except AssertionError: self.main.etiquetaDefinicionOut.setFocus() raise AssertionError except ValueError: self.error_dialog.setInformativeText( "Formato de definicion invalido para la funcion de membresia: " + mf + "\nDebe estar entre corchetes con valores separados por comas") self.error_dialog.exec_() self.main.etiquetaDefinicionOut.setFocus() raise AssertionError
[documentos]def round_list(lista): """ Funcion para redondear los digitos de una lista """ return list(np.around(np.array(lista), 3))
[documentos]def rule_list_visualizacion(self): """ Funcion para mostrar las reglas creadas para el controlador actual en un listWidget """ if self.main.fuzzyTabWidget.currentIndex() == 3: self.main.rulelistWidget.blockSignals(True) self.main.rulelistWidget.clear() for regla in self.RuleList: self.main.rulelistWidget.addItem(str(regla)) # Se ocultan los widgets necesarios en funcion del numero de entradas y salidas for i, o in zip(self.inframes, self.outframes): i.hide() o.hide() for i, o in zip(self.inlists, self.outlists): i.clear() o.clear() self.main.rulelistWidget.setCurrentRow(0) # Se muestran los widgets necesarios en funcion del numero de entradas for i, entrada in enumerate(self.InputList): self.inframes[i].show() self.inlabels[i].setText(entrada["nombre"]) for etiqueta in entrada["etiquetas"]: self.inlists[i].addItem(etiqueta["nombre"]) self.inlists[i].addItem("None") self.inlists[i].setCurrentRow(0) # Se muestran los widgets necesarios en funcion del numero de salidas for o, salida in enumerate(self.OutputList): self.outframes[o].show() self.outlabels[o].setText(salida["nombre"]) for etiqueta in salida["etiquetas"]: self.outlists[o].addItem(etiqueta["nombre"]) self.outlists[o].addItem("None") self.outlists[o].setCurrentRow(0) self.main.rulelistWidget.blockSignals(False) seleccionar_etiquetas(self)
[documentos]def seleccionar_etiquetas(self): """ Funcion para seleccionar las etiquetas correspodientes a cada entrada/salida de la regla seleccionada """ if len(self.RuleEtiquetas) > 0: ni = len(self.InputList) no = len(self.OutputList) ruleindex = self.main.rulelistWidget.currentRow() Etiquetasin, Etiquetasout, logica = self.RuleEtiquetas[ruleindex] # Chequeo de AND o OR if logica: self.main.andradioButton.setChecked(True) else: self.main.orradioButton.setChecked(True) # Determinando que etiquetas corresponden a cada entrada for index in range(ni): for Etiquetasin2 in Etiquetasin: if Etiquetasin2[1] == index: item = self.inlists[index].findItems( Etiquetasin2[0], QtCore.Qt.MatchExactly ) self.inlists[index].setCurrentItem(item[-1]) if Etiquetasin2[2]: self.innots[index].setChecked(True) else: self.innots[index].setChecked(False) break else: item = self.inlists[index].findItems("None", QtCore.Qt.MatchExactly) self.inlists[index].setCurrentItem(item[-1]) self.innots[index].setChecked(False) # Determinando que etiquetas corresponden a cada salida for index in range(no): for Etiquetasout2 in Etiquetasout: if Etiquetasout2[1] == index: item = self.outlists[index].findItems( Etiquetasout2[0], QtCore.Qt.MatchExactly ) self.outlists[index].setCurrentItem(item[-1]) self.outweights[index].setValue(Etiquetasout2[2]) break else: item = self.outlists[index].findItems("None", QtCore.Qt.MatchExactly) self.outlists[index].setCurrentItem(item[-1])
[documentos]def rule_list_agregar(self): """ Funcion para crear una nueva regla a partir de las etiquetas seleccionadas para cada entrada y salida """ self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) ni = len(self.InputList) no = len(self.OutputList) Etiquetasin = [] Etiquetasout = [] # Informacion de la entrada para la regla for i, entrada in enumerate(self.InputList): if self.inlists[i].currentItem().text() != "None": Etiquetasin.append( [self.inlists[i].currentItem().text(), i, self.innots[i].isChecked()] ) # Informacion de la salida para la regla for o, salida in enumerate(self.OutputList): if self.outlists[o].currentItem().text() != "None": Etiquetasout.append( [self.outlists[o].currentItem().text(), o, self.outweights[o].value()] ) # Si la regla es valida, se agrega al controlador y al listWidget if len(Etiquetasin) > 0 and len(Etiquetasout) > 0: self.RuleEtiquetas.append( copy.deepcopy( [Etiquetasin, Etiquetasout, self.main.andradioButton.isChecked()])) self.RuleList.append( self.fuzzController.agregar_regla(self, Etiquetasin, Etiquetasout, self.main.andradioButton.isChecked())) self.main.rulelistWidget.addItem(str(self.RuleList[-1])) self.main.rulelistWidget.setCurrentRow(len(self.RuleList) - 1) else: self.error_dialog.setInformativeText( "Regla no valida, debe contener al menos una entrada y una salida" ) self.error_dialog.exec_()
[documentos]def rule_list_eliminar(self): """ Funcion para eliminar una regla """ self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) if self.main.rulelistWidget.count(): index_rule = self.main.rulelistWidget.currentRow() self.fuzzController.eliminar_regla(index_rule) self.main.rulelistWidget.takeItem(self.main.rulelistWidget.currentRow()) del self.RuleList[index_rule] del self.RuleEtiquetas[index_rule]
[documentos]def rule_list_cambiar(self): """ Funcion para modificar una regla """ self.main.fuzzyTabWidget.removeTab(5) self.main.fuzzyTabWidget.removeTab(4) index_rule = self.main.rulelistWidget.currentRow() ni = len(self.InputList) no = len(self.OutputList) Etiquetasin = [] Etiquetasout = [] # Informacion de la entrada para la nueva regla for i, entrada in enumerate(self.InputList): if self.inlists[i].currentItem().text() != "None": Etiquetasin.append( [self.inlists[i].currentItem().text(), i, self.innots[i].isChecked()] ) # Informacion de la salida para la nueva regla for o, salida in enumerate(self.OutputList): if self.outlists[o].currentItem().text() != "None": Etiquetasout.append( [self.outlists[o].currentItem().text(), o, self.outweights[o].value()] ) # Si la nueva regla es valida, se elimina la anterior y se agrega al controlador y al listWidget if len(Etiquetasin) > 0 and len(Etiquetasout) > 0: del self.RuleEtiquetas[index_rule] self.RuleEtiquetas.insert( index_rule, copy.deepcopy( [Etiquetasin, Etiquetasout, self.main.andradioButton.isChecked()] ), ) regla = self.fuzzController.cambiar_regla(self, Etiquetasin, Etiquetasout, index_rule, self.main.andradioButton.isChecked()) self.main.rulelistWidget.takeItem(index_rule) self.main.rulelistWidget.insertItem(index_rule, str(regla)) self.main.rulelistWidget.setCurrentRow(index_rule) del self.RuleList[index_rule] self.RuleList.insert(index_rule, regla) else: self.error_dialog.setInformativeText( "Regla no valida, debe contener al menos una entrada y una salida" ) self.error_dialog.exec_()
[documentos]def crear_controlador(self): """ Funcion para crear el controlador a partir de toda la informacion recolectada, esta creacion se realiza con el fin de realizar la prueba del controlador y observar la superficie de respuesta del controlador en caso de poseer una o dos entradas """ if self.main.rulelistWidget.count(): self.fuzzController = self.fuzzInitController( self.InputList, self.OutputList, self.RuleEtiquetas ) self.RuleList = copy.deepcopy(self.fuzzController.rulelist) self.main.fuzzyTabWidget.addTab(self.PruebaTab, "Prueba") ni = len(self.InputList) no = len(self.OutputList) # Se ocultan los widgets necesarios en funcion del numero de entradas y salidas for it_f, ot_f, f2d, f3d in zip( self.intestframes, self.outtestframes, self.respuesta2dframes, self.respuesta3dframes, ): it_f.hide() ot_f.hide() f2d.hide() f3d.hide() # Se muestran los widgets necesarios en funcion del numero de entradas for i, salida in enumerate(self.InputList): self.intestframes[i].show() # Se muestran los widgets necesarios en funcion del numero de salidas for o, salida in enumerate(self.OutputList): self.outtestframes[o].show() # Ejecucion del codigo correspondiente a la prueba del controlador prueba_input(self) # Chequeo del numero de entradas if ni == 1: self.main.fuzzyTabWidget.addTab(self.RespuestaTab, "Respuesta") self.main.respuestastackedWidget.setCurrentIndex(0) for o, salida in enumerate(self.OutputList): self.respuesta2dframes[o].show() rimin, rimax = self.InputList[0]["rango"] self.fuzzController.graficar_respuesta_2d(self, [rimin, rimax], no) if ni == 2: self.main.fuzzyTabWidget.addTab(self.RespuestaTab, "Respuesta") self.main.respuestastackedWidget.setCurrentIndex(1) for o, salida in enumerate(self.OutputList): self.respuesta3dframes[o].show() rimin1, rimax1 = self.InputList[0]["rango"] rimin2, rimax2 = self.InputList[1]["rango"] self.fuzzController.graficar_respuesta_3d( self, [rimin1, rimax1], [rimin2, rimax2], no )
[documentos]def prueba_input(self): """ Funcion para la ejecucion del codigo correspondiente a la prueba del controlador """ ni = len(self.InputList) no = len(self.OutputList) # Captura de los valores de entrada values = [i.value() for i in self.intestsliders[:ni]] for i, entrada in enumerate(self.InputList[:ni]): rmin, rmax = entrada["rango"] values[i] = values[i] * (rmax-rmin) / 1000 + rmin self.intestlabels[i].setText(entrada["nombre"] + f": {np.around(values[i], 3)}") self.fuzzController.prueba_de_controlador(self, values, ni, no)
[documentos]def crear_vectores_de_widgets(self): """ Funcion para el almacenado de widgets en listas para acceder a ellos por indices """ self.inframes = [ self.main.inframe1, self.main.inframe2, self.main.inframe3, self.main.inframe4, self.main.inframe5, self.main.inframe6, self.main.inframe7, self.main.inframe8, self.main.inframe9, self.main.inframe10, ] self.outframes = [ self.main.outframe1, self.main.outframe2, self.main.outframe3, self.main.outframe4, self.main.outframe5, self.main.outframe6, self.main.outframe7, self.main.outframe8, self.main.outframe9, self.main.outframe10, ] self.inlists = [ self.main.inlist1, self.main.inlist2, self.main.inlist3, self.main.inlist4, self.main.inlist5, self.main.inlist6, self.main.inlist7, self.main.inlist8, self.main.inlist9, self.main.inlist10, ] self.outlists = [ self.main.outlist1, self.main.outlist2, self.main.outlist3, self.main.outlist4, self.main.outlist5, self.main.outlist6, self.main.outlist7, self.main.outlist8, self.main.outlist9, self.main.outlist10, ] self.inlabels = [ self.main.inlabel1, self.main.inlabel2, self.main.inlabel3, self.main.inlabel4, self.main.inlabel5, self.main.inlabel6, self.main.inlabel7, self.main.inlabel8, self.main.inlabel9, self.main.inlabel10, ] self.outlabels = [ self.main.outlabel1, self.main.outlabel2, self.main.outlabel3, self.main.outlabel4, self.main.outlabel5, self.main.outlabel6, self.main.outlabel7, self.main.outlabel8, self.main.outlabel9, self.main.outlabel10, ] self.innots = [ self.main.innot1, self.main.innot2, self.main.innot3, self.main.innot4, self.main.innot5, self.main.innot6, self.main.innot7, self.main.innot8, self.main.innot9, self.main.innot10, ] self.intestframes = [ self.main.intestframe1, self.main.intestframe2, self.main.intestframe3, self.main.intestframe4, self.main.intestframe5, self.main.intestframe6, self.main.intestframe7, self.main.intestframe8, self.main.intestframe9, self.main.intestframe10, ] self.outtestframes = [ self.main.outtestframe1, self.main.outtestframe2, self.main.outtestframe3, self.main.outtestframe4, self.main.outtestframe5, self.main.outtestframe6, self.main.outtestframe7, self.main.outtestframe8, self.main.outtestframe9, self.main.outtestframe10, ] self.intestsliders = [ self.main.intestslider1, self.main.intestslider2, self.main.intestslider3, self.main.intestslider4, self.main.intestslider5, self.main.intestslider6, self.main.intestslider7, self.main.intestslider8, self.main.intestslider9, self.main.intestslider10, ] self.ingraphs = [ self.main.ingraph1, self.main.ingraph2, self.main.ingraph3, self.main.ingraph4, self.main.ingraph5, self.main.ingraph6, self.main.ingraph7, self.main.ingraph8, self.main.ingraph9, self.main.ingraph10, ] self.outgraphs = [ self.main.outgraph1, self.main.outgraph2, self.main.outgraph3, self.main.outgraph4, self.main.outgraph5, self.main.outgraph6, self.main.outgraph7, self.main.outgraph8, self.main.outgraph9, self.main.outgraph10, ] self.intestlabels = [ self.main.intestlabel1, self.main.intestlabel2, self.main.intestlabel3, self.main.intestlabel4, self.main.intestlabel5, self.main.intestlabel6, self.main.intestlabel7, self.main.intestlabel8, self.main.intestlabel9, self.main.intestlabel10, ] self.outtestlabels = [ self.main.outtestlabel1, self.main.outtestlabel2, self.main.outtestlabel3, self.main.outtestlabel4, self.main.outtestlabel5, self.main.outtestlabel6, self.main.outtestlabel7, self.main.outtestlabel8, self.main.outtestlabel9, self.main.outtestlabel10, ] self.respuesta3dframes = [ self.main.respuesta3dframe1, self.main.respuesta3dframe2, self.main.respuesta3dframe3, self.main.respuesta3dframe4, self.main.respuesta3dframe5, self.main.respuesta3dframe6, self.main.respuesta3dframe7, self.main.respuesta3dframe8, self.main.respuesta3dframe9, self.main.respuesta3dframe10, ] self.respuesta2dframes = [ self.main.respuesta2dframe1, self.main.respuesta2dframe2, self.main.respuesta2dframe3, self.main.respuesta2dframe4, self.main.respuesta2dframe5, self.main.respuesta2dframe6, self.main.respuesta2dframe7, self.main.respuesta2dframe8, self.main.respuesta2dframe9, self.main.respuesta2dframe10, ] self.respuesta3ds = [ self.main.respuesta3d1, self.main.respuesta3d2, self.main.respuesta3d3, self.main.respuesta3d4, self.main.respuesta3d5, self.main.respuesta3d6, self.main.respuesta3d7, self.main.respuesta3d8, self.main.respuesta3d9, self.main.respuesta3d10, ] self.respuesta2ds = [ self.main.respuesta2d1, self.main.respuesta2d2, self.main.respuesta2d3, self.main.respuesta2d4, self.main.respuesta2d5, self.main.respuesta2d6, self.main.respuesta2d7, self.main.respuesta2d8, self.main.respuesta2d9, self.main.respuesta2d10, ] self.outweights = [ self.main.outweight1, self.main.outweight2, self.main.outweight3, self.main.outweight4, self.main.outweight5, self.main.outweight6, self.main.outweight7, self.main.outweight8, self.main.outweight9, self.main.outweight10, ]