This year marks the 40th anniversary of my graduation from the North Carolina School of Science and Mathematics (NCSSM). Attending NCSSM was one of the most formative experiences of my life, but to be honest I have never been that big on the reunions. For some reason I am super eager to go to the 40th.
Since it has been four decades since I’ve seen most of my classmates, I thought it would be cool to come up with a little game. In the US most schools used to produce a “yearbook” (sometimes called an “annual”) which is a large book containing pictures from the school year. While formats can differ, there is always a section for each class with pictures of the people in that class. I thought it would be cool to scan in all of those pictures and then create an online game where you have to match the person’s picture to their name.
The problem is that I do not consider myself a programmer. While I got my first computer in 1978 and did a lot of coding back then in BASIC, FORTRAN, Pascal and a little C when in college, I haven’t programmed seriously in decades. I mean, I can write a simple bash script and I can usually hack something that kind of does what I need into something that does what I need, but I would struggle to write “Hello world!” in any modern language.
TL;DR: We made a yearbook game where you try to match a name to the correct picture using generative AI.
But I don’t need to know how to code if I have access to generative AI, right? (grin)
I have to admit that I’m a little burned out by all the GenAI hype going on lately, but recently my boss pointed out we were in the same boat when cloud computing was first a thing. It was so bad that my friend Spot Callaway did a presentation [download] where the first four minutes was nothing but slides with the word “cloud” on them.
Now I work for a major cloud provider and cloud computing is pretty much everywhere. It doesn’t seem so bad anymore. My boss’s perspective on GenAI really changed my mind and now I had a reason to try and use it.
I am not the sharpest knife in the drawer, but my superpower is that I know a lot of very smart people. One of those is Ricardo Sueiras, and I figured he would be just the person to help with my project. Last Wednesday we set up a time to meet and to create my game.
First I had to digitize the pictures. People need to remember that, back in 1984, pictures involved this thing called “film”. Things we take for granted today were just impossible back then, and I am actually somewhat in awe of the people who put together the yearbook without the help of digital publishing. The pictures for our class photos were taken in color but in the yearbook they were published in black and white, which can wash out details when printed, but I didn’t have access to anything better. I started with our senior year yearbook since the senior class pictures were printed out larger than the junior class one.
After scanning in twelve pages and cropping each person into their own photo, I saved them in the format $NAME.png. Since I suffer from mild OCD, I had to go back to the junior year yearbook to get pictures of people who didn’t have a senior picture, either because they didn’t return for the second year or they missed picture day. When I was done I had a little over 200 pictures.
When I originally talked to Ricardo about the game, I figured we would show a picture and then offer some choices as to who it was. In fact, he went ahead and experimented with creating that game.
But as I thought about it, I figured most of the fun would be in seeing the pictures and it would take awhile to cycle through 200 or more of them, so I changed the game to present a single name and then four pictures as choices.
One other thing I did was create a CSV file containing the student’s name and their gender. Note that back in 1984 people weren’t as publicly gender fluid as they are now, so I went with the gender by which I knew each person. Feel free to gently correct me if I need to swap one, but I thought it would be a little more difficult to guess if a person with a masculine-sounding name was presented with four masculine-looking pictures.
With everything ready I jumped on a call with Ricardo. Now another thing that has changed since I used to program is that most people use an IDE. When I first started writing code I used a line editor, not even a full screen editor, so IDEs are just magic to me. Ricardo uses Visual Studio, and we decided to use Amazon Q (‘natch) which has an easy to use plugin.
The first thing we had to do was map the pictures to a new name. If you were asked to match “Tarus Balog” to the right picture, it wouldn’t do to just mouse over all four until you found “Tarus Balog.png”. Not only did Q create a script to rename all of the files by numbers, it updated the CSV file so that the correct file name was now included as a column, so now the file had name, gender and image number.
Ricardo decided to use Python to write the code and to host it in Flask, which is a simple Python web framework. It was surprisingly easy to get the first pass working, but we could never get the match to work. After debugging it, it seems like it was trying to match the correct person in one result to the random result of the next iteration. What’s weird is that once in awhile it would work, if the picture you chose just happened to be the correct guess for the next game, but it was very rare.
We tried a number of prompts to get Q to fix it, but the final solution involved pasting the code into Amazon Bedrock, choosing a different LLM and explaining what was happening. It created a result using a Python session object and, voila!, it worked.
That turned out to be about half of the project. I still wanted to be able to host it on my web server, but I had been lazy about upgrading Ubuntu and the version I was running didn’t support Python 3.10 (which was required for one of the libraries we used). So time to do a production upgrade and deal with those issues. I also spent a little time editing the web page templates and the CSS file (it turns out NCSSM publishes a brand style guide). I also went to find an old NCSSM logo, what we used to call “burning diapers” versus the modern one that looks like a stylized atom, to use a background.
Flask runs by default on localhost port 5000, so I set up a proxy in the Apache web server to make it accessible (I didn’t want to mess with SSL in Flask as I know my way around Apache configurations). But since I run WordPress in the root of https://tarus.io the submit didn’t work when accessed through the proxy, so I ended up creating a subdomain to host it. The finished product is at https://classof1984.tarus.io.
And to save you the time refreshing to find my picture, here it is.
Yes, my hair was magnificent.
One last note about those pictures. Not everyone in our class managed to live until the reunion. One of my beta testers mentioned that she was a bit triggered by seeing the picture of a friend of hers who had died from cancer. She asked me if I could remove pictures of those people we knew were no longer with us.
We talked about it and I could understand her issue but I had a different reaction. To me seeing pictures of those who had passed made me think of them fondly. Another beta tester said that he would feel like we were “erasing” them if we took them out. So it was decided to leave them in. It was funny to me how much thought needs to go into even the simplest app (well, if you care about not being a d*ck).
The last task was to upload the files to GitHub, which was my first ever repository even though I joined in 2006. We have generative AI to thank for that.
It was a lot of fun and now I’ve downloaded Visual Studio to my own computer and I plan to make even more programs.
Phear.