How I Made My Python Book Tracker Fully Customizable

Day 55 of 100 Days Coding Challenge: Python

Once upon a time—okay, a few days ago—I had my genre-color pairings carved in digital stone. Tucked inside a function like a squirrel’s hoard of acorns, the genres and their matching hues were hard-coded, like:

“Historical Fiction”: “sienna”,

“Fiction”: “gray”,

“Memoir”: “lightcoral”,

You get the idea.

Back then, it felt efficient. But let’s be honest: it was as user-friendly as a brick in a gift box. So I set out to give my humble book tracker a glow-up. I added functionality to let users add their own genres, pick colors from a GUI color chooser, save them in a JSON file, and even reorder or delete genres if needed. No more pre-determined palettes—now users can start with a clean slate.

With all those new powers in place, it became clear: the old load_genre_colors() hardcoded fallback was now the fossil in the room. So I yanked it out and simplified the codebase. And just to test it, I cleared out most of my book log entries too—leaving only a lean trio: Fantasy, Science Fiction, and Romance. The result? A slicker, cleaner, beginner-friendly tool. And no more assumptions about people loving “lightcoral.”

Today’s Motivation / Challenge

Today’s challenge was about trust. Not between people—but between me and my code. I wanted to trust my users enough to let them decide what genres they care about and what colors they want. The control panel is theirs now. My job? Just to make sure the wires behind the scenes don’t catch fire.

This was also a step toward user-friendliness. The kind that makes someone say, “Hey, I could actually use this!” rather than “What on earth is ‘slateblue’?”

Purpose of the Code (Object)

This program is a customizable book tracker. It lets users log what they read, track their reading progress over time, and visualize it through colorful charts. It also gives them complete control over how genres are defined and displayed—no default lists, no assumptions.

AI Prompt:

“Can I remove the hardcoded genre-color mapping and just let the user build their own?”

Yes. And I did.

Functions & Features

  • Add, edit, or delete book entries
  • Define custom genres and pick colors for each
  • Save genre-color preferences in a JSON file
  • View genre breakdowns via pie or bar charts
  • Reorder genre list and edit mappings interactively

Requirements / Setup

Install the essentials:

pip install pandas matplotlib

If using the color picker:

pip install tk

Tested with Python 3.10+

Minimal Code Sample

genre_color_dict = {

    ‘Fantasy’: ‘purple’,

    ‘Science Fiction’: ‘blue’,

    ‘Romance’: ‘red’

}

This is where your genre-color story begins—users can expand it from here.

Book Tracker App

Notes / Lessons Learned

Actually, for the first time in this series, I wrestled with my own AI prompt. You see, the chat history had gotten so long (we’ve been working on this file for over two weeks) that when I asked to “remove the hardcoded section,” it started offering way too much interpretation—like a method actor who wouldn’t stop improvising.

Eventually, I had to open a fresh chat in the same project folder and restate everything clearly. That’s when it hit me: AI is powerful, but not psychic. It only knows what you tell it. If you’re not precise with your wording, it’ll do what it thinks you mean, not what you actually mean.

Just like coding, AI prompting is a language of its own. Respect it. Be clear. And maybe don’t expect it to read your mind… yet.

Optional Ideas for Expansion

  • Add a “preview” button to visualize the genre-color palette before saving it
  • Let users export their reading stats as an image or PDF report
  • Build a tag system so one book can belong to multiple genres (for the indecisive types)

Let’s be honest, even Tolkien would’ve struggled choosing between “Fantasy” and “Adventure.”

Ending the Year Shaking, Sweating, and Still Standing

Brian’s fitness journal after a brain stroke

Being the very last day of the year, I decided it was now or never.

I added a few extra seconds to my planking session and went for my first three-minute plank. I’d been hoping to reach this milestone before the year ended, and since calendars are unforgiving, today was my final chance.

It took three attempts.

On the third try, I summoned every ounce of stubbornness I possess and held on through the shaking, bargaining, and quiet questioning of my life choices. But I made it. Three minutes. Done.

It’s strange how quickly a year disappears when you look back at it. Somehow, I managed to achieve all the goals I set for myself this year. Tomorrow, the slate resets—but today, I’m allowing myself to acknowledge that effort matters.

Feeling fairly triumphant, I headed out for my run, hoping to double the celebration by matching my target pace. That didn’t quite happen. Still, I achieved a sub-9-minute-per-kilometer pace, which was my primary running goal for the year. That counts.

My wife and I both set goals—but in very different ways.

I tend to set yearly goals, supported by smaller milestones that I adjust as needed. Physical progress isn’t linear. Sometimes you move forward, sometimes you stall, and sometimes you need to force a milestone just to see what’s possible.

My wife doesn’t really think in years. She thinks in decades.

Her goal is simple and ambitious: at 80, she still wants to enjoy moving her body. From there, she works backward—long-term vision, then mid-term goals (three to seven years), then short-term ones. She says that after 50, you really have to focus on the next zero to three years, because anything can happen. We share the same personality type—INTJ—but her timeline makes mine look impatient.

Still, I’m satisfied.

This Friday, I’ll begin a new year-long quest: shaving another minute off my pace. It will be hard. Possibly frustrating. But as long as I’m making progress, I’ll be content—even if I don’t fully succeed.

And if I don’t? I’ll try again next year.

What’s remarkable is that my slowest runs over the past couple of weeks would have ranked among my fastest runs at this time last year. Progress has happened, even when it didn’t feel dramatic.

So I’ll end the year the same way I lived it:

  • a little stubborn
  • a little reflective
  • and still moving forward

Taming the Menu Beast: When Order Matters More Than Code

Day 54 of 100 Days Coding Challenge: Python

I’ve been dancing with this project for over two weeks now. And you know what? When your project involves books—the thing you’re borderline obsessed with—you start fussing over the little things. Like menus. Yes, menus.

Today was the day I finally tackled something that had been silently bothering me: the out-of-whack order of the main menu. I had “Exit” sitting at #7 like it owned the place, while other features awkwardly piled up from 8 to 12. Not exactly elegant. So I did what any self-respecting, slightly neurotic book tracker would do—I cleaned house.

I reorganized the main menu to follow a more logical and satisfying sequence. Something clean, orderly, and sometimes won’t drive future-me (or any poor GitHub visitor) up the wall.

Here’s the new lineup, alphabet soup no more:

  1. Add a book
  2. Edit or delete a book
  3. Show all books
  4. Import from CSV
  5. Show overall reading graph
  6. Show genre summary chart (Pie or Bar)
  7. Show filtered chart by year and quarter
  8. Show average pages per genre per quarter
  9. Add a new genre and color
  10. Rename or delete a genre
  11. Reorder genre list manually
  12. Exit

Take that, chaos.

Today’s Motivation / Challenge

The real motivation? Sanity—and a sprinkle of future-proofing. I want to post this project on GitHub when it’s done, and I figured any stranger poking around deserves a user-friendly menu. Think of it like alphabetizing your spice rack: not necessary, but undeniably satisfying.

Also, adding new functions is becoming easier. Which means cleaning up after myself is now the least I can do.

Purpose of the Code (Object)

This script tracks the books you’ve read and turns them into beautiful visual summaries. From adding titles to generating colorful graphs, it’s designed to help readers stay organized, reflect on their reading habits, and play with genre data like it’s LEGO.

Today’s focus? Making the main menu feel like a polished app, not a last-minute potluck.

AI Prompt:

“Reorder the menu options and update the corresponding elif statements so the user sees a more intuitive and logically grouped main menu.”

Functions & Features

  • Add, edit, or delete book entries
  • Import a list of books from a CSV
  • Display all books in a clean format
  • Visualize reading progress with graphs
  • Analyze reading trends by genre and quarter
  • Manage genres with custom colors and order

Requirements / Setup

pip install matplotlib

pip install pandas

tkinter (comes pre-installed with Python)

Tested with Python 3.10+

Minimal Code Sample

print(“12. Exit”)

elif choice == “12”:

    print(“Goodbye!”)

    break

Just update the number and make sure the function still points to the right feature. Think of it like updating the index in your table of contents—crucial if you don’t want your reader flipping to the wrong page.

Book Tracker

Notes / Lessons Learned

Basically, what you need to do is reassign the menu numbers in the order you want. Then, carefully adjust each elif block to reflect the new structure.

I had:

elif choice == “7”:

    print(“Goodbye!”)

    break

Now I want:

elif choice == “12”:

    print(“Goodbye!”)

    break

The actual task wasn’t hard. The challenge was not falling into a logic trap—accidentally assigning two features to the same number or skipping one entirely. I highly recommend using AI or a numbered to-do list when reordering more than a few options. Saves brain cells.

It’s funny how a simple reorder can make the whole project feel more finished, more elegant—even if no code logic changes at all.

Optional Ideas for Expansion

  • Let users “star” favorite genres for quick filtering
  • Add keyboard shortcuts for power users
  • Enable saving custom menu layouts as presets

The Librarian Strikes Back: Renaming and Deleting with Style

Day 53 of 100 Days Coding Challenge: Python

We’re rounding the final bend on this book tracker project, and like any good road trip, it’s time to clean out the car before showing it off. Yesterday, I had an itch to tidy up the main menu—it had the organizational charm of a sock drawer after laundry day. It wouldn’t matter much if I were the only one using this program, but I plan to upload it to GitHub. And if you’re going to invite guests into your house, you should at least sweep the floor.

But before I rolled up my sleeves to alphabetize those menu options, I realized one last function was missing: editing or deleting a book from the log. Imagine proudly logging “The Wind in the Pillars” instead of “The Wind in the Willows,” and having no way to fix it. I knew I had to patch that hole. Mistakes happen—we’re human, and sometimes our fingers think faster than our brains.

This new function feels like the final polish on a well-loved tool, the last screw tightened before the machine hums just right.

Today’s Motivation / Challenge

Let’s face it: no book tracking tool is complete if you can’t fix a typo or remove that self-help book you never actually finished (and don’t want to admit you bought). Editing and deleting books makes your log feel more like a digital journal and less like a permanent tattoo. Today’s challenge was about giving myself—and any future users—permission to change their minds.

Purpose of the Code (Object)

This feature adds a small but mighty update to the book tracker: the ability to edit or delete entries in your reading log. It helps you clean up titles, fix authors, update genres, or just delete a book altogether if you never finished it (no judgment). It’s all about control—because even logs deserve second chances.

Functions & Features

  • View a list of all books in your log with entry numbers
  • Edit any detail of a selected book (or leave it unchanged)
  • Delete a book entirely if it was added by mistake
  • Automatically save updates to your CSV log file

Requirements / Setup

pip install pandas

You’ll also need:

  • Python 3.8 or higher
  • A CSV file named book_log.csv in the same folder (or let the script create one)

Minimal Code Sample

df = pd.read_csv(FILE_NAME)

for idx, row in df.iterrows():

    print(f”{idx+1}. {row[‘Title’]} by {row[‘Author’]}”)

choice = int(input(“Choose a book to edit or delete: “)) – 1

This snippet prints a numbered list of books and lets the user choose one to modify.

Book Tracker

Notes / Lessons Learned

Adding new features is getting easier—finally! The hardest part this time wasn’t writing the logic; it was making the user interface feel smooth and forgiving. I had to read through my own book log like a detective, catch typos, and trace the moment a “Memoir” turned into “Memor.” It turns out, the edit function is not just about fixing mistakes. It’s about telling your story the way you meant to tell it.

At one point, I found a mismatch between my Notion log and the CSV file this script uses. That’s when I decided: I’ll start fresh—clean log, clean menu, clean conscience.

Optional Ideas for Expansion

  • Add a search function so you can find books by keyword before editing.
  • Include a confirmation screen to preview changes before saving.
  • Show book stats (like total pages read) after edits are made.

Nashville Weather Changes: Spring Yesterday, Winter Today

Brian’s fitness journal after a brain stroke

True to the forecast, the temperature dropped 40 degrees since yesterday. This is classic Nashville behavior. Our weather doesn’t transition—it teleports. One day you’re contemplating spring allergies, the next you’re questioning your glove choices.

Just yesterday, it felt so warm that we spotted early spring flowers on the trees. My wife’s allergies immediately noticed. Apparently, pollen doesn’t wait for official permission. Spring showed up briefly, caused chaos, and left.

The shift happened fast. It stayed warm through the evening, but around 10 p.m., the wind started howling like it had a personal vendetta. The temperature plunged, and for a while, I was mildly concerned about losing electricity. My wife, meanwhile, slept soundly through it all—completely unaware of the weather drama unfolding outside.

To be fair, she had already checked today’s temperature before bed. She always does. Her running clothes are selected and staged based on the forecast, prepared calmly in advance like a seasoned field commander.

This morning, I waited for the day to reach its warmest point—which was still just below freezing—then reluctantly pulled on my gloves and headed out for my run. I was annoyed, but annoyance is practically a Tennessee weather survival skill.

Sometime overnight, a large branch snapped off a tree behind our house. I’m fairly certain I heard it crack. The tree itself survived, thankfully—it chose to sacrifice an arm rather than topple over onto our deck or house. Strategic, if unfortunate.

In the daylight, the damage was clear. The tree lost its largest limb and now looks thoroughly defeated. It was already struggling against neighboring trees, and since the one next to it fell last year, the ground may be too disturbed for it to stay upright much longer. This is likely a conversation I’ll need to have with my wife later.

On a brighter note, her Christmas present finally arrived today. I wrapped it up so it’ll be ready when she gets home—a small victory amid the wind, cold, and fallen branches.

So yes:
  • Yesterday: spring
  • Today: winter
  • Tomorrow: who knows

That’s Nashville. And somehow, we keep running anyway.

Graphing My Way Through the Library

Day 52 of 100 Days Coding Challenge: Python

You know you’ve reached a new level of coding attachment when you start treating your genre list like a prized bonsai tree—snipping here, trimming there, fussing over every little branch of logic. After revamping the program so it could accept new genres and pretty colors via a palette (very fancy, I know), I realized there was no graceful way to unmake a genre. What if I added “Historicl Fiction” by mistake? What if I picked a color so hideous that even my pie chart looked like it wanted to gag?
Today was all about giving myself the power to fix those flubs. Rename it, delete it, clean up my genre garden—snip snip! Because frankly, if I don’t like the color, the genre might just have to go.

Today’s Motivation / Challenge

Every great coder hits that moment where they scream at the screen, “Why can I add but not delete?!” It’s like buying furniture without knowing how to return it. I wanted my program to feel flexible, like a well-organized closet—not a hoarder’s storage unit of genre typos and duplicate categories. And let’s be honest, sometimes “Fantasy” and “Science Fiction” are just playing dress-up in each other’s clothes. Merge, rename, delete, repeat.

Purpose of the Code (Object)

This update lets users do a little genre housekeeping. You can now clean up your list by renaming genres (in case of typos or re-categorizing) or deleting them completely. It helps keep your visualizations tidy and your data organized—without diving into the JSON file manually. Think of it like giving your genre system a tiny admin panel without the drama.

AI Prompt:


Add a feature to let users rename or delete genres from the saved genre-color dictionary and persist it using JSON.

Functions & Features

Add a new genre and assign it a color using a color picker
Save all genres and colors to a JSON file automatically
Rename existing genres in case of typos or reclassification
Delete genres that are no longer wanted
Keep your pie charts and reports squeaky clean

Requirements / Setup

Install required library: pip install matplotlib pandas
Python 3.9 or later recommended for date handling and plotting.
No external JSON library needed—just the built-in json and os modules
tkinter (comes with Python standard library)

Minimal Code Sample

def rename_or_delete_genre(genre_color_dict):
print(“\nCurrent Genres:”)
for genre in genre_color_dict:
print(f”- {genre}”)

choice = input("\nRename or Delete? (r/d): ").strip().lower()
if choice == 'r':
    old = input("Old genre name: ")
    new = input("New genre name: ")
    if old in genre_color_dict:
        genre_color_dict[new] = genre_color_dict.pop(old)
        print(f"Renamed '{old}' to '{new}'.")
    else:
        print("Genre not found.")
elif choice == 'd':
    target = input("Genre to delete: ")
    if target in genre_color_dict:
        del genre_color_dict[target]
        print(f"Deleted '{target}'.")
    else:
        print("Genre not found.")
save_genre_colors(genre_color_dict)

This snippet shows how to let users clean up the genre-color dictionary and save the changes.

Book Tracker

Notes / Lessons Learned

This might sound like a small tweak, but it was a surgical upgrade. I tested, tweaked, and made backup copies like I was preparing to launch a space probe, not a genre menu. And wow—what a difference it made. Now if I want to merge “Thriller” into “Mystery,” I don’t need to panic about breaking anything.
It also got me thinking about naming in general. Genres are a bit like moods—they shift. So it helps to keep things tidy and editable. Pro tip? Rename before deleting, just in case you regret it five seconds later.
Also, I’m now officially annoyed that my function menu jumps from 7 to 11. Time to refactor. Naming may be hard, but numbering is… even harder?

Optional Ideas for Expansion

  • Add a feature to merge two genres into one, including updating past entries
  • Include a log file that records changes to genres for version control
  • Let users reorder the genre list manually so the menu stays tidy and satisfying

A Little Genre Surgery: Rename, Remove, Repeat

Day 51 of 100 Days Coding Challenge: Python

You know you’ve reached a new level of coding attachment when you start treating your genre list like a prized bonsai tree—snipping here, trimming there, fussing over every little branch of logic. After revamping the program so it could accept new genres and pretty colors via a palette (very fancy, I know), I realized there was no graceful way to unmake a genre. What if I added “Historicl Fiction” by mistake? What if I picked a color so hideous that even my pie chart looked like it wanted to gag?

Today was all about giving myself the power to fix those flubs. Rename it, delete it, clean up my genre garden—snip snip! Because frankly, if I don’t like the color, the genre might just have to go.

Today’s Motivation / Challenge

Every great coder hits that moment where they scream at the screen, “Why can I add but not delete?!” It’s like buying furniture without knowing how to return it. I wanted my program to feel flexible, like a well-organized closet—not a hoarder’s storage unit of genre typos and duplicate categories. And let’s be honest, sometimes “Fantasy” and “Science Fiction” are just playing dress-up in each other’s clothes. Merge, rename, delete, repeat.

Purpose of the Code (Object)

This update lets users do a little genre housekeeping. You can now clean up your list by renaming genres (in case of typos or re-categorizing) or deleting them completely. It helps keep your visualizations tidy and your data organized—without diving into the JSON file manually. Think of it like giving your genre system a tiny admin panel without the drama.

AI Prompt:

“Add a feature to let users rename or delete genres from the saved genre-color dictionary and persist it using JSON.”

Functions & Features

  • Add a new genre and assign it a color using a color picker
  • Save all genres and colors to a JSON file automatically
  • Rename existing genres in case of typos or reclassification
  • Delete genres that are no longer wanted
  • Keep your pie charts and reports squeaky clean

Requirements / Setup

pip install matplotlib pandas

(Also includes built-in modules like json and os, so no sweat there.)

Minimal Code Sample

def rename_or_delete_genre(genre_color_dict):

    print(“\nCurrent Genres:”)

    for genre in genre_color_dict:

        print(f”- {genre}”)

    choice = input(“\nRename or Delete? (r/d): “).strip().lower()

    if choice == ‘r’:

        old = input(“Old genre name: “)

        new = input(“New genre name: “)

        if old in genre_color_dict:

            genre_color_dict[new] = genre_color_dict.pop(old)

            print(f”Renamed ‘{old}’ to ‘{new}’.”)

        else:

            print(“Genre not found.”)

    elif choice == ‘d’:

        target = input(“Genre to delete: “)

        if target in genre_color_dict:

            del genre_color_dict[target]

            print(f”Deleted ‘{target}’.”)

        else:

            print(“Genre not found.”)

    save_genre_colors(genre_color_dict)

This snippet shows how to let users clean up the genre-color dictionary and save the changes.

Book Tracker

Notes / Lessons Learned

This might sound like a small tweak, but it was a surgical upgrade. I tested, tweaked, and made backup copies like I was preparing to launch a space probe, not a genre menu. And wow—what a difference it made. Now if I want to merge “Thriller” into “Mystery,” I don’t need to panic about breaking anything.

It also got me thinking about naming in general. Genres are a bit like moods—they shift. So it helps to keep things tidy and editable. Pro tip? Rename before deleting, just in case you regret it five seconds later.

Also, I’m now officially annoyed that my function menu jumps from 7 to 11. Time to refactor. Naming may be hard, but numbering is… even harder?

Optional Ideas for Expansion

  • Add a feature to merge two genres into one, including updating past entries
  • Include a log file that records changes to genres for version control
  • Let users reorder the genre list manually so the menu stays tidy and satisfying

Running After Poor Sleep and Even Less Patience

Brian’s fitness journal after a brain stroke

Some days, sleep simply refuses to cooperate. Last night was one of them.

I woke up around 1 a.m. and stayed awake for hours, staring into the darkness while my brain ran its own unsolicited marathon. By morning, my body made it very clear that it had not signed up for this level of sleep deprivation.

Fridays come with their own fixed set of chores, and today was no exception. My wife took the day off—strategically—because she needs to work an extra day next week. She had already been up for hours, moving briskly through chores she scheduled a month ago. That’s just how she operates. Planning is her superpower.

Despite feeling tired down to my bones, I got up at my normal time. Routine has a way of carrying you when energy doesn’t. After breakfast, I felt marginally more human and decided to go for my run. This was not enthusiasm—it was willpower.

My wife, already finished with her morning exercise, cheerfully reported how wonderful it was outside. And she was right. By the time I stepped out, it was already above 65°F—shockingly warm for winter in Tennessee. She’s thoroughly enjoying this mild American winter, having lived in Canada long enough to expect a white Christmas.

I remember Canadian winters vividly. One year, we shoveled nearly a foot of snow. If you live in the snow belt, snow removal becomes a lifestyle choice.

Today’s run felt great weather-wise. Shorts made another appearance. Speed, however, did not. I didn’t hit my target pace, and I’m placing full responsibility on poor sleep and lingering exhaustion.

My wife mentioned the other day—backed by her usual deep dive into nearly 100 academic journals—that sleep quality has a direct impact on cardio and resistance training performance. She doesn’t repeat common wisdom; she verifies it. That level of professional skepticism likely comes from her accounting background. Admirable? Yes. Exhausting? Also yes.

Despite the fatigue, I managed to complete everything on today’s to-do list. Still, there was a quiet sense of dread hovering over the day—the kind that only poor sleep can bring.

Now that it’s early evening, I’m nearly caught up. Once I finish my pullovers, I’ll officially be in the clear. The hope is simple: better sleep tonight, a stronger run tomorrow, and fewer arguments with my pillow.

One tired day down. Tomorrow gets another shot.

Fifty Shades of Hue: Letting the User Pick the Palette

Day 50 of 100 Days Coding Challenge: Python

Some people know the names of colors the way sommeliers know wines—by region, undertone, and emotional baggage. I am not one of those people. The other day, I misspelled a color name while trying to assign it to a new genre. I expected a big angry error message. Instead? Python shrugged and picked something. It was a shade, I suppose, but not the one I had in mind. That’s when I realized: if I’m going to survive this genre-color dance, I need more than luck. I need a color picker.

So today’s upgrade is all about seeing what you’re getting. No more guessing if “slateblue” is dusty or deep, no more typing out names like “lightgoldenrodyellow” with trembling fingers. Now I just click, pick, and go. Call it coding for the colorblindly optimistic.

Today’s Motivation / Challenge

Because naming colors from memory is a trap. Unless you moonlight as a paint chip designer at Benjamin Moore, chances are you don’t know your cornflower from your cadet blue. Adding a visual color picker turns the guessing game into a satisfying click-and-smile experience. Think of it as your genre’s fashion stylist—choosing just the right outfit without you typing the wrong thing.

Purpose of the Code (Object)

This project adds a GUI color picker to the genre customization tool. Now, when you want to assign a new color to a genre, a little window pops up and lets you see your options—no spelling errors, no surprises. Once you choose your color, the code saves it so your pie charts remain stylish and sensible across runs.

AI Prompt:

Create a visual color picker for assigning genre colors in a book tracking program using tkinter. Make sure the selection is saved and reused.

Functions & Features

  • Add new genres with customized colors
  • Pick colors visually using a color palette window
  • Automatically save selected colors to a persistent JSON file
  • Load colors each time the program starts—no hardcoding needed
  • Keeps your genre pie charts looking consistent and fabulous

Requirements / Setup

 Built-in modules only—no pip installs needed!
Just make sure you’re using:

  • Python 3.x
  • tkinter (comes with Python standard library)

Minimal Code Sample

def choose_color_gui():

    import tkinter as tk

    from tkinter import colorchooser

    root = tk.Tk()

    root.withdraw()

    return colorchooser.askcolor(title=”Choose a Color”)[1]

This little window lets you visually pick a HEX color without typing anything.

Book Tracker

Notes / Lessons Learned

Adding a color picker was smoother than expected—until I realized the pop-up window was hiding behind my active screen. Cue two minutes of wondering if the code was broken, followed by an “aha!” moment on screen two. Also, as always, I backed up my program first. Rule #1 of coding anything visual: back up, test, and be ready for the ghost windows that pop up in the digital shadows. But once I found it, the tool worked beautifully. For someone like me—who thinks in color families, not exact swatches—this is a game changer.

Optional Ideas for Expansion

  • Add a “preview pie chart” before saving the color to test how it looks
  • Suggest complementary or contrasting colors based on your selection
  • Group similar genres with similar shades for aesthetic cohesion

The Case of the Missing Genre: Solved by JSON

Day 49 of 100 Days Coding Challenge: Python

One day, you’re happily adding a shiny new genre—Mystery—and the next day it’s gone, vanished like a plot twist in an Agatha Christie novel. No “goodbye,” no note, not even a hint of suspense music. I had proudly added a function yesterday to introduce new genres and assign them pretty colors. But today? That color-coded Mystery entry was MIA.

It turns out I was adding it, but… nowhere permanent. The program was as forgetful as I am without caffeine. So, I rolled up my digital sleeves and decided it was time to get serious. Enter: the humble JSON file. My mission? To build a system where genres and their colors stick around—even after the script shuts down. This also meant rewriting a lot of the functions that were still clinging to the old hardcoded dictionary, like it was a safety blanket. It was a minor genre revolution.

Today’s Motivation / Challenge

Why bother with persistent data? Well, imagine creating something you’re proud of—then watching it vanish the next time you open the program. Frustrating, right? This project reminded me of learning to save Word documents the first time you write them. This was about teaching my Python script to remember what I told it… like a well-trained assistant, not a goldfish.

Purpose of the Code (Object)

This update allows the program to permanently remember newly added genres and their colors. Instead of living only in memory (and disappearing the moment you close your terminal), your genres are now safely stored in a JSON file—ready to return every time you open the app. It’s like giving your code a diary… and making sure it actually writes in it.

AI Prompt

Able to save newly added genres and their colors.

Functions & Features

  • Load genre-color pairs from a JSON file at startup
  • Add new genres with custom colors on the fly
  • Automatically save those updates so nothing gets lost
  • Replaces hardcoded dictionaries with dynamic loading

Requirements / Setup

  • Python 3.6+
  • pandas, matplotlib
  • No external JSON library needed—just the built-in json and os modules

Install if needed:

pip install pandas matplotlib

Minimal Code Sample

import json

import os

GENRE_FILE = “genre_colors.json”

def load_genre_colors():

    if os.path.exists(GENRE_FILE):

        with open(GENRE_FILE, ‘r’) as f:

            return json.load(f)

    return {

        “Fiction”: “gray”,

        “Fantasy”: “purple”

    }

def save_genre_colors(genre_color_dict):

    with open(GENRE_FILE, ‘w’) as f:

        json.dump(genre_color_dict, f, indent=4)

# Use these to load and update your color map

genre_color_dict = load_genre_colors()

This snippet loads and saves your genre-color dictionary using a JSON file instead of hardcoded values.

Book Tracker

Notes / Lessons Learned

This was actually a significant overhaul of the existing programming. I was so nervous I triple-checked every line and even cloned my file before making changes—just in case things went full chaos mode. First, I had to import json and os, then create a file path for my new JSON genre diary. Next, I rewired the loading function to pull from this file, and rewrote add_new_genre_color() to actually save the additions (not just pretend).

Then came the big cleanup: my program was still using GENRE_COLORS all over the place like it was 2022. Every instance had to be swapped with genre_color_dict to work with my new system. That part? Not glamorous. But when I ran the script and everything held together—and Mystery stayed put—it felt like winning a game of digital Clue.

Optional Ideas for Expansion

  • Add a user input menu to pick a color visually from a palette (instead of typing ‘slateblue’)
  • Add a “reset to default” feature if your JSON file ever gets out of hand
  • Include tooltips in the visualization showing genre + average page counts