Static and Dynamic Typing: A Point of Friction
By: Aaron Chen
Tags: Python3, Data Science, Python, Debugging, Learn To Code

Yes, I started this one with a pun.

Hi everyone! I’m back again to talk about something that I think is pretty cool and is both new and old.

One of our instructors gave us a quick lesson on something that he told us was called “static typing”. At the time, I didn’t understand why we would use static typing and why he thought it was such a cool feature. From my point of view, static typing seemed to make Python code longer and even more detailed than it needed to be. I realize now, well after that first introduction, that static typing is quite powerful. We did not use it much in our classes or projects in the bootcamp, but I think it would be a good idea to actively incorporate it.

What is dynamic vs static typing?

Dynamic typing? From http://gph.is/1oXJHnO

Static typing? From http://gph.is/2aRJKNj

Static typing is kind of the opposite of how Python was made. Python by default uses dynamic types for variables, which means that a coder can declare variables without stating what data type they are and the types are given by Python in the background automatically.

For example, if we had

counter = 0 # Python

counter would be of type int . While we as humans could look at that code and say “of course!”, Python wouldn’t actually know until it ran the code counter = 0 and assigned the int type to counter.

Here’s where I realize my memory is bad: My previous experience with Java years ago should’ve set off alarm bells as Java requires data types for variables to be declared when the variable is created, unlike Python. For example, in Java, I would’ve had to have

int counter = 0 // Java

Ok, so how and why is static typing in Python helpful? Wouldn’t dynamic typing be better since that was how Python was made? Well, yes and no. Let’s think about this according to the Zen of Python ( https://www.python.org/dev/peps/pep-0020/). Dynamic typing certainly saves keystrokes and time for developers, and makes for prettier, simpler, and sparser code. Basically, dynamic typing goes against the “Explicit is better than implicit” aphorism but better fulfills the aphorisms “Beautiful is better than ugly,” “Simple is better than complex,” “Sparse is better than dense,” and “Readability counts.”

Using static typing in Python, or rather utilizing the optional static type checker mypy (http://mypy-lang.org/), allows for better error checking and debugging! Now that I’m more experienced with data science, I can tell you that I’ve run across a few different datasets where a human (say me, most of the time and when I’ve had enough caffeine) looks at the data, somewhat logically classifies what the data is and how it can be used, and then begins actually working with the data in code just to see how differently the machine spirit handles it.

Easiest example? Let’s make a card picker game in Python. If you’ve never really looked at a deck of cards, been bored, and pondered a world where 4 2D kingdoms fight over treasure with only 13 members in each kingdom, let me explain what’s in a deck of cards. We’re going to ignore the (usually 2) Joker cards as well as the blanks and the rule cards, and we’ll find 52 cards split among four different symbols with 13 different ranks for each symbol. These symbols are the Clubs, Diamonds, Hearts, and Spades and the ranks are Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, and King. Now, look back at the ranks and realize where there could be a problem. A human might look at the ranks and say “Well, these cards are technically categories and combined with the fact that some have names, I would use strings for the card values.” As such, I would declare hearts = ['A’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘10’, ‘J', ‘Q', ‘K'] . When debugging, the developer may keep in mind “Everything has to be a string” and never run into an issue because they would always use strings as inputs.

However, the USER of this game may not have this in mind! They may input a 5 card as the integer 5 instead of the string ‘5’. In this case, the game would never agree with the user as int 5 is never equal to string ‘5’.

Original card picker script, which in my head is named “Jean Luc”

Hey wait a minute…Now that I actually ran the code…

I take most of what I just wrote back: through writing the pick_card script, I ended up finding out that inputs are taken as strings! In an extremely roundabout way though, this points out one of the benefits of static typing: It makes explicit what you expect to provide as an argument and what you expect to receive from a return.

Demo for card picker with explicit “static” typing.

While this is something that can be fixed with type casting in the code or by explicitly asking for strings, this is not always applicable for larger scale projects.

For example, let’s look at our King County real estate data:

This is a subset of the King County

Residential Building zip provided at

https://info.kingcounty.gov/assessor/DataDownload/default.aspx

We can see that there are values that are technically numeric (zip code, majorID, minorID) but should not actually be integers or floats. Logically, we would process them as strings, such as when we concatenate the major and minor ID values to make parcelID. However, if we allow majorID and minorID to be naively interpreted as numeric values by Python, we will end up with incorrect values for parcelID; the ID values might get added like integers, or Python may/will remove leading zeros. And in fact, the latter is what happens in the dataframe. The county states that parcelID values are 9 digits from being a concatenation of 5 digit major and 4 digit minor ID values, but some of the minor values are only 2 digits!

That leading zero issue is a much bigger problem than it seems! Think about time given in 24 clocks, or even trying to reapply the King County model to ANY of these zip codes:

https://simple.wikipedia.org/wiki/List_of_ZIP_Code_prefixes#000s

Then the model would give you errors because all of those leading zeros would be removed. Unless the developer knew about this issue beforehand, they could end up deploying code that would not return easy-to-find errors. In these cases, it would again be better to explicitly state what you’re looking to use as arguments and what you expect to receive back as a return.

So, I highly encourage using this feature, introduced to Python in version 3.6, to help with bug checking and even sanity checks for developers!