How to build a Custom Bingo Board with Python

J. Humms
4 min readFeb 2, 2022

At work, we like to play bingo for product launches at our company. Due to privacy concerns, we didn’t want to use an online tool, so I was tasked with building one for the team! Find how I did it below and some of the choices I made when building it.

First things first, I found a tutorial (no sense in reinventing the wheel) https://dadoverflow.com/2019/05/31/python-bingo/ and decided that it didn’t work as well as I wanted. Plus, I needed to build 50 and didn’t want to run the script 50 times.

So the first part is to load your packages, in this case, we will use Matplotlib and random.

import matplotlib.pyplot as plt
import matplotlib.style as style
import random
%matplotlib inline
style.use('seaborn-poster')

Then let’s create the list:

states = ["AL - Alabama", "AK - Alaska", "AZ - Arizona", "AR - Arkansas", "CA - California", "CO - Colorado",
"CT - Connecticut", "DC - Washington DC", "DE - Deleware", "FL - Florida", "GA - Georgia",
"HI - Hawaii", "ID - Idaho", "IL - Illinios", "IN - Indiana", "IA - Iowa",
"KS - Kansas", "KY - Kentucky", "LA - Louisiana", "ME - Maine", "MD - Maryland",
"MA - Massachusetts", "MI - Michigan", "MN - Minnesota", "MS - Mississippi",
"MO - Missouri", "MT - Montana", "NE - Nebraska", "NV - Nevada", "NH - New Hampshire",
"NJ - New Jersey", "NM - New Mexico", "NY - New York", "NC - North Carolina",
"ND - North Dakota", "OH - Ohio", "OK - Oklahoma", "OR - Oregon", "PA - Pennsylvania",
"RI - Rhode Island", "SC - South Carolina", "SD - South Dakota", "TN - Tennessee",
"TX - Texas", "UT - Utah", "VT - Vermont", "VA - Virgina", "WA - Washington", "WV - West Virginia",
"WI - Wisconsin", "WY - Wyoming"]
terms = [s.split('-')[1].strip() for s in states]
t = 0

Now let’s add in the code to generate one Bingo Board

# Section 1
random.shuffle(terms) # Shuffles the list randomly for different boards
terms.insert(12,"Free")

rowlen= 5 # makes a 5x5 bingo board

##################################
# Section 2
fig = plt.figure()
ax = fig.gca()
ax.set_xticks(np.arange(0, rowlen + 1))
ax.set_yticks(np.arange(0, rowlen + 1))
ax.set_xticklabels([])
ax.set_yticklabels([])
plt.grid(color='black',linewidth=1)
################################
# Section 3
for i, word in enumerate(terms[:rowlen**2]):
x = (i % rowlen) + 0.5 - len(word)/50
y = int(i / rowlen) + 0.45
ax.annotate(word, xy=(x, y), xytext=(x, y))
plt.show()

Let’s discuss some of the features of the code starting with Section 1:

random.shuffle(terms) # Shuffles the list randomly for different boards
terms.insert(12,"Free")
rowlen= 5 # makes a 5x5 bingo board

This part adds the “Free” Space. We do this by inserting Free into the 12th position, the middle position. Then we set the row length as 5 for a 5x5 board and we shuffle the terms (in this case State Names).

And section 2

fig = plt.figure()
ax = fig.gca()
ax.set_xticks(np.arange(0, rowlen + 1))
ax.set_yticks(np.arange(0, rowlen + 1))
ax.set_xticklabels([])
ax.set_yticklabels([])
plt.grid(color='black',linewidth=1)

This part will set up the graph so it shows as a grid with a line at each 1 increment both on the y as well as the x-axis. I didn’t want to see the axis labels so I set the list as empty, then I plotted with a black line.

for i, word in enumerate(terms[:rowlen**2]):
x = (i % rowlen) + 0.5 - len(word)/50
y = int(i / rowlen) + 0.45
ax.annotate(word, xy=(x, y), xytext=(x, y))
plt.show()

First, since this is a 5x5 board, we only want the first 25 States in the list, so we get that by specifying enumerate(terms[:rowlen**2]).

Then, for the x-axis, I use the modulo operator to get 0–4 (5%5 being the 0) and add .5 to place the words in the center of each box. I then center it even more by dividing the length of the words by 50 to enter them so that states like New York and Ohio are both centered.

Since we do not have to worry about the height of the words changing, I get the y-axis by getting the int (rounds down so that you get 1–5) of all the numbers and adding .45, that way each item in each row is at the same y-axis point.

Then I specify annotate, which adds the state text to the coordinates we just created!

Here is the result:

Now I had to make 50, so this is what the code looked like after I made the changes. All I had to do was create a loop that would run it 50 times and save each plot as a PDF. See if you can spot the code changes.

import matplotlib.pyplot as plt
import matplotlib.style as style
import numpy as np
import random
get_ipython().run_line_magic('matplotlib', 'inline')
style.use('seaborn-poster')
######################################################
states = ["AL - Alabama", "AK - Alaska", "AZ - Arizona", "AR - Arkansas", "CA - California", "CO - Colorado",
"CT - Connecticut", "DC - Washington DC", "DE - Deleware", "FL - Florida", "GA - Georgia",
"HI - Hawaii", "ID - Idaho", "IL - Illinios", "IN - Indiana", "IA - Iowa",
"KS - Kansas", "KY - Kentucky", "LA - Louisiana", "ME - Maine", "MD - Maryland",
"MA - Massachusetts", "MI - Michigan", "MN - Minnesota", "MS - Mississippi",
"MO - Missouri", "MT - Montana", "NE - Nebraska", "NV - Nevada", "NH - New Hampshire",
"NJ - New Jersey", "NM - New Mexico", "NY - New York", "NC - North Carolina",
"ND - North Dakota", "OH - Ohio", "OK - Oklahoma", "OR - Oregon", "PA - Pennsylvania",
"RI - Rhode Island", "SC - South Carolina", "SD - South Dakota", "TN - Tennessee",
"TX - Texas", "UT - Utah", "VT - Vermont", "VA - Virgina", "WA - Washington", "WV - West Virginia",
"WI - Wisconsin", "WY - Wyoming"]
terms = [s.split('-')[1].strip() for s in states]########################################################
for t in range(1,51,1):
if t == 1:
random.shuffle(terms)
terms.insert(12,"Free")
else:
terms.pop(12)
random.shuffle(terms)
terms.insert(12,"Free")
rowlen= 5 # makes a 5x5 bingo boardfig = plt.figure()
ax = fig.gca()
ax.set_xticks(np.arange(0, rowlen + 1))
ax.set_yticks(np.arange(0, rowlen + 1))
ax.set_xticklabels([])
ax.set_yticklabels([])
plt.grid(color='black',linewidth=1)
for i, word in enumerate(terms[:rowlen**2]):
x = (i % rowlen) + 0.5 - len(word)/50
y = int(i / rowlen) + 0.45
ax.annotate(word, xy=(x, y), xytext=(x, y))

plt.show()
fig.savefig("C:/Users/name/Downloads/Bingo Cards/%s-Bingo.pdf" %t)

--

--

J. Humms

I am a Marketing Analytics Manager excited about all aspects of advertising in the digital age.