← Back to Blog

Safe Paws Project — Round 4/5

Lassie is doing better. Time to find her a new home — and build the procedure for it.

Two things need to happen when an animal is adopted. Its status in our shelter file changes from "available" to "adopted". And a record of the adoption gets written to a second file — who adopted it, when, and how to reach them if the animal is ever lost.

The function is similar to edit_health() — but simpler. We don't ask for a new status. We already know it.

def paw_adopted():

    available_paws = {}
    adopted_paws = {}

    for key in paws_dict:
        if paws_dict[key][5] == "available":
            available_paws[key] = paws_dict[key]
        else:
            adopted_paws[key] = paws_dict[key]

    while True:
        try:
            id = int(input("Adopted paw id: "))
            if id in available_paws.keys():

                owner_name = ""
                while not owner_name:
                    owner_name = input("New owner name: ")

                owner_contact = ""
                while not owner_contact:
                    owner_contact = input("New owner contact: ")

                adoption_date = datetime.date.today().strftime("%Y-%m-%d")

                with open("adopted_paws.txt", "a", encoding="utf-8") as f:
                    f.write(f"{id};{owner_name};{owner_contact};{adoption_date}\n")

                paws_dict[id][5] = "adopted"
                print(f"Great! {paws_dict[id][0].upper()} has a new home.")

                with open("safe_paws.txt", "w", encoding="utf-8") as f:
                    for key in paws_dict:
                        f.write(f"{key};{paws_dict[key][0]};{paws_dict[key][1]};{paws_dict[key][2]};{paws_dict[key][3]};{paws_dict[key][4]};{paws_dict[key][5]}\n")
                print("safe_paws.txt was updated!")
                load_from_txt()
                break

            elif id in adopted_paws.keys():
                print(f"{paws_dict[id][0].upper()} was already adopted.")
                break

        except ValueError:
            print("Invalid ID. Enter a number.")

The structure will look familiar. Two dictionaries for filtering — available and adopted. The loop asks for an ID and routes accordingly.

If the animal is available: we collect the owner's name, contact, and today's date — automated with datetime.date.today(). We write the adoption record to adopted_paws.txt with "a" — append, never overwrite, every adoption stays on record. Then we update the status in paws_dict and rewrite safe_paws.txt with "w". Both files stay in sync.

The two with open() blocks use the same variable name f — and that's fine. They're separate blocks for separate files, executed one after the other. Python closes the first file when the first block ends, then opens the second. f is just a local alias — it can be reused freely.

If the animal is already adopted: a personalized message, nothing written.

One more thing worth noting. We update paws_dict[id][5] — the main dictionary — not available_paws. That's intentional. available_paws was only used for filtering. When we rewrite the file, we need every animal — adopted and available — and paws_dict has them all.

A side note for those curious: try replacing "adopted" with other statuses — "recovered", "escaped", "deceased". You'll quickly see whether a single flexible function with a status input makes more sense than a dedicated function for each case. Both approaches are valid. The choice depends on how the shelter actually operates.

Into the menu:

while True:
    print("\nSafe Paws Menu")
    option = input("1-Add paw\n2-Adv search\n3-Edit paw health\n4-Register adoption\nq-Quit\nChoose your option: ")
    if option == "1":
        add_paw()
        print("Paw added successfully!")
    elif option == "2":
        if len(adv_search()) > 0:
            print_adv_search()
        else:
            print("No data match your search.")
    elif option == "3":
        edit_health()
    elif option == "4":
        paw_adopted()
    elif option == "q":
        break
    else:
        print("Invalid option!")

Here's what the interaction looks like in practice.

Registering an adoption:

Adopted paw id: 1
New owner name: Jon Snow
New owner contact: 0123456789
Great! LASSIE has a new home.
safe_paws.txt was updated!

Trying to adopt an animal that's already gone:

Adopted paw id: 1
LASSIE was already adopted.

adopted_paws.txt after the first adoption:

1;Jon Snow;0123456789;2025-04-07

safe_paws.txt — Lassie's entry, updated:

1;Lassie;dog;medium;healthy;4;adopted

Two files now. Next — a report that pulls from both and presents something worth sharing.

Congratulations, Lassie. You got a second chance.

[ login to bookmark ] // copied! 31 views · 2 min
// resources
Other safe_paws.txt Exercise safe_paws_r4.py
← prev Safe Paws Project — Round 3/5 next → Safe Paws Project — Round 5/5
// 0 comments
// No comments yet. Be the first.
// leave a comment

// Your comment will appear after approval.