Skip to content

Instantly share code, notes, and snippets.

@misaelvillaverde
Created June 6, 2021 02:43
Show Gist options
  • Select an option

  • Save misaelvillaverde/0f46bc420910c8e43c5016698367f29b to your computer and use it in GitHub Desktop.

Select an option

Save misaelvillaverde/0f46bc420910c8e43c5016698367f29b to your computer and use it in GitHub Desktop.
# 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