The Python Class that landed me an engineering role

Mike Tarpey
6 min readFeb 6, 2022

My junior year of high school was the first year when (for myriad reasons) I really shifted my mindset from “let’s take as many classes as possible” to “what career path am I even on?” In a bid to decide an answer to that very question, I was in three AP math classes that year: computer science, calculus, and statistics.

But something about AP Computer Science just didn’t resonate with me. I thoroughly enjoyed working with the teacher (shoutout Mrs. Ferran), but whether it was the Java-based curriculum or the verbosity of the language itself, it ultimately turned me away from a developer-focused career path and more toward my pure math classes…which eventually led to me spending my 20s as an actuary.

Fast forward 13 years later to February 2022, when I’m claiming in this article that I wrote a Python class that powered me into my first role as a software engineer…it’s a surreal feeling! I definitely have a ton more to say about the amazing actuarial teams I worked with, the profession as a whole, why it took me a decade to figure out it wasn’t for me, and words of encouragement/caution for those thinking about pursuing it themselves…but those are all better topics for another post.

The Python Bite

When I first started incorporating Python into my actuarial work back in mid-2019, it felt more natural to me than any other programming language I had touched to that point (Java, VBA, SAS…there are likely a couple others). I’m not alone in this sentiment, and I think the reasons for this phenomenon are well-documented by others (especially Michael Kennedy’s excellent Python podcast). Where other languages got in the way with syntax, Python got out of the way at a time when someone like me, still a non-developer-developer, was looking to create actuarial automations that would “just work”.

To be fair, I’m far enough down the engineering path at this point to start appreciating the value provided by more strongly-typed languages, and I also love where Python’s type hinting is going. I just want to emphasize here that Python’s relatively low bar to entry (not to mention the amazing open source community and packages) were essential in igniting the spark that eventually pushed me into career change.

When I started getting into technical interview prep seriously a few months ago, Python became my go-to tool when given the choice of language for the assessment (which was pretty common in my experience). Through a combination of personal projects, automation scripts, and sharing my work with other teams/departments, I had reached a point where I didn’t have to reserve bandwidth for Python syntax anymore because of how natural it felt. I had become comfortable enough to focus entirely on the technical interview questions themselves and how to problem solve them.

At the peak of my interview prep, I was doing a few problems on CodeWars per day, which boosted my problem solving confidence quite a bit more. And one fateful “Kata” I received one day ended up pushing me over the edge in a subsequent interview…

The Brute Force Recursive Sudoku Solver

Old copy of Penguin Sudoku 2006 I had lying around.
Old copy of a Sudoku puzzle book I had lying around.

Up to this point in my life, I had written very few actual Python classes. Most of my scripts at work had relied entirely on self-taught functional programming (which I was relieved to learn is a totally valid coding paradigm), in combination with popular open source libraries. Maybe I just never discovered the right learning resources for me, but I always found myself struggling to justify writing a class for anything…could this have been the same mental block that prevented me from gelling with Java all those years ago?

So, I’d like to formally thank the CodeWars algorithm for serving this one up for me right before a technical final interview a couple months back:

Write a function that will solve a 9x9 Sudoku puzzle. The function will take one argument consisting of the 2D puzzle array, with the value 0 representing an unknown square.

The Sudokus tested against your function will be “easy” (i.e. determinable; there will be no need to assume and test possibilities on unknowns) and can be solved with a brute-force approach.

For Sudoku rules, see the Wikipedia article.

I twisted my brain into knots for a few minutes…I suppose it could be easy enough to check a 2D array’s rows and columns for Sudoku validity, but what about those 3x3 mini grids I have to check? Should I do some [i:i+3] shenanigans in a few places?

Then, a spark…just make a Cell class! If I do that, I can give it all three attributes of a Sudoku board that need validation (row, column, and mini-grid), instead of just the inherent two dimensions (row and column) that a 2D array has. But let’s leave no room for error with that extra mini-grid attribute (which I call square in the code): we know it’s a function of the row and column! So we initialize it as such:

But why stop at just the Cell? (I had thoughts about reverting to my functional comfort zone here, but I forced myself to power down the object-oriented road and see what it would yield.)

With the Cell’s attributes safely tucked away, I started to write another class to represent the entire Sudoku Board. In my head, it needed to:

  • Contain an array of 81 of our Cells to represent the full board
  • Be capable of validating rows, columns and squares (no matter if the puzzle is unfinished or finished)
  • Be able to iterate through its own empty cells, trying all possible values and progressing/backing up repeatedly until the solution is found

Once I had these goals defined, it was just a matter of working through each goal and realizing/building what I needed! Here’s a sample of my rough thought process:

  • We need to be able to validate entire rows to make sure they contain each of the numbers 1–9…it would be helpful to have a method that returns all Cells in a given row! (Same for columns and squares)
  • Now we can build the validation methods on top of these methods
  • If every validation passes for a given cell, we move on to the next blank cell
  • If we run out of values that work in our current cell, it must mean a value we placed in a prior cell on the Board was wrong — let’s go back and change it
  • Repeat until board is solved!

The full GitHub Gist is below if you’re interested in the exact implementation I cooked up. But more importantly, Python had opened up yet another locked door in my brain. And just two weeks later, it paid off in a big way during a two hour technical interview. The entire second hour? “Design a parking lot using object-oriented principles.” Crushing victory — the job offer came next week!

Now for the twist: I was fortunate enough to have the luxury of choice and actually ended up declining this offer in favor of another one…but I think the article title is still technically true. =]

For those of you deep in the arc of career change like me, I wish you the best of luck! No matter who you are, thanks for reading — you can reach out to me anytime and let me know what you thought of this piece. I’ll be sure to share more stories from the transition soon, in addition to my new daily adventures as an actuary-turned-developer.

Full implementation:

-Mike Tarpey

--

--

Mike Tarpey

software engineer | former actuary | uconn | upenn | citizen of Earth | ars longa, vita brevis