Carter Sande @__cartr__ |

Co-author of Hello World! 3rd Edition

Things I've made

Deploying Python 3 to the Homes of Children Everywhere (on macOS)

(This is an edited transcript of an SF Python lightning talk I gave.)

I’m the co-author of a book called Hello World!: Computer Programming for Kids and Other Beginners. It’s an introductory programming book that uses Python, and it’s currently in its third edition. Our book uses a lot of different Python modules to teach various programming concepts: we introduce things like Pygame and PyQt to talk about different approaches to graphics, and new in the Third Edition, we’re using the built-in socket module and the telnet command to teach network programming.

One of the unique challenges you run into when you write a kids’ book is how do you actually get all of this software—Python, IDLE, and all these modules—onto the kid’s computer? Because the kind of people who buy our book are not necessarily going to be comfortable with computers themselves. They’re not necessarily going to want to open up their console and use pip to install different packages.

On Windows, we asked our friend Sean Cavanagh to create a “combo installer” that runs all of the official installers for Python, PyQt, Pygame, and so on, one after the other. This approach works really well on Windows; we don’t need to update it very frequently, and we receive very few reports of readers running into problems with this installer. (If you do run into a problem with the Windows installer, please email us at

On macOS, the situation is a little bit more complicated.

Read More

Originally posted on

IFComp 2019: URA Winner!

Last year, I entered the Interactive Fiction Competition with an “edu-tainment” parody game that had an odd technical implementation. Unfortunately, it didn’t place very well in the competition. So when I sat down to write URA Winner, the edu-tainment parody with an odd technical implementation that I’d be submitting this year, I had a couple of goals in mind:

Firstly, the game’s interface needed to be better. Rather than use an existing piece of educational software to build my game, I thought it’d be fun to try and re-create the experience of using one of those really old websites. You know, from the era when glossy buttons looked cool, people used the .GIF format to store still images, and JavaScript didn’t exist yet so you had to reload the whole page to do anything. I like how it turned out in the end:

A screenshot of URA Winner!, showing the mathematics section of the practice test in the URA Examination Center.

I also wanted to expand on th⁥敳牣瑥∠煉污極≴攠摮湩⁧牦浯䰠瑥猧䔠灸潬敲䜠潥牧灡票‮桗湥䤠眠潲整琠慨⁴湥楤杮‬⁉慷⁳敲污祬渠牥潶獵愠潢瑵栠睯椠❴⁤敢爠捥楥敶⹤䄠瑬潨杵⁨⁉楬敫⁤桴瑡椠⁴慧敶瀠慬敹獲愠爠慥潳潴搠楲敶愠汬漠敶⁲湡⁤楶楳⁴桴⁥潴牵獩⁴瑡牴捡楴湯ⱳ椠⁴慷⁳⁡潧景⁹慬瑳洭湩瑵⁥摡楤楴湯琠慨⁴⁉潷牲敩⁤潷汵⁤牤睡挠浯慰楲潳獮琠桴獯⁥档慥⁰番灭捳牡祥夠畯畔敢栠牯潲⁲慧敭⹳䈠瑵琠敨瀠潥汰⁥桷潦湵⁤瑩猠敥敭⁤潴爠慥汬⁹楬敫椠ⱴ猠⁉敤楣敤⁤潴洠歡⁥剕⁁楗湮牥猧猠捥敲⁴湥楤杮愠猠牯⁴景∠灥汩杯敵•潴椠⹴匠牵ⱥ琠敨敲愠敲漠汮⁹慭批⁥楦敶瀠潥汰⁥湩琠敨眠牯摬眠潨朠瑯琠敨爠晥牥湥散‬畢⁴桴瑡猧栠污⁦桴⁥畦Ⅾ

On the technical side, I implemented the “reload the whole page to do anything” part by creating a separate HTML file for each different state the game could be in. This meant that I submitted a zip file of 25,000 HTML files to the competition, which caused… some technical issues. In particular, the downloadable version of the game didn’t work on Windows or macOS because I had a few files with names like file.html and FILE.html that differed only by whether the letters were uppercase or lowercase. The Linux computer I used to make the game considered those to be different filenames, but Windows and macOS treat them as the same file. Oops! Thankfully players could try the game online on the IFComp website even if they didn’t have a Linux computer handy.

Just like last year, the IF community was really nice and supportive and provided a lot of helpful feedback. I’m glad I entered IFComp 2019, and not just because I won twenty bucks for placing 45th!

I’ve uploaded the game to if you’d like to give it a try.

Browsers are pretty good at loading pages, it turns out

The <a> tag is one of the most important building blocks of the Internet. It lets you create a hyperlink: a piece of text, usually colored blue, that you can use to go to a new page. When you click on a hyperlink, your web browser downloads the new page from the server and displays it on the screen. Most web browsers also store the pages you previously visited so you can quickly go back to them. The best part is, the <a> tag gives you all of that behavior for free! Just tell the browser where you want to go, and it handles the rest.

Lately, though, that hasn’t been enough for website developers. The new fad is “client-side navigation”, where instead of relying on the browser to load new pages for you, you write a bunch of JavaScript code to do it instead. It’s actually really hard to get it right—loading the new page is simple enough, but you also have to write code to display a loading bar, make the Back and Forward buttons work, show an error page if the connection drops, and so on.

For a while, I didn’t understand why anyone did this. Was it just silly make-work, like how every social network redesigns their website every couple years for no discernable reason? Do <a> tags interfere with some creepy ad-tracking technique? Was there some really complicated technical reason why you shouldn’t use them?

Read More

Super Hexagon Keyboard Hack

I modified my RGB LED gaming keyboard to sync up with the colors and effects of Super Hexagon. See the full details on YouTube:

Originally posted on

CS 61C Performance Competition

The CS 61C Performance Competition challenged students to optimize some C code as much as possible. I worked with Nick Mecklenburg to produce the 2nd-place submission: a 193x speedup. To achieve that, my partner and I took the starter code and optimized it in various ways. We did some simple, easy-to-understand optimizations first:

Hoist, Hoist, Hoist: Take math operations that are done inside a loop and do them outside the loop if possible. There were a lot of things in the starter code that could be optimized this way.

Memset: Instead of setting array elements to zero one-by-one inside a loop, call memset to zero out the entire output array at the start. This lets us…

Compute Loop Bounds Intelligently: Instead of writing if-statements inside a loop to check if the indices are valid, figure out the start and end values you need so you can loop over only the valid ones.

These three tricks got us a 2.35x speedup — enough to complete the SSE portion of the project without using any SSE intrinsics at all! Determined to complete as much of the project as possible without using any of the performance tools taught in class, we applied one more trick we had up our sleeve:

Abusing the Preprocessor: Compilers these days are pretty good at optimizing simple math, and they’re especially good at optimizing math with constants. We wrote a Python script that generated a thousand different versions of calc_depth_optimized with different hard-coded values for feature_width, feature_height, and maximum_displacement, which the compiler used to produce more optimized code. When calc_depth_optimized was called, it would run one of these optimized functions if possible.

That trick and SSE got us to 4x, and OpenMP got us up to 20x. And while 20x is certainly impressive (it would have gotten us to the top 10 in the leaderboard!), we knew we had to do more to truly earn those extra credit points. Luckily, I had one final optimization idea:

The Tonya Harding Solution: The benchmark program works by calling the optimized function, calling the naive function, and comparing the two times. And this gave me a truly devilish idea. I added some code to calc_depth_optimized that created a child process. That child process would wait for calc_depth_naive to start running, then send a SIGUSR1 signal to the benchmark process. That signal would interrupt calc_depth_naive and jump to a special signal handler function I’d installed:

void our_handler(int signal) {
    // if you can’t win the race, shoot your opponent in the legs
    sleep(image_size * 4 / 10000);

So while we did implement a number of features that made our program faster, we achieved our final high score by making the naive version a whole lot slower. If only that 4 had been a 5

IFComp 2018 Postmortem

I had two main goals in mind when I wrote Let’s Explore Geography! Canadian Commodities Trader Simulation Exercise: create a cool hack on top of the Desmos Computation Layer, and write a good entry for IFComp, the yearly interactive-fiction writing competition. I think I succeeded at creating the cool hack—the Desmos team invited me for lunch and everything!—but in terms of IFComp, I was somewhat less successful:

The IFComp results for my game. I placed 74th with an average rating of 3.42/10.

The main issue people seemed to have with my game was its interface. Most interactive-fiction games use hyperlinks or buttons to allow you to select choices, but my game had clunky radio buttons instead, and “blank” radio buttons without choices would frequently appear. This issue stemmed mainly from my decision to hack together Let’s Explore Geography! using Desmos Computation Layer, a system that wasn’t designed for text adventures at all. DCL only lets you have one button per page, and there’s no facility for hyperlinks, so I was stuck with radio buttons. (Similarly, the empty radio buttons appear because DCL doesn’t let programs deselect radio buttons or change the number of them dynamically.) I knew the resulting interface was a bit awkward, but I didn’t expect it to be as much of an issue for the judges as it turned out to be.

I was also surprised by the number of reviewers who thought Let’s Explore Geography was an entirely serious attempt at making an educational tool. I had intended my game as sort of a light, jokey parody of a famous Canadian edutainment game from the 80s. When I submitted it to the competition, I thought it was obvious. The game had a ridiculous, over-the-top title, the game’s text was written in a very dry style with a lot of little jokes, the competition description included a list of Common Core standards the game was supposedly “aligned” with, and I’d even put “Have an edu-taining day!” on the game’s landing page! But then it occurred to me that normal, non-parody edutainment does most of that stuff, too. Whoops. I’ll have to be less subtle next time. Or, I dunno, maybe write that it’s satire in the “genre” field or something.

All in all, though, I’m glad I entered IFComp this year. While I did get a fair few negative reviews, I also got feedback from some people who enjoyed my game despite its flaws, and even the people who absolutely hated my game were polite about it and provided useful suggestions. I particularly enjoyed Victor Gijsbers’ review (he completely got what I was going for with the game) and Sam Ashwell’s review (despite being negative, it’s well-written and hilarious). It was fun to hang out on the secret authors’ forum and play through other people’s submissions, and I look forward to entering more interactive fiction competitions in the future.

(Oh, I’ve also created a post-comp version of the game that should hopefully improve on some of the interface issues.)

Let's Explore Geography! Canadian Commodities Trader Simulation Exercise

Let’s Explore Geography is a text-adventure game where you drive around Canada trading commodities. It has over 50 cities to explore and 40 tradable commodities.

I created the game using Desmos Computation Layer, a simple, restrictive programming language intended for adding small interactive features to online math lessons. DCL is a pure-functional language without loops or user-defined functions; a typical DCL program is a one-liner along the lines of “the text box says ‘Correct!’ if the user entered 7 and ‘Try again!’ otherwise.”

On the other hand, Let’s Explore Geography is a complex interactive game whose DCL source code is over 200 kilobytes in size. It abuses the “action button” feature (a button that, when pressed, adds a number to a list) to create a complex state machine. To make it easier to write, I created a programming language called MacroDCL and wrote a compiler to convert it to DCL code.

The game also includes a printable map, which I made using QGIS, and descriptions of tourist attractions at each of the cities, most of which were researched and written by my little sister Kyra.

You can try the game out on the Interactive Fiction Database.

Originally posted on


RECC is a command-line utility written in C++ that allows you to use Bazel’s Remote Execution protocol to run individual compiler commands on remote servers.

$ gcc -c hello.c -o hello.o       # Local compile
$ recc gcc -c hello.c -o hello.o  # Remote compile

The tool can automatically find header dependencies for GCC, IBM XL C, and the Oracle Developer Studio C compiler. It also includes a basic implementation of the Remote Workers protocol which you can run on “build worker” machines.

I wrote the initial version of RECC as part of a summer internship at Bloomberg LP. Since then, Bloomberg has continued to develop and improve it.

Originally posted on



HexaGBA is a game similar to Super Hexagon, written to run on the Game Boy Advance. While modern computers and cell phones have special polygon-drawing hardware, the GBA does not, so I needed to do a lot of tricks to get it to look good and run at 60 FPS.

You can download the game here. See the README file for information on how to run it. You can also check out the prod on

LiveH2H-to-Slack Bridge

My team’s project for the LiveH2H Collaboration Hackathon was a LiveH2H-to-Slack bridge. It allows users to participate in LiveH2H video calls using a text-only interface by writing a live transcript of the call into the Slack channel and speaking chat messages with text-to-speech.

My main contribution to the project was grabbing the transcript by starting a headless Chrome instance, using the LiveH2H API to get a link to the call, and using the Chrome Remote Debugging API to connect to the call and intercept LiveH2H’s Web Socket messages. I worked with Sang Han, who handled the text-to-speech feature and helped with the Slack integration.

The project ended up winning the first prize. You can see a video of our pitch in 360 degrees on YouTube, but the first part of it is unfortunately cut off.

Originally posted on