• Using Gemini To Find Potential Bugs In My Code

    Using Gemini To Find Potential Bugs In My Code

    I’m using Gemini to find potential bugs in my code because it works so well. I used it while creating my last project: Easy Home Directory Backup. After it worked out so well, I’m going to continue using it for all my future projects.

    Why Am I Using Gemini To Find Potential Bugs?

    I can’t think of all the potential issues a user could run into while using my program. Oh yes, I can think of the big ones like validating user input, but there are other issues lurking that I’m missing.

    So I turned to Gemini and entered this prompt:

    Hey Gemini, I'm building a backup program that will run in the terminal (CLI) just for Linux distros that uses rsync to back up the currently-signed in user's Home Directory to a backup device. I'm building this with Python. The user supplies the path to the backup device. What are some potential issues a user can run into using this program?

    I wanted to give the Large Language Model (LLM) that background information so it could form a good answer. Then I put my question last so the LLM knew what I wanted. I’ve tried putting questions in the middle of the prompt, and that works sometimes, but more often than not I don’t get the greatest replies.

    Speaking of replies, I got a lengthy one. I’ll break it down in sections:

    Potential Issues and Considerations for Your Backup Program
    
    Here are some potential issues a user might encounter when using your Python-based rsync backup script:
    
    1. Incorrect Backup Device Path:
    
    * Permissions: Ensure the user has read-write permissions to the backup device.
    * Device Mount: Verify the device is properly mounted and accessible.
    * Device Format: Check the device's file system (e.g., ext4, NTFS, FAT32) and its compatibility with rsync.

    Gemini correctly pointed out that a user could provide a backup device that doesn’t have read/write permissions. Without validating that my program could crash. Or it could run and not do anything. Next, the user could try to use a backup device that isn’t mounted, or has non-Linux compatible file system. With this information in hand I added a TODO in my notebook to figure out a solution to these issues.

    2. Rsync Errors and Failures:
    
    * Network Issues: If the backup device is network-mounted, intermittent network connectivity can cause failures.
    * Disk Space: Insufficient space on the backup device can lead to incomplete backups.
    * File Access Permissions: If files or directories on the source or destination have restrictive permissions, rsync might fail.
    * File System Errors: Corrupted file systems or disk errors can disrupt the backup process.

    This section is all about various rsync errors users could run into. I skipped over the information about network issues because my program is strictly for local storage usage, and I inform the user of that. However, disk space is a huge potential issue I didn’t think of. Or course checking for ample free space to contain the Home Directory backup was vital, so I created a TODO for that. Regarding the last two bullet points I decided to check for basic file access permissions, but not for file system errors. The user will need to do the latter.

    3. Script Execution and Permissions:
    
    * Script Permissions: The script must have executable permissions for the user.
    * User Privileges: The user might need elevated privileges (e.g., sudo) to access certain directories or devices.
    * Background Execution: If the script is intended to run in the background, ensure proper configuration for logging and error handling.

    These issues I skipped over. Since I’m targeting experienced Linux users with my backup program they should know how to make the script executable. However, I don’t think that’s needed from my testing. The other two bullet points don’t apply to my program since it doesn’t require elevated privileges or runs in the background.

    4. Backup Strategy and Retention:
    
    * Incremental Backups: Consider implementing incremental backups to reduce backup time and storage usage.
    * Backup Rotation: Implement a strategy to rotate backup files to prevent excessive disk usage.
    * Backup Verification: Regularly verify the integrity of backups to ensure data recoverability.

    Frankly, I skipped over this section since I wasn’t going to implement any of these features in my program.

    5. User Experience and Error Handling:
    
    * Clear Error Messages: Provide informative error messages to help users troubleshoot issues.
    * Progress Indicators: Display progress indicators to keep users informed about the backup process.
    * Logging: Log detailed information about the backup process for troubleshooting and analysis.
    * User Input Validation: Validate user input to prevent invalid paths and other errors.

    These suggestions was what I was looking for, and it should’ve been the first thing listed instead of the last. I added all of these as TODOs in my notebook.

    Now I hope you see why I will continue using Gemini to find potential bugs in my code.

  • Writing Code With Pen And Paper

    Writing Code With Pen And Paper

    When it comes to developing a new technical project I enjoy writing code with pen and paper. Yes, I don’t load up my favorite Integrated Developer Environment (IDE) and create a plan there. I rather use the notebook I keep on my desk next to my keyboard.

    Why I Like Writing Code with Pen And Paper

    The reason I like writing code with pen and paper because:

    1. It’s easier for me to make a thorough plan
    2. I can follow each step in that plan as I write code in my IDE
    3. Then I can mark off each item in the plan as I complete them

    Example Of My Plans

    Here are some pictures of my plans in my notebook. First up are the images of the plan that would later become The Infected Land:

    Next are pictures of my plans that would later become Easy Home Directory Backup

    As you can see by my chicken scratch I not only write some code, but I work out the logic (or conditional) statements for my program. I usually come up with potential problems I can run into (issues with user input) and find potential solutions. Finally, I just cross out a whole block of text and start over. Frankly, I do that quite a bit.

    I think the best benefit I found doing this is working out problem in my logic. Sometimes I think I have it all planned out correctly on paper so I type it up. However, when I test out my application it doesn’t behave probably. Thus, I start debugging both in my IDE and on paper. And that’s when I discover my mistake (or three).

    I think the reason writing code with pen and paper works for me because I take things slower. I actually think about the user will progress through the code. Thus, I can design my code to follow that workflow. Or I can discover a set of steps I can transform into a function, and use that function in different files.

    If you find yourself lost in your codebase frequently I suggest grab a piece of paper and a pen and start writing!

  • Easy Home Directory Backup: An Introduction

    Easy Home Directory Backup: An Introduction

    Over my Christmas vacation I released a new technical project in its own repo onto my GitHub profile: Easy Home Directory Backup. It’s a Command Line Interface (CLI) program that runs on any Linux distribution in the Terminal. It performs a local backup of the user’s Home Directory. I developed the program in the Python programming language. In this post I will discuss the following topics about this web application:

    1. Why I created it
    2. The code running it
    3. My future plans for the application

    Why I Created Easy Home Directory Backup

    I created Easy Home Directory Backup because I wanted to improve upon a Python script I made to back up specific directories in my Home Directory. That script is also on my GitHub account which you can view here. I used a separate disk installed in my computer to hold the backups.

    While the script works great for me, I wanted to see if I could enhance it to work for other users of Linux distributions. Finally, I developed the application to continue on my current path to improve my Python programming skill-set.

    The Code Running Easy Home Directory Backup To Validate User Input

    During my design process for the program I decided to run the program in the Terminal using the Command Line Interface (CLI). I also wanted the user to provide the path of the local backup device. This imposed a problem I had to protect against: Improper user input.

    A user could input gibberish or a different value than what the program required. To keep the program from crashing, and inform the user of their mistake, I used “Try/Except” statements for user input. Here’s an truncated example from the main.py file:

    try:
            menu_choice: int = int(input("Enter your choice here: "))
            if menu_choice == 0:
                clear_screen()
                main_menu()
            elif menu_choice == 1:
                full_backup()
            elif menu_choice == 2:
                partial_backup()
            else:
                print()
                print(center_text("*" * 80))
                print(center_text("!! Enter either 0, 1, or 2 !!"))
                print()
                print(center_text(" -- The menu will reappear in a few seconds -- "))
                print(center_text("*" * 80))
                sleep_print()
                clear_screen()
                one_time_backup()
        except ValueError:
            print()
            print(center_text("*" * 80))
            print(center_text("!! This menu only accepts numbers !!"))
            print()
            print(center_text("-- The menu will reappear in a few seconds --"))
            print(center_text("*" * 80))
            sleep_print()
            clear_screen()
            one_time_backup()

    If a user entered a “4” the Else clause would fire off and a message would appear in the Terminal alert the user of their error. Thus, the user would have another chance to input the correct information in the menu. However, if the user entered an “a” that would fire off the Except statement regarding a ValueError. Again, a message appears in the Terminal informing the user to only enter numbers. Finally, the menu appears again.

    Not only did I have to validate user input, I had to validate if the path to the backup device was valid. Well, not only valid, but also a Linux-compatible file system, has read/write permissions, and mounted to name a few. I created a separate module (called validate_backup_device.py) to validate the path. I’ll explain a small portion of that code:

    def check_backup_device_permissions(backup_path: Path) -> bool:
            """Checks if the user-supplied backup device for read and write permissions.
            :param backup_path: The user-supplied path to the backup device.
            :return: True if the device has both read and write permissions, but False if it doesn't.
            """
            path_stats = os.stat(backup_path)
            mode = path_stats.st_mode
            return bool(mode & stat.S_IRUSR) and bool(mode & stat.S_IWUSR)

    In the function above I check the backup device has read/write permissions using the “stat” command to pull the file information about the backup device. Then I check the device’s mode to determine it has both read and write permissions. That’s what the “S_IRUSR” and the “S_IWUSR” options mean. The function returns True if both are correct, but False if not.

    I then run the function in one of the many conditional statements listed in the module:

    elif not check_backup_device_permissions(path):
            print()
            print(center_text(f"Backup path {path} doesn't have read/write permissions."))
            print(center_text("Please add the read/write permissions to the backup device and run this program again."))
            sleep_print()
            print()
            print(center_text("*" * 80))
            print(center_text("!! Program exited !!"))
            print(center_text("*" * 80))
            print()
            sys.exit()

    If the function returns False then the message displays in the Terminal about why the program cannot continue, and gives the user a suggestion on how to resolve the issue.

    This is just a snippet of code running the program. Please go through the repo to review the entire codebase.

    The Code Running The Backup

    I developed the program around the “rsync” command to perform the backups. however, I had to change the module I used in my script to call/run the command in the program. Before I used the “os.system” module, but during my research using Gemini I found out using the “subprocess.run” module was better to use. Because it offers secure command execution. Here’s what that code looks like:

    """rsync options
                        a = Archive
                        z = Compression
                        """
                        subprocess.run(["rsync", "-az",
                                        f"--log-file={path}/easy_home_directory_backup_{formatted_today_date}_log_file",
                                        home_dir_path, backup_device_path])

    That snippet of code performs a full backup of the user’s Home Directory. (The program also offers an option for a partial backup.) The flags in the code both archives and compresses the data. Finally, it creates a log file using a specific path name, including the date of the backup, and contains a list of all the files in the directories.

    My Future Plans For This Application

    I do want to add the ability for users to schedule a backup using crontab. However, I will have to work on implementing this feature as a user can only have one crontab. Thus, my code would need to append the file.

    Another feature I’m thinking about creating is allow users to delete the backups they create with the program. Again, that requires more testing.

    Once I enable one or more of those features I’ll post an update on my website.

  • My 2025 Career Goals

    My 2025 Career Goals

    Happy New Year! With the coming of the new year it’s time for me create my 2025 career goals and post them online so I can force myself to actually attain them! (I wrote that line to have a sarcastic tinge to it, but I’m not sure if readers will read it that way. Ah, one of the major pains of being a writer. Enough, Brittany. I way off on a tangent and the readers want to know about my goals.)

    My 2025 Career Goals: Continue My Journey To Become A Software Engineer

    One of my 2025 career goals it continue my journey to upgrade from a Data Center Technician to a Software Engineer at Google. Will that happen this year? I’m leaning toward no, but there is a slight chance I could make a successful transition. For that to happen I need to accomplish the following:

    • Submit working code changes into the codebase: This shows not only can I write good code, but other coworkers who review it think so too.
    • Continue to write and update technical documentation: There’s quite of bit of outdated documents that are waiting for anyone knowledgeable to update them. And there’s need for someone to create new documentation for upcoming services and/or procedures.
    • Widen my professional relationships to include additional individuals from other teams: Not only does this help me get to know new people, but also create the opportunity to share information and improve productivity for both parties.
    • Improve my programming language skills: I will continue to improve my Python skills. I’m also interested in continuing my C/C++ education. I plan to do this through books. Yes, actual books. I love to read!

    My 2025 Career Goals: Move?

    Yeah, I’m thinking about moving this year. And by moving I mean transferring to a different work location. If I’m able to do that with a Software Engineering role, that would be fantastic! However, if I can’t then I would transfer to another Google data center.

    Why is moving one of my 2025 career goals? Frankly, I’m not that fond of Tennessee. As a lifelong Georgia resident I find living in its upstairs neighbor a boring. Also, the road infrastructure is worse in Tennessee than Georgia. I did move to Nashville to see if that would make life exciting, and it did for a bit, but I’m back to wanting more.

    Where am I thinking of moving to? Here’s a list of all the states containing a data center I’m interested in:

    • Georgia
    • Virginia
    • Texas
    • Arizona

    Now, if I’m able to get a Software Engineer job I would probably transfer to the Bay Area, Pittsburgh, or Raleigh. That’s where many openings are. (Granted, there are others in the Seattle area, but I’m not sure I would want to move there.)

    I plan to travel to Texas (and possibly Arizona) this year to get a feel of the different cities. I already traveled to Virginia a few times in 2023 and 2024 to perform some work in the data centers up there.

    When I would move would be around after August 1st, as I have to work in my current role for 12 months before transferring to a new role. So I wouldn’t start looking for a new position until late June or early July.

  • My 2024 Career Recap

    My 2024 Career Recap

    I had the idea to write a post about my 2024 career recap before I get on a plane in the morning to go back to Georgia to spend the Christmas holiday with various family members. So here it is!

    My 2024 Career Recap: Month-By-Month

    January

    After spending the previous month working the night shift in the Ohio data centers, I travel back to Tennessee to take a small break before getting back on the road to travel to other data centers. I spend two weeks in cold and snowy Northern Virginia (specifically Data Center Alley) to help deploy new hardware and wonder how people live in snowy areas. After my stint there, I travel back to Tennessee to work for a few days before traveling to Mountain View, CA for a training seminar. Here’s some pictures from that trip:

    February

    I spent a good bit of the month back at in Tennessee and offered my expertise on a new machine the site got after deploying it at other sites.The big news I got was I was chosen to travel down to the data center in Chile to help out with a deployment there.

    March

    Well, my trip to Chile turned out to be a trip to Belgium instead to help out the data center there. Before I went there I traveled to Omaha, Nebraska for the first time to help out at that data center. Then I went to Ohio for the umpteenth time to do some work there for about a week and a half. I traveled from there to New York city for my Employee Resource Group (ERG) conference. Then I went back to Tennessee to pack up for my trip to Belgium!

    April & May

    I spent six weeks in Belgium to help the team there deploy a new machine I had extensive knowledge of. It was my first time overseas and I loved my time over there. Here are three of the many pictures I took during my time over there:

    I did run into some trouble with the language because I can’t speak or understand French. Some citizens knew English. I tried my best to pick up some bits of language, but French is hard! However, Google Translate did help out. In addition to the difference in language, being six hours ahead of Eastern Time made it difficult to stay in contact with my family.

    I spent some time after work learning Java using a class on Udemy as I got the idea from my mentor to try to transfer into a Developer Relations role.

    I traveled back to the US in mid-May and took some well-deserved time off. It was a working vacation because I had to move out of my apartment since my lease was up. I brought my Tennessee peeps back some Belgian chocolate and other goodies, which made them happy!

    June

    Well, I didn’t get enough of Belgium because I traveled back to help the team there for another two weeks. Then I came back to the US in mid-June to find a new apartment in Nashville because I wanted to live in the big city! Finally, I made the decision to transfer off my team and stop traveling. Thus, I waited for a position to open up at Tennessee so I could work full-time there. Finally, I continued learning Java.

    July

    I applied for and got the role at the Tennessee data center! My new role was to work on the Network Projects team. The team’s role is to build out and/or upgrade the network so the machines can communicate with each other and the world. I spent the rest of the month transferring my duties to other coworkers on my team.

    August to September

    I officially started on the Network Projects team on August 1st and spent the months taking so many training classes and working on the data center floor. I stop learning Java and switch back to refreshing my Python skills.

    October

    I traveled to Nebraska again to facilitate a class and train other Data Center Technicians on how to fix Google’s ML machines.

    November

    After a lengthy delay the tasks for the Network Projects team arrived! I finally got to put all that training to use.

    December

    I continued to work various Network Projects tasks until the Christmas break. I dabbled learning the C programming language as I continued to improve my Python skills.

    And that’s all for my 2024 career recap. See y’all in 2025!