Rate my Python code/project

Hi folks! I’m new on Python so, recently I create this little program. You can register an animal in a list (create), update, delete, and check that list.
Do you have any recommendations or see something weird in my code, or something that can be improved?
Thanks in advance.

If you want run this program remember install PrettyTable.

from prettytable import PrettyTable
import random
import string
import sys

animal_dic = {}

print('\nAnimal register 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.')


# ~~~~~~~~~~~~~~~~~~ Functions(): ~~~~~~~~~~~~~~~~~~~
def print_register():
    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 Register"))


def random_id():
    random_string = ''.join(random.choices(string.ascii_uppercase
                                           + string.digits, k=4))
    return random_string


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)


def delete_animal():
    animal_id = input("\nEnter the animal ID you want delete: ").upper()
    try:
        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} register has been deleted!")
        else:
            print("ID not found. Check list pressing 'L'")
    except Exception:
        print("Something bad happend.")


def update_animal():
    animal_id = input("\nEnter the animal ID you want update: ").upper()
    try:
        # If key in dictionary, if key is equal to ID (animal_id)
        for animal in animal_dic:
            if animal == animal_id:
                choice = input(f"Update register {animal_id}? (y/n): ").lower()
                if choice == "yes" or choice == "y":
                    # Changing names
                    scientific_name = input("Write a new scientific name: ")
                    animal_dic[animal]['scientific_name'] = scientific_name
                    common_name = input("Write a new common name: ")
                    animal_dic[animal]['common_name'] = common_name
                    print("Register updated!")
                    print_register()
                else:
                    print("ID not found. Check list pressing 'L'")
    except Exception:
        print("Something bad happend.")


def exit_program():
    sys.exit("Goodbye!")


# ~~~~~~~~~~~~~~ User's choise ~~~~~~~~~~~~~~~
while True:
    user_input = input("\nwhat do you want to do? (a, d, u, e, l): ").lower()
    if user_input == "a":
        add_animal()
    elif user_input == "d":
        delete_animal()
    elif user_input == "u":
        update_animal()
    elif user_input == "e":
        exit_program()
    elif user_input == "l":
        print_register()
    elif not user_input:
        print("please, enter something!")
2 Likes

I’d start with asking what do you think about it? What was harder and easier than you expected while writing this? Any specific issues during that, or particularly hard parts? Is there anything that feels off to you? Do you have any suspected places where code might be improved or in what areas that improvement might be?

1 Like

It was difficult find a way to store a data that can be bind one single “key” to more that two values, then someone here say "are you ever heard about “nested dictionaries” and that was the main “Oh! i got it!”. Then, was a little challenge find the way to access to certain values. I still handle my insecurities/perfection in order to make my code more “elegant”. So, always i’m looking for recommendation, maybe someone has a better or simpler way to make a thing.
My main concern is about the way I’m handling the Exception.

There’s few things that can be looked at, but exceptions is a nice place to start.

Considering delete_animal function, are you expecting any specific issue which might raise exception there?

Usually it’s better to catch only those exceptions that in fact are expected in some part of code. Catching whole Exception class makes unclear what actually was an issue. This includes multiple exceptions that are raised only in some abnormal situation - for example like memory or system issue. Sure there’s information printed that something happened, but what and why remains unknown.

You are totally right! Thanks a tons! I will be aware of that the next time.

Btw, should I write an
if name == “main”:
Then the while True loop (the last part of the code)? I’m very confusing if I always have to write that “if name…” Even in small programs like this.

Like this. Works good, and it’s better, right?

if __name__ == "__main__":
    animal_dic = {}

    # ~~~~~~~~~~~~~~ User's choise ~~~~~~~~~~~~~~~
    while True:
        instrucctions()
        user_input = input("\nWhat do you want to do? "
                           "(a, d, u, e, l): ").lower()
        if user_input == "a":
            add_animal()
        elif user_input == "d":
            delete_animal()
        elif user_input == "u":
            update_animal()
        elif user_input == "e":
            exit_program()
        elif user_input == "l":
            print_register()
        elif not user_input:
            print("please, enter something!")

That depends how one look at it. If you don’t plan to import functions from this file, or the whole file to some other code, then it will not matter much really.

What this condition does is ensure that code in it will be run only if file is run as standalone (ie. it’s not imported by some other file).

1 Like

Thanks again! I Just wanna follow best practice!

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.