def agregar_conexion(self, desde, hasta, largo, confirmado=False): if not confirmado: # Corresponden los tipos: if self.siguiente[desde.nodo] != hasta.nodo: raise ForbiddenAction(desde, hasta, self.agregar_conexion, "tipo") # Si hasta es casa, verificar que desde es de la misma comuna: elif hasta.nodo == "C" and desde.comuna != hasta.comuna: raise ForbiddenAction(desde, hasta, self.agregar_conexion, "comuna") # Si hasta es estacion elevadora, verificar que generadora no # tenga una previamente elif hasta.nodo == "E" and len(desde.children) > 0: raise ForbiddenAction(desde, hasta, self.agregar_conexion, "GE") # Verificar relaciones 1 a n elif desde.nodo in Tupla("E", "T") and len(hasta.parent) > 0: raise ForbiddenAction(desde, hasta, self.agregar_conexion, f"{desde.nodo}{hasta.nodo}") elif desde in hasta.children.descomprimir(0) or hasta in \ desde.parent.descomprimir(0): raise ForbiddenAction(desde, hasta, self.agregar_conexion, "ciclo") elif hasta in desde.children.descomprimir(0): raise ForbiddenAction(desde, hasta, self.agregar_conexion, "yasellama") desde.children.agregar(Tupla(hasta, largo)) hasta.hasta.agregar(Tupla(desde, largo))
def conectar(self, diccionario_d, diccionario_h, datos, desde_hasta=True): lista = Lista() for i in datos.items(): lista.agregar(i[1]) desde, hasta, longitud = lista if not desde_hasta: desde, hasta = hasta, desde diccionario_d[desde].children.agregar( Tupla(diccionario_h[hasta], longitud)) diccionario_h[hasta].parent.agregar( Tupla(diccionario_d[desde], longitud))
def __init__(self, desde, hasta, funcion, tipo="tipo"): if tipo == "tipo": tupla = Tupla(funcion.__name__, desde.clase, hasta.clase) texto = "Acción {} no está permitida entre {} y {}" elif tipo in Tupla("comuna", "provincia"): if desde.clase == hasta.clase: entidad = "casas" else: entidad = "casas y subestaciones" tupla = Tupla(funcion.__name__, entidad, tipo) texto = "Acción {} no está permitida entre {} que tienen {} " \ "distintas." elif tipo == "ciclo": tupla = Tupla(funcion.__name__) texto = "Acción {} no está permitida entre nodos " \ "previamente conectados porque se " \ "formaría un ciclo" elif tipo in ("GE", "ET", "TD"): if tipo == "GE": tupla = Tupla(funcion.__name__, desde.clase, hasta.clase) elif tipo in Tupla("ET", "TD"): tupla = Tupla(funcion.__name__, hasta.clase, desde.clase) texto = "Acción {} no está permitida porque esta {} ya tiene una " \ "{}." elif "sellama" in tipo: mensaje = tipo[:2] tupla = Tupla(funcion.__name__, mensaje) texto = "Accion {} no se completará porque esta conexión {} existe." super().__init__(texto.format(*tupla))
def modificar_aristas(self): try: mensaje("modificar_arista") ingreso = entrada(">>> ") while ingreso != "": try: descifrado = descifrar_input_conexion(ingreso) except ErrorEntrada as error: mensaje("error_entrada", error) else: try: desde = self.diccionario[descifrado[1][0]][ descifrado[1][1]] hasta = self.diccionario[descifrado[2][0]][ descifrado[2][1]] except InvalidQuery as error: mensaje("excepcion", Tupla("InvalidQuery", error)) raise Volver() else: if descifrado[0] == "+": print("A continuación puede ingresar la distancia " "que separa a estos nodos") distancia = entrada(">>> Distancia: ") while not distancia.replace('.', '', 1).isnumeric(): print( "Estamos teniendo problemas para leer el " "input") print("Por favor, inténtelo de nuevo :D") distancia = entrada(">>> Distancia: ") try: self.agregar_conexion(desde, hasta, distancia) except ForbiddenAction as error: print("Error:", error) print("Puede intentarlo nuevamente :D") elif descifrado[0] == "-": try: self.remover_conexion(desde, hasta) except ForbiddenAction as error: mensaje("excepcion", Tupla("ForbiddenAction", error)) finally: ingreso = entrada(">>> ") except Volver: self.modificar_aristas()
def __init__(self, datos, tipo="C", inicio=True): super().__init__(tipo) if inicio: valores = Lista() for elemento in datos.items(): valores.agregar(elemento[1]) else: valores = datos self.id, self.sistema, self.provincia, self.comuna, \ self.consumo_datos = valores if self.sistema == "AYSEN": self.sistema = "SEA" elif self.sistema == "MAGALLANES": self.sistema = "SEM" if self.consumo in Tupla(-1, "-1"): self.consumo = self.consumo_datos self.seccion_transversal = 85 self.nodo_parent = "D" self.nodo = "C" self.nodo_children = "C" self.clase = "Casa" self.consumo = float(self.consumo)
def calcular_demanda(self): for nodo in self.generadoras.valores(): nodo.calcular_demanda() for grupo in Tupla(self.generadoras, self.elevadoras, self.transmision, self.distribucion, self.casas): for nodo in grupo.valores(): nodo.demanda_calculada = False
def flujo(self, primero=Nodo("G")): ### El método BFS fue extraído de los contenidos del curso :D visited = Conjunto() if primero.tipo == "G": for i in self.elevadoras.valores(): primero.children.agregar(Tupla(i, 0)) queue = Cola(primero) while queue: nodo = queue.popleft() vertex = nodo.valor if vertex not in visited: if vertex.nodo != "G": visited.add(vertex) if vertex.nodo == "E": print("jeje") vertex.potencia = float(vertex.potencia_elevadora) else: vertex.consumo = min(float(vertex.consumo_datos), float(vertex.potencia)) vertex.potencia_restante = float(vertex.potencia) - \ float(vertex.consumo) valores_mij = Tupla() for child in vertex.children.descomprimir(0): valores_mij.agregar(float(child.mij)) potencias_entregar = proporciones(valores_mij, \ vertex.potencia_restante) for num in range_(len(potencias_entregar)): valor_mij = potencias_entregar[num] nodo_num = vertex.children.descomprimir(0)[num] nodo_num.potencia = \ max(valor_mij - (valor_mij * resistividad * float( vertex.children.descomprimir(1)[num]) / nodo_num.seccion_transversal), 0) nodo_num.mij, nodo_num.mij_0 = valor_mij, nodo_num.mij for n in vertex.children: v = n[0] if v not in visited: queue.append(v) return visited
def remover_nodo(self): try: mensaje("remover_nodo") numero_tipo = entrada(">>> ") while numero_tipo.strip() not in Tupla("0", "1", "2", "3", "4"): mensaje("error") numero_tipo = entrada(">>> ") print("-" * 80) grupos = Tupla(self.generadoras, self.elevadoras, self.transmision, self.distribucion, self.casas) grupo = grupos[int(numero_tipo)] numero_nodo = input_lista( grupo.valores(), f">>> " f"{self.nombres[int(numero_tipo)]}: ") nodo_ = grupo.valores()[numero_nodo] borrado = grupo.pop(nodo_.id).valor print(f"Se quitó el nodo: {borrado}") except Volver: self.remover_nodo()
def mayor_menor_consumo(self, sistema, tipo=0): sistema = str(sistema).strip().upper() if sistema not in self.sistemas.llaves(): raise InvalidQuery(sistema, "sistema") if int(tipo) == 1: nodo = max(self.casas.valores(), key=lambda i: float(i.consumo)) accion = "mayor" elif int(tipo) == 2: accion = "menor" nodo = min(self.casas.valores(), key=lambda i: float(i.consumo)) return Tupla(accion, nodo.id, nodo.provincia, nodo.comuna)
def consumo_total(self, comuna): comuna = str(comuna).strip().upper() if comuna not in self.comunas: raise InvalidQuery(comuna, "comuna") consumo_casas = float() consumo_total = float() for casa in self.casas.valores(): if casa.comuna == comuna: consumo_casas += float(casa.consumo) consumo_total += float(casa.consumo) for grupo in Tupla(self.elevadoras, self.transmision, self.distribucion): for nodo in grupo.valores(): if nodo.comuna == comuna: consumo_total += float(nodo.consumo) if consumo_total == 0: porcentaje = 100 else: porcentaje = (consumo_casas / consumo_total) * 100 return Tupla(consumo_casas, porcentaje)
def consulta(self): try: opcion = mensaje("consultas") if int(opcion) == 0: mensaje("consumo_total") respuesta = input_lista(self.comunas, otro=True) if respuesta == "*": comuna = entrada(">>> Comuna: ").strip().upper() else: comuna = self.comunas[respuesta] consumo, porcentaje = self.consumo_total(comuna) print(f"La comuna {comuna} tiene un consumo de " f"{consumo} kW (un {round(porcentaje, 2)}% del " f"total)") elif int(opcion) in Tupla(1, 2): mensaje("mayor_menor_consumo") sigla = entrada(">>> Sigla: ") accion, id_, provincia, comuna = self.mayor_menor_consumo( sigla, opcion) print(f"Los datos de la casa con {accion} consumo son:") print(f"Casa: id = {id_}, Provincia = {provincia}, Comuna =" f" {comuna}") elif int(opcion) == 3: mensaje("perdida_potencia") id_ = entrada(">>> id: ") resultado = self.potencia_perdida(id_) print(f"La potencia de perdida en la transmisión es de " f"{resultado} kW.") elif int(opcion) == 4: tipo, id_ = mensaje("consumo_subestacion") respuesta = self.consumo_subestacion(id_, tipo) print(f"El consumo total de esta subestación es de " f"{respuesta} kW.") except InvalidQuery as error: mensaje("excepcion", Tupla("InvalidQuery", error)) self.consulta() except Volver: self.consulta()
def __init__(self, datos, tipo, inicio=True): super().__init__(tipo) if inicio: valores = Lista() for elemento in datos.items(): valores.agregar(elemento[1]) else: valores = datos self.id, self.nombre, self.sistema, self.provincia, self.comuna, \ self.consumo_datos = valores if self.consumo in Tupla(-1, "-1"): self.consumo = self.consumo_datos self.nodo = tipo if tipo == "E": self.tipo = "Estacion Elevadora" self.seccion_transversal = 253 elif tipo == "T": self.tipo = "Subestacion de Transmisión" self.seccion_transversal = 202.7 elif tipo == "D": self.tipo = "Subestación de Distribución" self.seccion_transversal = 152 if self.sistema == "AYSEN": self.sistema = "SEA" elif self.sistema == "MAGALLANES": self.sistema = "SEM" self.clase = self.tipo self.nodo_parent = Nodo.tipos[Nodo.tipos.find(self.nodo) - 1] self.nodo_children = Nodo.tipos[Nodo.tipos.find(self.nodo) + 1] self.consumo = float(self.consumo) * 1000
def __init__(self): self.casas = Diccionario() self.generadoras = Diccionario() self.distribucion = Diccionario() self.elevadoras = Diccionario() self.transmision = Diccionario() self.diccionario = Diccionario( Tupla(Tupla("C", self.casas), Tupla("G", self.generadoras), Tupla("D", self.distribucion), Tupla("E", self.elevadoras), Tupla("T", self.transmision))) self.siguiente = Diccionario( Tupla(Tupla("C", "C"), Tupla("G", "E"), Tupla("D", "C"), Tupla("E", "T"), Tupla("T", "D"))) self.lugares = DiccionarioPorDefecto(Conjunto) self.comunas = Conjunto() self.sistemas = DiccionarioPorDefecto(Conjunto) self.tipos_centrales = Tupla("Solar", "Termoelectrica", "Biomasa") self.nombres = Tupla("Central Generadora", "Estación Elevadora", "Subestación de Transmisión", "Subestación de " "Distribución", "Casa")
def mensaje(tipo="-", opcional=""): grupos = Tupla("Central Generadora", "Estación de Elevación", "Subestación de Transmisión", "Subestación de " "Distribución", "Casa") if tipo == "modificar_arista": print("_" * 80) print("AGREGAR O ELIMINAR CONEXIÓN") print("-" * 80) print("A continuación, puede ingresar lo conexión a agregar/eliminar") print("La forma para ingresarlo es:") print("Xi * Yj") print("Donde:\n" "* <X> corresponde al tipo de conexión del nodo de donde " "comienza la conexión") print("* <Y> es el tipo de conexión del nodo de destino") print("* <i> es la id del nodo X") print("* <j> es la id del nodo Y") print("* <*> corresponde a la acción a realizar") print("-" * 80) print("Tipos de conexión y acciones:") print("G: Central Generadora, E: Estación de Elevación") print("T: Subestación de Transmisión, D: Subestación de Distribución") print("C: Casas, +: Agragar Conexión, -: Quitar Conexión") print("-" * 80) print("Ejemplos:") print("G0 - E2 ---> Quita conexión entre la Central(0) y la " "EstaciónElevadora(2)") print("T2 + D3 ---> Agrega una conexión entre el Transmisor(2) y la " "Distribuidora(3)") print("-" * 80) elif tipo == "modificar_aristas_clasico": print("_" * 80) print("AGREGAR O ELIMINAR CONEXIÓN (CLÁSICO)") print("-" * 80) mensaje("listado") print("-" * 80) print("A continuación puede ingresar el [número] correspondiente al " "tipo de nodo :D") elif tipo == "consultas": print("_" * 80) print("CONSULTAS") print("-" * 80) print("A continuación puede ingresar el [número] de la consulta :D") return input_lista(Tupla("Energía total consumida en una comuna", "Cliente " "con mayor consumo energético", "Cliente con menor " "consumo energético", "Potencia perdida en " "transmisión", "Consumo de una subestación"), ">>> ") elif tipo == "consumo_total": print("-" * 80) print("Ahora puede ingresar el [numero] de la comuna :D") elif tipo == "mayor_menor_consumo": print("-" * 80) print("Ahora puede ingresar la sigla del sistema eléctrico a " "consultar :D") elif tipo == "perdida_potencia": print("-" * 80) print("Ahora puede ingresar la id de la casa a consultar :D") elif tipo == "consumo_subestacion": print("-" * 80) print("¿Qué tipo de subestación desea consultar?") num = input_lista(Tupla("Subestación de Transmisión", "Subestación de " "Distribución")) if int(num) == 0: nodo = "T" elif int(num) == 1: nodo = "D" print("Ahora puede ingresar la id de la subestación a consultar :D") id_ = entrada(">>> id:") return Tupla(nodo, id_) elif tipo == "error_entrada": print("(Error) ErrorEntrada", opcional) print("Lo sentimos :O Estamos teniendo problemas para " "entender lo ingresado") print("Por favor, inténtelo de nuevo :D") elif tipo in Tupla("agregar_nodo", "remover_nodo"): print("_" * 80) if tipo == "agregar_nodo": print("AGREGAR NODO") elif tipo == "remover_nodo": print("REMOVER NODO") print("-" * 80) mensaje("listado") print("-" * 80) print("A continuación puede ingresar el [número] correspondiente al " "tipo de nodo :D") elif tipo == "error": print("Estamos teniendo problemas para entender el input") print("Por favor, inténtelo de nuevo :D") elif tipo == "excepcion": print(f"(Error) {opcional[0]}: {opcional[1]}") print("¡Lo sentimos! Puedes intentarlo de nuevo :D ") elif tipo == "listado": for n in range_(len(grupos)): print(f"[{n}] {grupos[n]}") elif tipo == "menu": print("_" * 80) print("Bienvenid@ a Electromatic :D") print("_" * 80) print("A continuación se muestran las opciones disponibles:")
def modificar_aristas_clasico(self): try: mensaje("modificar_aristas_clasico") numero_tipo = entrada(">>> ") while numero_tipo.strip() not in Tupla("0", "1", "2", "3", "4"): mensaje("error") numero_tipo = entrada(">>> ") print("-" * 80) grupos = Tupla(self.generadoras, self.elevadoras, self.transmision, self.distribucion, self.casas, self.casas) grupo = grupos[int(numero_tipo)] numero_nodo = input_lista( grupo.valores(), f">>> " f"{self.nombres[int(numero_tipo)]}: ") nodo_ = grupo.valores()[numero_nodo] print("-" * 80) print("¿Qué acción desea realizar?") numero_accion = int( input_lista(Tupla("Añadir Conexión", "Quitar " "Conexión"), ">>> ")) if int(numero_tipo) == 0: numero_respuesta = 0 else: numero_respuesta = int( input_lista( Tupla("Este nodo es quien " "inicia la conexión", "Este nodo es el receptor"), ">>> ")) print("-" * 80) print("Ahora puede elegir el otro nodo :D") if numero_accion == 0: if numero_respuesta == 0: numero_child = input_lista( grupos[int(numero_tipo) + 1].valores(), ">>> ") desde = nodo_ hasta = desde.children.descomprimir(0)[numero_child] elif numero_respuesta == 1: numero_parent = input_lista( grupos[int(numero_tipo) - 1].valores(), ">>> ") hasta = nodo_ desde = hasta.parent.descomprimir(0)[numero_parent] print("Ahora, puedes ingresar la distancia que hay entre los " "nodos :D") distancia = entrada(">>> Distancia: ") while not distancia.replace('.', '', 1).isnumeric(): print("Estamos teniendo problemas para leer el " "input") print("Por favor, inténtelo de nuevo :D") distancia = entrada(">>> Distancia: ") try: self.agregar_conexion(desde, hasta, distancia) except ForbiddenAction as error: mensaje("excepcion", Tupla("ForbiddenAction", error)) raise Volver() elif numero_accion == 1: if numero_respuesta == 0: numero_child = input_lista(nodo_.children.descomprimir(0), ">>> ") desde = nodo_ hasta = desde.children.descomprimir(0)[numero_child] elif numero_respuesta == 1: numero_parent = input_lista(nodo_.parent.descomprimir(0), ">>> ") hasta = nodo_ desde = hasta.parent.descomprimir(0)[numero_parent] try: self.remover_conexion(desde, hasta, confirmado=True) except ForbiddenAction as error: mensaje("excepcion", Tupla("ForbbidenAction", error)) raise Volver() except Volver: self.modificar_aristas_clasico()
ruta = f"bd/{tipo_datos}" ###################### if __name__ == '__main__': grafo = SistemaElectrico() grafo.cargar_datos(ruta) grafo.cargar_conexiones(ruta) grafo.calcular_demanda() grafo.simular_flujo() while True: try: mensaje("menu") opciones = Tupla("Generar Consulta", "Agregar Nodo", "Remover Nodo", "Añadir o Quitar Conexiones (Classic)", "Añadir o Quitar Conexiones (Modo Hackermen)") respuesta = int(input_lista(opciones, ">>> ")) if respuesta == 0: grafo.consulta() elif respuesta == 1: grafo.agregar_nodo() elif respuesta == 2: grafo.remover_nodo() elif respuesta == 3: grafo.modificar_aristas_clasico() elif respuesta == 4: grafo.modificar_aristas() except Volver: pass
def agregar_nodo(self): try: mensaje("agregar_nodo") numero_tipo = entrada(">>> ") while numero_tipo.strip() not in Tupla("0", "1", "2", "3", "4"): mensaje("error") numero_tipo = entrada(">>> ") print("-" * 80) presentacion = "A continuación puede ingresar los datos de la {} " \ "nueva.\nEn algunos campos se tiene la " \ "posibilidad de presionar [ENTER] para " \ "ingresar un valor al azar." titulos = self.nombres grupos = Tupla(self.generadoras, self.elevadoras, self.transmision, self.distribucion, self.casas) grupo = grupos[int(numero_tipo)] tipo_estacion = "GETDC"[int(numero_tipo)] print(presentacion.format(f"{titulos[int(numero_tipo)]}")) # 0. ID print("-" * 80) id_ = entrada(">>> id: ") while grupo.existe(id_): if id_ == "": id_ = grupo.llave_random() else: print("Esta id ya existe, por favor elige otra :D") id_ = entrada(">>> id: ") if id_ == "": id_ = grupo.llave_random() print(f"id seleccionada: {id_}") print("-" * 80) if int(numero_tipo) != 4: # 1. Nombre nombre_ = entrada(">>> Nombre: ") print("-" * 80) print(f"nombre seleccionada: {nombre_}") # 2. Sistema numero_sistema = input_lista(self.sistemas.llaves(), ">>> Sistema Eléctrico: ") sistema_ = self.sistemas.llaves()[numero_sistema] print(f"sistema electrico seleccionada: {sistema_}") print("-" * 80) # 3. Provincia numero_provincia = input_lista(self.sistemas[sistema_], ">>> Provincia: ", True) if numero_provincia == "*": provincia_ = entrada(">>> Provincia (nombre): ").upper() else: provincia_ = self.sistemas[sistema_][numero_provincia] print(f"provincia seleccionada: {provincia_}") print("-" * 80) # 4. Comuna numero_comuna = input_lista(self.lugares[provincia_], ">>> Comuna: ", True) if numero_comuna == "*": comuna_ = entrada(">>> Comuna (nombre): ").upper() else: comuna_ = self.lugares[provincia_][numero_comuna] print(f"comuna seleccionada: {comuna_}") print("-" * 80) if int(numero_tipo) == 0: # 5. Tipo numero_tipo = input_lista(self.tipos_centrales, ">>> Tipo: ") tipo_ = self.tipos_centrales[numero_tipo] print(f"tipo seleccionado: {tipo_}") print("-" * 80) # 6. Potencia potencia_ = entrada(">>> Potencia (MW): ") while not potencia_.replace('.', '', 1).isnumeric(): print("No pudimos entender tu input :O " "inténtelo de nuevo por favor :D") potencia_ = entrada(">>> Potencia (MW): ") central_ = Generadora(Tupla(id_, nombre_, sistema_, provincia_, comuna_, tipo_, potencia_), inicio=False) self.generadoras[central_.id] = central_ self.lugares[provincia_].add(comuna_) self.comunas.add(comuna_) elif int(numero_tipo) in Tupla(1, 2, 3): # 6. Consumo consumo_ = entrada(">>> Consumo (MW): ") while not consumo_.replace('.', '', 1).isnumeric(): print("No pudimos entender tu input :O " "inténtelo de nuevo por favor :D") consumo_ = entrada(">>> Consumo (MW): ") estacion_ = Estacion(Tupla(id_, nombre_, sistema_, provincia_, comuna_, consumo_), inicio=False, tipo=tipo_estacion) grupo[estacion_.id] = estacion_ self.lugares[provincia_].add(comuna_) self.comunas.add(comuna_) elif int(numero_tipo) == 4: # 6. Consumo consumo_ = entrada(">>> Consumo (kW): ") while not consumo_.replace('.', '', 1).isnumeric(): print("No pudimos entender tu input :O " "inténtelo de nuevo por favor :D") consumo_ = entrada(">>> Consumo (kW): ") casa_ = Casa(Tupla(id_, sistema_, provincia_, comuna_, consumo_), inicio=False) self.casas[casa_.id] = casa_ self.lugares[provincia_].add(comuna_) self.comunas.add(comuna_) except Volver: self.agregar_nodo()