FamiTracker Instrument Generator - Retrospective

Sunday 04 October, 2020

Tags: development retrospective

Coming off the back of my second project using the tkinter Python library to create a Linux desktop application, as well as new dives into the matplotlib and numpy libraries, it's time to have another retrospective to see:

Let's dive in for six more learnings - here is the the previous retrospective post if you missed it.

  1. Code structure was much better this time and better resembled a Python application.

    Especially when it came to the wave package itself that I created, this project feels more like a Python project. I tried to follow more importing standards and naming conventions where possible to achieve this and I think it worked out. Everything is nicely split up, with GUI views, waveform generation and export functionality being separated. I hope this also makes it easier to understand for any new eyes on the codebase.

  2. Better code re-use and inheritance all around.

    Any functionality that could be shared between the FDS and N163 waveform generation was made so by class inheritance where necessary to ensure there is as little code duplication as possible. Each expansion chip has it's own parent class which houses the majority of the functionality and then each waveform type (e.g. sine, triangle, sawtooth) has it's own child instance with specific parameters and baseline information. I'm particularly happy with the export file generation class which was made generic enough that both expansion chips can make use of, along with help from a constants class for referencing text strings.

  3. Towards the end of the v1.0.0 release, it was easy to recognise more and more why a test first approach would suit best.

    I think the realisation came when I was debugging a part of the waveform generation package and I noticed that the plot data was completely wrong. However, I was lucky to come across the fact that I had used an incorrect index on one of the lists housing the data. Now, if I had tests in place already with expected output values, then I would have been informed immediately that there is unexpected output from all of the generated waveforms. As it was only a small variation, I couldn't pick up these differences as there is already some variance on the randomly generated waveforms that isn't clear to the human eye.

  4. Laziness started to slip in towards the end of the project due to motivation.

    There are a couple of user experience issues that, if I'm being honest (and why wouldn't I be), were unacceptable even though I shipped the first version. The first one being the lack of a back button which takes the user back to the main menu so another expansion chip can be selected. Expecting the user to close and re-open the application via the command line isn't really acceptable at all. The second being the exception handling during the file export process. Currently, the app prints a warning in the command line if the cancel button is clicked due to there being a lack of valid filename being returned to continue. As these things were small, it's even more reason to fix them before release as apposed to just wanting to get something out the door.

  5. Never knowingly ignore any small details, especially after acknowledging them.

    Pertaining to the previous point about laziness and motivation, there were times when something I would have considered for the last project was not considered here. Your full effort should be given regardless of the task and project you're working on and it was no excuse here to be lax and gloss over the "small items". Everything matters, however small.

  6. Ensure the project is revisted to add additional functionality and essentials that were missing from the v1.0.0 release.

    I think it's imperative to revisit this codebase and finish what I started, to be true to myself and what I believe in - producing clean, well structured and well documented code. While I definitely made some advancements in the code architecture and how I write Python in general, I slipped up on fundamentals that I should consider every time I sit down to write code. It was a wake up call to not be complacent and write bad code just because you don't think anyone will ever see it or it won't ever be used again. Write every line like it's your last.

It's time to take a break from doing desktop app development and move onto some work with APIs and Flask, while still being able to use Python as still in the mood for more of that!

Jon

« Back