Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys
- import pickle
- from functools import total_ordering
- from pdb import set_trace
- def nulo_o_vacio(texto):
- return texto == None or not texto.strip()
- def valida_franja_entero(pregunta, inicio, fin, estandar=None):
- while True:
- try:
- entrada = input(pregunta)
- if nulo_o_vacio(entrada) and estandar != None:
- entrada = estandar
- valor = int(entrada)
- if inicio <= valor <= fin:
- return(valor)
- except ValueError:
- print("Valor inválido, favor digitar entre %d y %d" % (inicio, fin))
- def valida_franja_entero_o_blanco(pregunta, inicio, fin):
- while True:
- try:
- entrada = input(pregunta)
- if nulo_o_vacio(entrada):
- return None
- valor = int(entrada)
- if inicio <= valor <= fin:
- return(valor)
- except ValueError:
- print("Valor inválido, favor digitar entre %d y %d" % (inicio, fin))
- class ListaUnica:
- def __init__(self, elem_class):
- self.lista = []
- self.elem_class = elem_class
- def __len__(self):
- return len(self.lista)
- def __iter__(self):
- return iter(self.lista)
- def __getitem__(self, p):
- return self.lista[p]
- def indiceValido(self, i):
- return i >= 0 and i < len(self.lista)
- def adiciona(self, elem):
- if self.investigacion(elem) == -1:
- self.lista.append(elem)
- def remove(self, elem):
- self.lista.remove(elem)
- def investigacion(self, elem):
- self.verifica_tipo(elem)
- try:
- return self.lista.index(elem)
- except ValueError:
- return -1
- def verifica_tipo(self, elem):
- if type(elem) != self.elem_class:
- raise TypeError("Tipo inválido")
- def ordena(self, clave=None):
- self.lista.sort(key=clave)
- @total_ordering
- class Nombre:
- def __init__(self, nombre):
- self.nombre = nombre
- def __str__(self):
- return self.nombre
- def __repr__(self):
- return "<Clase {3} en 0x{0:x} Nombre: {1} Clave: {2}>".format(
- id(self), self.__nombre, self.__clave, type(self).__name__)
- def __eq__(self, otro):
- return self.nombre == otro.nombre
- def __lt__(self, otro):
- return self.nombre < otro.nombre
- @property
- def nombre(self):
- return self.__nombre
- @nombre.setter
- def nombre(self, valor):
- if nulo_o_vacio(valor):
- raise ValueError("Nombre no puede ser nulo ni en blanco")
- self.__nombre = valor
- self.__clave = Nombre.CreaClave(valor)
- @property
- def clave(self):
- return self.__clave
- @staticmethod
- def CreaClave(nombre):
- return nombre.strip().lower()
- @total_ordering
- class TipoTelefono:
- def __init__(self, tipo):
- self.tipo = tipo
- def __str__(self):
- return "({0})".format(self.tipo)
- def __eq__(self, otro):
- if otro is None:
- return False
- return self.tipo == otro.tipo
- def __lt__(self, otro):
- return self.tipo < otro.tipo
- class Telefono:
- def __init__(self, numero, tipo=None):
- self.numero = numero
- self.tipo = tipo
- def __str__(self):
- if self.tipo!=None:
- tipo = self.tipo
- else:
- tipo = ""
- return "{0} {1}".format(self.numero, tipo)
- def __eq__(self, otro):
- return (self.numero == otro.numero and ((self.tipo == otro.tipo) or (self.tipo == None or otro.tipo == None))
- @property
- def número(self):
- return self.__número
- @número.setter
- def número(self, valor):
- if nulo_o_vacio(valor):
- raise ValueError("Número no puede ser None o en blanco")
- self.__número = valor
- class Telefonos(ListaUnica):
- def __init__(self):
- super().__init__(Telefono)
- class TiposTelefono(ListaUnica):
- def __init__(self):
- super().__init__(TipoTelefono)
- class DatoAgenda:
- def __init__(self, nombre):
- self.nombre = nombre
- self.telefonos = Telefonos()
- @property
- def nombre(self):
- return self.__nombre
- @nombre.setter
- def nombre(self, valor):
- if type(valor) != Nombre:
- raise TypeError("nombre debe ser una instancia de la clase Nombre")
- self.__nombre = valor
- def investigacionTelefono(self, telefono):
- posicion = self.telefonos.investigacion(Telefono(telefono))
- if posicion == -1:
- return None
- else:
- return self.telefonos[posicion]
- class Agenda(ListaUnica):
- def __init__(self):
- super().__init__(DatoAgenda)
- self.tiposTelefono = TiposTelefono()
- def adicionaTipo(self, tipo):
- self.tiposTelefono.adiciona(TipoTelefono(tipo))
- def investigacionNombre(self, nombre):
- if type(nombre) == str:
- nombre = Nombre(nombre)
- for datos in self.lista:
- if datos.nombre == nombre:
- return datos
- else:
- return None
- def ordena(self):
- super().ordena(lambda dato: str(dato.nombre))
- class Menu:
- def __init__(self):
- self.opciones = [["Salir", None]]
- def adicionaopcion(self, nombre, funcion):
- self.opciones.append([nombre, funcion])
- def exhibe(self):
- print("====")
- print("Menú")
- print("====\n")
- for i, opcion in enumerate(self.opciones):
- print("[{0}] - {1}".format(i, opcion[0]))
- print()
- def ejecute(self):
- while True:
- self.exhibe()
- elija = valida_franja_entero("Elija una opción: ",
- 0, len(self.opciones) - 1)
- if elija == 0:
- break
- self.opciones[elija][1]()
- class AppAgenda:
- @staticmethod
- def pide_nombre():
- return(input("Nombre: "))
- @staticmethod
- def pide_telefono():
- return(input("Teléfono: "))
- @staticmethod
- def muestra_datos(datos):
- print("Nombre: %s" % datos.nombre)
- for telefono in datos.telefonos:
- print("Teléfono: %s" % telefono)
- print()
- @staticmethod
- def muestra_datos_telefono(datos):
- print("Nombre: %s" % datos.nombre)
- for i, telefono in enumerate(datos.telefonos):
- print("{0} - Teléfono: {1}".format(i, telefono))
- print()
- @staticmethod
- def pide_nombre_archivo():
- return(input("Nombre del archivo: "))
- def __init__(self):
- self.agenda = Agenda()
- self.agenda.adicionaTipo("Celular")
- self.agenda.adicionaTipo("Residencia")
- self.agenda.adicionaTipo("Trabajo")
- self.agenda.adicionaTipo("Fax")
- self.menu = Menu()
- self.menu.adicionaopcion("Nuevo", self.nuevo)
- self.menu.adicionaopcion("Altera", self.altera)
- self.menu.adicionaopcion("Borra", self.borra)
- self.menu.adicionaopcion("Lista", self.lista)
- self.menu.adicionaopcion("Graba", self.graba)
- self.menu.adicionaopcion("Lee", self.lee)
- self.menu.adicionaopcion("Ordena", self.ordena)
- self.ultimo_nombre = None
- def pide_tipo_telefono(self, estandar=None):
- for i, tipo in enumerate(self.agenda.tiposTelefono):
- print(" {0} - {1} ".format(i, tipo), end=None)
- t = valida_franja_entero("Tipo: ", 0, len(self.agenda.tiposTelefono) - 1, estandar)
- return self.agenda.tiposTelefono[t]
- def investigacion(self, nombre):
- dato = self.agenda.investigacionNombre(nombre)
- return dato
- def nuevo(self):
- nuevo = AppAgenda.pide_nombre()
- if nulo_o_vacio(nuevo):
- return
- nombre = Nombre(nuevo)
- if self.investigacion(nombre) != None:
- print("¡Nombre ya existe!")
- return
- registro = DatoAgenda(nombre)
- self.menu_telefonos(registro)
- self.agenda.adiciona(registro)
- def borra(self):
- if len(self.agenda) == 0:
- print("Agenda vacía, nada a borrar")
- nombre = AppAgenda.pide_nombre()
- if(nulo_o_vacio(nombre)):
- return
- p = self.investigacion(nombre)
- if p != None:
- self.agenda.remove(p)
- print("Borrado. La agenda ahora tiene solo: %d registros" % len(self.agenda))
- else:
- print("Nombre no encontrado.")
- def altera(self):
- if len(self.agenda) == 0:
- print("Agenda vacía, nada a alterar")
- nombre = AppAgenda.pide_nombre()
- if(nulo_o_vacio(nombre)):
- return
- p = self.investigacion(nombre)
- if p != None:
- print("\nEncontrado:\n")
- AppAgenda.muestra_datos(p)
- print("Digite enter en caso de que no quiera alterar el nombre")
- nuevo = AppAgenda.pide_nombre()
- if not nulo_o_vacio(nuevo):
- p.nombre = Nombre(nuevo)
- self.menu_telefonos(p)
- else:
- print("¡Nombre no encontrado!")
- def menu_telefonos(self, datos):
- while True:
- print("\nEditando teléfonos\n")
- AppAgenda.muestra_datos_telefono(datos)
- if(len(datos.telefonos)>0):
- print("\n[A] - alterar\n[D] - borrar\n", end="")
- print("[N] - nuevo\n[S] - salir\n")
- operacion = input("Elija una operación: ")
- operacion = operacion.lower()
- if operacion not in ["a", "d", "n", "s"]:
- print("Operación inválida. Digite A, D, N o S")
- continue
- if operacion == 'a' and len(datos.telefonos)>0:
- self.altera_telefonos(datos)
- elif operacion == 'd' and len(datos.telefonos)>0:
- self.borra_telefono(datos)
- elif operacion == 'n':
- self.nuevo_telefono(datos)
- elif operacion == "s":
- break
- def nuevo_telefono(self, datos):
- telefono = AppAgenda.pide_telefono()
- if nulo_o_vacio(telefono):
- return
- if datos.investigacionTelefono(telefono) != None:
- print("Teléfono ya existe")
- tipo = self.pide_tipo_telefono()
- datos.telefonos.adiciona(Telefono(telefono, tipo))
- def borra_telefono(self, datos):
- t = valida_franja_entero_o_blanco(
- "Digite la posición del número a borrar, enter para salir: ",
- 0, len(datos.telefonos) - 1)
- if t == None:
- return
- datos.telefonos.remove(datos.telefonos[t])
- def altera_telefonos(self, datos):
- t = valida_franja_entero_o_blanco(
- "Digite la posición del número a alterar, enter para salir: ",
- 0, len(datos.telefonos) - 1)
- if t == None:
- return
- telefono = datos.telefonos[t]
- print("Teléfono: %s" % telefono)
- print("Digite enter en caso de que no quiera alterar el número")
- nuevotelefono = AppAgenda.pide_telefono()
- if not nulo_o_vacio(nuevotelefono):
- telefono.numero = nuevotelefono
- print("Digite enter en caso de que no quiera alterar el tipo")
- telefono.tipo = self.pide_tipo_telefono(
- self.agenda.tiposTelefono.investigacion(telefono.tipo))
- def lista(self):
- print("\nAgenda")
- print("-" * 60)
- for e in self.agenda:
- AppAgenda.muestra_datos(e)
- print("-" * 60)
- def lee(self, nombre_archivo=None):
- if nombre_archivo == None:
- nombre_archivo = AppAgenda.pide_nombre_archivo()
- if nulo_o_vacio(nombre_archivo):
- return
- with open(nombre_archivo, "rb") as archivo:
- self.agenda = pickle.load(archivo)
- self.ultimo_nombre = nombre_archivo
- def ordena(self):
- self.agenda.ordena()
- print("\nAgenda ordenada\n")
- def graba(self):
- if self.ultimo_nombre != None:
- print("Último nombre utilizado fue '%s'" % self.ultimo_nombre)
- print("Digite enter en caso de que quiera utilizar el mismo nombre")
- nombre_archivo = AppAgenda.pide_nombre_archivo()
- if nulo_o_vacio(nombre_archivo):
- if self.ultimo_nombre != None:
- nombre_archivo = self.ultimo_nombre
- else:
- return
- with open(nombre_archivo, "wb") as archivo:
- pickle.dump(self.agenda, archivo)
- def ejecute(self):
- self.menu.ejecute()
- if __name__ == "__main__":
- app = AppAgenda()
- if len(sys.argv) > 1:
- app.lee(sys.argv[1])
- app.ejecute()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement