Escribiremos un programa que nos permita hacer un registro de animales, con su nombre científico
y su nombre común, estos enlazados por un ID único. Usando ese ID podremos eliminar al animal del registro,
o simplemente modificar los nombres ya escritos. Así como una opción de ver la lista de los animales ya
registrados y una opción que nos permita salir del programa.
La meta es generar e imprimir una lista que se pueda modificar como esta:
Animal Registry | ||
---|---|---|
ID | Scientific Name | Common Name |
3Y99 | Canis Lupus Familiaris | Siberian Husky |
MT5R | Cebinae | Capuchin Monkey |
8D6U | Octopoda | Octopus |
YG0E | Anthophila | Bee |
JN14 | Dinastinae | Rhinoceros Beetle |
WVTA | Python Regius | Ball Python |
HAZP | Gorilla | Gorilla |
Trabajaremos con:
- El modulo PrettyTable.
- Diccionarios anidados.
- Control del flujo.
- Funciones.
Debes instalar PrettyTable mediante Pip.
Intenta, en la consola, con:
pip install prettytable
Primero, importaremos los módulos necesarios:
PrettyTable para la creación de la tabla en donde registraremos a los animales, random y string para
generar un ID al azar con el cual identificaremos la fila en el registo y sys para salir del programa.
from prettytable import PrettyTable
import random
import string
import sys
Ahora crearemos un diccionario vacío en donde almacenaremos los animales que vayamos a registrar.
animal_dic = {}
Escribiremos la condicional "if name == "main"" para evitar errores de importación y por buenas practicas.
y llamamos a nuestra función main().
if __name__ == "__main__":
main()
La explicación de como if _name_ == "_main_" funciona está fuera del alcance de este articulo.
Funciones:
Ahora bien, escribamos las funciones que harán andar nuestro programa, estas, irán ANTES de la condicional "if _name_ == "_main_"" anteriormente descrito. De lo contrario Python intentaría ejecutar la función main() cuando esta no han sido definida, por lo tanto dispararía un error.
Función pricipal main:
Dentro de main() obligaremos a que se ejecute este loop con un while True,
imprimirá las instrucciones de añadir, borrar, actualizar, chequear y salir del programa.
También tenemos un input() que será la opción que elija el usuario y esta será almacenada en
la variable user_input. Atento al método .lower(), este convierte en minúsculas lo que ingrese el usuario, así evitamos errores de tipeo por parte de este. Finalmente, las condicionales. Dependiendo de lo que elija el usuario se llamará a una función.
# ~~~~~~~~~~~~~~~~~~ Functions(): ~~~~~~~~~~~~~~~~~~~
def main():
# ~~~~~~~~~~~~~~ User's choise ~~~~~~~~~~~~~~~
while True:
instrucctions()
user_input = input("\nWhat do you want to do? "
"(a, d, u, l, e): ").lower()
if user_input == "a":
add_animal()
elif user_input == "d":
delete_animal()
elif user_input == "u":
update_animal()
elif user_input == "l":
print_register()
elif user_input == "e":
exit_program()
elif not user_input:
print("please, enter something!")
Instrucciones:
Crearemos una función para que el usuario vea las opciones de nuestro programa junto a una tecla a presionar para que se ejecute esa opción, y para que el usuario sepa que hacer. Las opciones son: agregar animal, borrar animal, actualizar animal, mirar lista y salir del programa.
Por lo tanto, sería así:
# ~~~~~~~~~~~~~ Functions ~~~~~~~~~~~~~~
def instrucctions():
print('\nAnimal registry program:'
'\n1: Enter A or a to add new animal.'
'\n2: Enter D or d to delete a animal'
'\n3: Enter U or u to update animal.'
'\n4: Enter L or l to check list of animals. '
'\n5: Enter E or e to exit the program.')
Imprimimos las opciones. '/n' significa un salto de linea.
Imprimir registro:
def print_registry():
x = PrettyTable(["ID", "Scientific Name", "Common Name"])
for animal_data in animal_dic:
x.add_row([animal_data, animal_dic[animal_data]["scientific_name"],
animal_dic[animal_data]["common_name"]])
print(x.get_string(title="Animal registry"))
Atento a lo que sucede aquí:
- Para darles nombres a los encabezados de las columnas los escribimos en formato de lista, y la pasamos como parámetro de PrettyTable y la almacenamos en la variable "x".
- Antes de hablar del ciclo for, debemos recordar y tener muy claro de que estamos intentando acceder a un diccionario dentro de otro diccionario. Solo para tenerlo claro, comparemos un diccionario común, a uno anidado.
Diccionario:
Donde tenemos una colección de elementos almacenados en pares de key/value (clave/valor).
{'name': 'Adam'}
'name' es la key (clave) y 'Adam' el value (valor).
{'name': 'Adam', 'last': 'Smith'}
Podemos tener más de un key/value en UN diccionario. 'name' y 'last' son las keys.
Diccionario anidado:
Los valores al exterior del diccionario, también son diccionarios.
{0: {'book': 'Wealth of Nations', 'author': 'Adam Smith'},
1: {'book': 'Economic Sophisms',' author': 'Frédéric Bastiat'}}
0 es la key/clave del diccionario externo, y 'book' y 'author' claves del diccionario interno.
Entendido esto, volvamos al código anterior.
for animal_data in animal_dic:
Lo que ocurre aquí es que accedemos al key externo (Es decir, el ID), mediante animal_date.
x.add_row([animal_data, animal_dic[animal_data]["scientific_name"],
animal_dic[animal_data]["common_name"]])
Ya que accedemos al key externo, tendremos acceso a los valores internos. Ocurre de
la siguiente manera:
- animal_dic = ID del animal
- animal_dic[animal_data]["scientific_name"] = nombre científico
- animal_dic[animal_data]["common_name"] = nombre común
Entonces, pues:
x.add_row([animal_data, animal_dic[animal_data]["scientific_name"],
animal_dic[animal_data]["common_name"]])
Ingresamos los valores de nuestro diccionario a la fila de PrettyTable como una lista, mediante el
método add_row().
Finalmente le damos un encabezado a nuestra tabla:
print(x.get_string(title="Animal registry"))
Ahora puedes imprimir la lista iniciando el programa y presionando "l" o "L". Obviamente, ahora nuestro diccionario está vacío. Más adelante veremos como ingresarle datos.
Random ID:
Necesitamos un ID para identificar la columna y al animal registrado, este ID servirá como enlace, siendo la key externa de nuestros diccionarios anidados.
Es necesario para un futuro poder actualizar uno o ambos nombres del animal, o borrarlo definitivamente.
Para facilitarle la tarea al usuario, y evitar que cree duplicados, crearemos una función que retorne
un string al azar. Lo haremos con el siguiente código:
def random_id():
random_string = ''.join(random.choices(string.ascii_uppercase
+ string.digits, k=4))
return random_string
Donde "k" es el largo del string.
La explicación de como funciona esta función está fuera del alcance de este articulo.
Agregar:
Ahora hagamos la función que se encargará de tomar los valores que escriba el usuario e ingresarlos en el diccionario.
def add_animal():
animal_id = random_id()
scientific_name = input("\nPlease enter the scientific name: ").title()
common_name = input("\nPlease enter the common name: ").title()
data = {animal_id: {'scientific_name': scientific_name,
'common_name': common_name}}
if not scientific_name and not common_name:
print("You must write something!")
else:
animal_dic.update(data)
- Lo primero que notarás es que llamamos a la función random_id que devuelve un string y lo almacenamos en la variable animal_id. Como su nombre lo indica, identifica al animal y su fila dentro del registro.
- Mediante el método input() le pedimos al usuario que escriba el nombre común y científico. y los almacenamos en variables. Usamos el método .title() por estética.
Hagamos una pausa y miremos otra vez esta parte del código:
data = {animal_id: {'scientific_name': scientific_name,
'common_name': common_name}}
Actualizamos nuestro diccionario anidado y lo almacenamos en una variable llamada "data". De modo que:
animal_id = Es el random ID que retorna nuestra función. Es la key/clave externa de este
diccionario anidado.
'scientific_name': que está entre comillas, es la key/llave interna.
scientific_name: que una variable, es la value/valor interno. Ingresado por el usuario.El siguiente bloque de código establece una condición donde si el usuario no ingresa
ni un nombre científico ni un nombre común, imprima un mensaje de que debe hacerlo.Por ultimo, en el 'else': si se han ingresados al menos uno de los dos input()
actualizaremos el "animal_dic" con los datos escritos por el usuario.
Eliminar fila:
Ahora escribamos la función para borrar la fila que el usuario elija, mediante el ID único.
def delete_animal():
animal_id = input("\nEnter the animal ID you want delete: ").upper()
if animal_id in animal_dic:
choice = input("Delete (y/n)").lower()
if choice == "yes" or choice == "y":
del animal_dic[animal_id]
print(f"{animal_id} registry has been deleted!")
else:
print("ID not found. Check list pressing 'L'")
- Le pedimos al usuario que ingrese el ID de la fila. Usamos upper() para que este no tenga que escribir mayúsculas.
- Creamos un 'if': que chequea si el ID ingresado por el usuario está en el diccionario le de la elección de querer borrarlo con un sí o no. Si escribe si se borrara con un "del animal_dic[animal_id]" que busca el ID (key externo) y borra todos sus key/values internos .
- Con el else declaramos de que, si no se ha encontrado el ID, imprime un "ID not found"
Actualización:
Tal vez el usuario ha cometido un error de tipeo, y desea cambiar los campos de una fila en especifico
Ahí la necesidad de una función que los actualice.
def update_animal():
animal_id = input("\nEnter the animal ID you want update: ").upper()
# If external key in dictionary, if key is equal to ID (animal_id)
for animal in animal_dic:
if animal == animal_id:
choice = input(f"Update registry {animal_id}? (y/n): ").lower()
if choice == "yes" or choice == "y":
# Changing names
scientific_name = input("Write a new scientific name: ").title()
common_name = input("Write a new common name: ").title()
if not scientific_name and not common_name:
print("You must write something!")
else:
# Updating
animal_dic[animal]['scientific_name'] = scientific_name
animal_dic[animal]['common_name'] = common_name
print("registry updated!")
print_registry()
else:
print("ID not found. Check list pressing 'L'")
- El usuario ingresa el ID mediante un input() y es almacenado en una variable.
- Sí el ID (key externo) existe en nuestro diccionario avanzará a recorrerlo mediante un for loop, de lo contrario, imprimirá un "ID not found".
- Preguntamos si el usuario realmente quiere borrar la fila y almacenamos su respuesta en una variable. Si es afirmativo, procedemos. Contrario se detiene el flujo.
- Pedimos al usuario, mediante un input(), que escriba los nuevos nombres y los almacenamos en variables.
- Si el usuario ha dejado en blanco ambos campos se imprimirá "You must write something!" de lo contrario accederemos al diccionario, a su llave externa y almacenaremos los nuevos valores.
Salir del programa:
def exit_program():
sys.exit("Goodbye!")
Usamos el método exit() del modulo built-in sys para salirnos del programa e imprimiremos un
mensaje.
Top comments (0)