Created
June 6, 2021 02:43
-
-
Save misaelvillaverde/0f46bc420910c8e43c5016698367f29b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Circular linked list implementation | |
| """ | |
| Se desea llevar un control de las temperaturas diarias en la ciudad, los atributos de la clase Temperaturas son: fecha (dd,mm,yy) y temperatura máxima; utilizar una lista simplemente ligada circular que realice los siguientes procedimientos: | |
| • insertar en forma ordenada en base a la fecha. | |
| • mostrar la temperatura más alta y la fecha. | |
| • eliminar un registro ´x´. | |
| • mostrar los datos. | |
| • modificar una temperatura. | |
| """ | |
| import re | |
| from datetime import datetime | |
| # Nodo Temperatura | |
| class Temperatura: | |
| def __init__(self, fecha: datetime, maxTemp: int): | |
| self.fecha = fecha | |
| self.maxTemp = maxTemp | |
| self.next = self | |
| def __repr__(self): | |
| string = f"fecha: {self.fecha.date()} | temperatura: {self.maxTemp}" | |
| return string | |
| # Lista enlazada circular | |
| class ListaEnlazadaCircular: | |
| def __init__(self): | |
| # Inicializa los atributos | |
| self.head = None | |
| self.count = 0 | |
| #---------------------Imprime los valores del objeto-----------------------# | |
| def __repr__(self): | |
| string = "Registros actuales\n" | |
| if(self.head == None): | |
| string += "Lista vacía" | |
| return string | |
| string += f"fecha: {self.head.fecha.date()} | temperatura: {self.head.maxTemp}" | |
| temp = self.head.next | |
| while(temp != self.head): | |
| string += f" -> \nfecha: {temp.fecha.date()} | temperatura: {temp.maxTemp}" | |
| temp = temp.next | |
| return string | |
| #----------------------------------------------------------------------# | |
| def append(self, fecha: str, maxTemp: int) -> bool: | |
| """Inserta un nodo (fecha, temperatura) en orden en la lista circular""" | |
| # Verifica que la fecha este en el formato correcto | |
| if (not self.verificarFecha(fecha)): | |
| return False | |
| # Castear la fecha de tipo string a datetime para aplicarle logica | |
| try: | |
| fecha = datetime.strptime(fecha, "%d,%m,%y") | |
| except ValueError: | |
| print(f"{FAIL}Error en la fecha{ENDC}, ejemplo: 31 de Febrero") | |
| return | |
| # Crear el nuevo nodo, que va a ser insertado | |
| new_node = Temperatura(fecha, maxTemp) | |
| # Insertar en head si la lista circular esta vacia | |
| if self.head == None: | |
| self.head = new_node | |
| self.count += 1 | |
| return True | |
| # Insertar antes o despues de head, si solo existe head en la lista | |
| if self.count == 1: | |
| if (new_node.fecha >= self.head.fecha): | |
| self.head.next = new_node | |
| new_node.next = self.head | |
| else: | |
| new_node.next = self.head | |
| self.head.next = new_node | |
| self.head = new_node | |
| self.count += 1 | |
| return True | |
| # Iterar sobre la lista hasta encontrar la posicion | |
| temp = self.head | |
| for _ in range(self.count-1): | |
| # Insertar el nodo temperatura por orden de fecha | |
| if (new_node.fecha >= temp.fecha and new_node.fecha < temp.next.fecha): | |
| # Conecta el nuevo nodo a el nodo siguiente a temp | |
| new_node.next = temp.next | |
| # Conecta a temp con el nuevo nodo | |
| temp.next = new_node | |
| return True | |
| temp = temp.next | |
| # Al salir del for anterior solo quedan los casos: es mayor que el ultimo, o es menor que el primero | |
| if (new_node.fecha >= temp.fecha): | |
| # Conecta el nuevo nodo a el nodo siguiente a temp | |
| new_node.next = temp.next | |
| # Conecta a temp con el nuevo nodo | |
| temp.next = new_node | |
| else: | |
| # Conecta el ultimo nodo al nuevo [...temp.next] -> [new_node: x] | |
| temp.next = new_node | |
| # Conecta el nuevo nodo a la cabeza [new_node: x] -> [head] | |
| new_node.next = self.head | |
| # Cambia la cabeza al nuevo nodo [head: x] | |
| self.head = new_node | |
| self.count += 1 | |
| return True | |
| def verificarFecha(self, fecha: str) -> bool: | |
| """Regular expression para verificar que la fecha esta en el formato solicitado""" | |
| match = re.search( | |
| "(0?[1-9]|1[1-9]|2[1-9]|3[01]),(0?[1-9]|1[012]),\d{2}", fecha) | |
| if (match): | |
| return True | |
| # else | |
| print(f"{FAIL}Fecha invalida{ENDC}, debe ser en el formato (dd,mm,yy)") | |
| return False | |
| def mostrarMaxTemp(self): | |
| # [5] -> [8] -> [2] | |
| maxT = self.head.maxTemp | |
| temp = self.head | |
| max_node = self.head | |
| for _ in range(self.count): | |
| if (temp.maxTemp >= maxT): | |
| max_node = temp | |
| maxT = temp.maxTemp | |
| temp = temp.next | |
| print(max_node) | |
| def delRegister(self, fecha: str) -> bool: | |
| """Elimina un nodo (fecha, temperatura) de la lista circular""" | |
| # Verifica que la fecha este en el formato correcto | |
| if (not self.verificarFecha(fecha)): | |
| return False | |
| # Castear la fecha de tipo string a datetime para aplicarle logica | |
| try: | |
| fecha = datetime.strptime(fecha, "%d,%m,%y") | |
| except ValueError: | |
| print(f"{FAIL}Error en la fecha{ENDC}, ejemplo: 31 de Febrero") | |
| return | |
| # Itera sobre la lista hasta hallar la fecha | |
| temp = self.head | |
| for _ in range(self.count-1): | |
| if (temp.next.fecha == fecha): | |
| # Eliminar nodo de la lista, conectando el nodo actual al siguiente nodo del nodo a eliminar | |
| temp.next = temp.next.next | |
| self.count -= 1 | |
| return True | |
| temp = temp.next | |
| # Si salimos del for posiblemente el nodo a eliminar es el head | |
| if (self.head.fecha == fecha): | |
| # Conecto el nodo actual (el ultimo de la lista al salir del for) con el siguiente del head | |
| temp.next = self.head.next | |
| # Asigno el nuevo head | |
| self.head = temp.next | |
| self.count -= 1 | |
| return True | |
| # De otro modo | |
| print("Fecha no encontrada") | |
| return False | |
| def modTemp(self, fecha: str, nmaxT: int) -> bool: | |
| """Modifica un nodo (fecha, temperatura) de la lista circular""" | |
| # Verifica que la fecha este en el formato correcto | |
| if (not self.verificarFecha(fecha)): | |
| return False | |
| # Castear la fecha de tipo string a datetime para aplicarle logica | |
| try: | |
| fecha = datetime.strptime(fecha, "%d,%m,%y") | |
| except ValueError: | |
| print(f"{FAIL}Error en la fecha{ENDC}, ejemplo: 31 de Febrero") | |
| return | |
| # Itera sobre la lista hasta hallar la fecha | |
| temp = self.head | |
| for _ in range(self.count): | |
| if (temp.fecha == fecha): | |
| # Modificar nodo con nueva temperatura | |
| temp.maxTemp = nmaxT | |
| return True | |
| temp = temp.next | |
| # De otro modo | |
| print("Fecha no encontrada") | |
| return False | |
| def isEmpty(self) -> bool: | |
| if (self.head == None): | |
| print("La lista circular esta vacia") | |
| input("(enter)") | |
| return True | |
| return False | |
| # Colores | |
| HEADER = '\033[95m' | |
| OKBLUE = '\033[94m' | |
| OKGREEN = '\033[92m' | |
| WARNING = "\033[93m" | |
| FAIL = '\033[91m' | |
| ENDC = '\033[0m' | |
| BOLD = '\033[1m' | |
| UNDERLINE = '\033[4m' | |
| def main(): | |
| print(f"{HEADER}---------------------------------") | |
| print("Temperaturas Diarias en la Ciudad") | |
| print(f"---------------------------------{ENDC}") | |
| lista = ListaEnlazadaCircular() | |
| e = True | |
| while(e): | |
| print("---------------------------------") | |
| print(f"{OKBLUE}1. Insertar temperatura") | |
| print("2. Mostrar temperatura más alta") | |
| print("3. Eliminar un registro") | |
| print("4. Mostrar las temperaturas") | |
| print("5. Modificar una temperatura") | |
| print(f"{WARNING}6. Salir{OKBLUE}") | |
| print(f"{OKGREEN}") | |
| option = int(input("> ")) | |
| print(f"{OKBLUE}") | |
| if (option == 1): | |
| fecha = input("Inserte la fecha (formato: dd,mm,yy): ") | |
| maxTemp = int(input("Inserte la temperatura maxima de ese dia: ")) | |
| if(lista.append(fecha, maxTemp)): | |
| print("Fecha y temperatura insertados exitosamente en la lista") | |
| else: | |
| print("Vuelva a intentar") | |
| input("(enter)") | |
| elif (option == 2 and not lista.isEmpty()): | |
| print("Temperatura maxima: ", end='') | |
| lista.mostrarMaxTemp() | |
| input("(enter)") | |
| elif (option == 3 and not lista.isEmpty()): | |
| fecha = input("Inserte la fecha (formato: dd,mm,yy): ") | |
| if(lista.delRegister(fecha)): | |
| print("Registro eliminado correctamente") | |
| else: | |
| print("Vuelva a intentar") | |
| input("(enter)") | |
| elif (option == 4): | |
| print(lista) | |
| input("(enter)") | |
| elif (option == 5 and not lista.isEmpty()): | |
| fecha = input("Inserte la fecha (formato: dd,mm,yy): ") | |
| nmaxT = int(input("Inserte nueva temperatura: ")) | |
| if(lista.modTemp(fecha, nmaxT)): | |
| print("Registro modificado exitosamente") | |
| else: | |
| print("Vuelva a intentar") | |
| input("(enter)") | |
| elif (option == 6): | |
| print(f"{OKGREEN}Hasta la proxima{ENDC}") | |
| e = False | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment