Philip Guo (Phil Guo, Philip J. Guo, Philip Jia Guo, pgbovine)

Python Tutor: The First Three Years

Summary
This article provides the backstory of how Python Tutor (pythontutor.com) gained momentum during its first three years of development, starting as a hobby project.

For the past six years, I've been developing Python Tutor (pythontutor.com), a free educational tool that millions of people from over 180 countries have used so far to visually understand their code when learning computer programming. Thousands of people use it every day to run tens of thousands of pieces of code in seven languages: Python, Java, JavaScript, TypeScript, Ruby, C, and C++. This tool has also become a platform for HCI, educational technology, and computing education research. Most recently, it formed the basis for my faculty job applications that got me a job at UC San Diego.

How did this project grow from nothing to its current state? I've been wanting to write a “history of Python Tutor” article for a while now but never found a good time to do so. There's actually no good time since there's no logical stopping point when this project is “done” ... I hope to keep it going as long as I can. So in this article, I'll just focus on how it all began in its first three years.

I'll assume you're familiar with Python Tutor. If you're not, play around with it first before reading further. Here we go!

Inception: December 2009

It all started in December 2009 when I was halfway through the fourth year of my Ph.D. I had spent the past semester creating IncPy, an auto-memoizing Python interpreter, and submitted a TaPP workshop paper on it. After finishing that submission, I was looking for something else to do over winter break as a diversion. I started thinking about the problem of parsing messy data since I had to do a lot of that in grad school. I wanted to create a web interface where the user could paste in a blob of semi-structured textual data and interactively “grow a parser” by making selections and having the tool heuristically suggest parse rules.

I was directly inspired by Kathleen Fisher's PADS, especially her POPL '08 paper, From Dirt to Shovels. (Kathleen co-taught the programming languages course that I TA'ed that semester.) Unbeknownst to me, my friend Sean Kandel was starting to work on a similar project called Wrangler with Jeff Heer, Joe Hellerstein, and others. Sumit Gulwani at MSR was also thinking about this problem in the context of Excel spreadsheets. But I was just pursuing this on my own for fun over winter break; I didn't have any intention of turning it into a serious research project.

As I started prototyping a GUI for data parsing, one immediate challenge was rendering semi-structured nested data in a sensible way. Tabular data was easy, but what if your data was weirdly nested? To explore this question, I hacked up some JavaScript code to take in JSON data, recurse into it, and render it as HTML tables that clarified its structure. I made a simple web app where the user can paste in JSON, click a “Visualize Me!” button, and the tool renders that data using colored table cells. This example shows a list of structures, where the permissions field points to a nested structure (click to see full-sized screenshot):

(If this primordial user interface reminds you of Python Tutor, it's not a coincidence. Hold that thought.)

At the same time as I was hacking on this data parser GUI, I found out about Khan Academy, which at the time was just a collection of YouTube videos where Sal Khan explained math and science concepts while drawing on a digital tablet. It was still a one-man operation with Sal recording videos in his home; there was no global phenomenon yet. (The hype around online education and MOOCs wouldn't begin until almost two years later.) I got hooked on watching those videos and was super inspired to make something similar for computer programming, which Sal didn't cover at the time since he focused on K-12 math and science.

I was especially impressed by the way Sal sketched out visual explanations of how mathematical operations worked step-by-step. I wanted to do something similar to explain how computer code worked, but I didn't want to tediously draw those diagrams by hand. Instead, I wanted to create a tool that would take a piece of code, run it, and automatically generate those step-by-step diagrams. Then I could annotate the diagrams or record videos with them to create my own “Khan-style” tutorials. Even better, this tool would also allow the learner to edit the code examples and see how the corresponding run-time diagrams change in response to their edits, which is impossible when watching pre-made videos.

Since I wanted my tutorials to be accessible to as many people as possible, I decided to create an automatic visualizer for JavaScript code since that language runs in all web browsers. I excitedly cold-emailed Sal, and we had coffee at Peet's in Mountain View to talk about these ideas (he wasn't nearly as busy back then!). He probably doesn't remember that meeting, but it was pivotal for inspiring me to keep going with this hobby project that had absolutely nothing to do with my Ph.D. research.

I knew that JavaScript debuggers such as Firebug (the most popular one at the time) could single-step through execution and inspect the state of all variables, so I thought I could use that to build my visualizer. However, after a lot of poking around I couldn't for the life of me figure out how to expose that debugging functionality in an ordinary web application without hacking the browser itself or forcing the user to install a plug-in, both of which would negate the “user doesn't have to install anything” benefit of web apps. The final nail in the coffin came from me emailing one of the lead developers of Firebug, who said that what I proposed was impossible because no browser at the time would expose these debugger hooks for security reasons.

I was sad that I couldn't realize my dream in JavaScript since it would've been super convenient for people to write code in a web browser and instantly visualize it without needing to send data to a server. Realizing that I had to run code on the server, I then turned to the language that I knew best and was thinking about most recently since I had been working on IncPy. Instead of a JavaScript Tutor, I decided to create a Python Tutor.

Version 1: January 2010

As winter break ended, I ditched my plans of working on the growable data parser since it seemed too hard to make headway on it as a solo research project. (However, thinking about this problem would inspire me to join the Wrangler project the following year and add Jeff Heer to my Ph.D. committee.) Plus, after meeting with Sal Khan, I became a lot more intrigued by the potential of Web-based technologies for online education.

At the time, I had a gut feeling that web browsers were just about to get good enough to support rich interactive learning experiences, and I wanted to be one of the first to explore this frontier.

I recycled much of the ideas and code behind my JSON nested data visualizer prototype from the prior month to now visualize data structures in Python code. After a few weeks of hacking, I “released” Python Tutor Version 1 on January 19, 2010 by sending an email to a dozen friends. It was a simple text box where the user enters Python code, clicks “Execute code” ...

... and sees a step-by-step visualization of what their code does to data structures at run time (click to see full-sized screenshot):

An astute reader will notice that while x and y appear like they are referring to two separate lists with identical values [1, 2, 3, 4], in fact they really point to the same list in memory. However, since Version 1 was a minimum viable product hacked up in two weeks, it didn't use pointers to explicitly capture such aliasing. Instead, everything was rendered as nested HTML tables just like in my JSON nested data visualizer. This was the primary limitation of Version 1, but I was happy to get it out the door and return to my Ph.D. work. It was a fun month-long diversion, but that was it.

The 1.5-Year Lull: 2010 – 2011

Nothing happened with this project for the next 1.5 years. I returned to working on my Ph.D. research, finishing up my fourth and fifth years. I showed Python Tutor to friends whenever I got the chance, but it wasn't something that I actively promoted. Online education wasn't at all on my mind during that time.

One relevant trend I saw during that period was that more and more universities (including my alma mater, MIT) were starting to teach introductory programming courses using Python. And as MOOCs booted up in subsequent years, many of those were also taught with Python. Thus, it was tremendously fortunate that I ended up creating a visualizer for Python and not JavaScript simply because I couldn't get JavaScript step-by-step tracing working in the browser. Otherwise this tool would not have become nearly as popular, since JavaScript was not (yet!) a common teaching language.

The one stranger who contacted me about Python Tutor during that time was Professor Peter Wentworth at Rhodes University in South Africa. Besides teaching Python, Peter had also customized Allen Downey's popular textbook Think Python: How to Think Like a Computer Scientist into a Rhodes Local Edition (RLE) that used Python 3.

Peter found Python Tutor online, liked it, and wanted a version for Python 3 to use in his teaching; it supported only Python 2 back then, and porting was non-trivial. Since I didn't have the time or expertise to port it to Python 3 myself, in December 2010 I zipped up the source code and gave it to him to hack on. I didn't even bother open sourcing it at that point since I figured nobody would care, and I was too busy with my Ph.D. work. (I finally put it on GitHub in July 2011.)

By the end of 2010, Peter and his students finished a Python 3 port and hosted it on their university's server. I happily linked to it from my official Python 2 version. I was excited that I had at least one real user, and from halfway around the world too!

My first three users: Summer 2011

Aside from Peter, two other professors started using Python Tutor in Summer 2011 as they prepped for fall courses. Feedback from these first three users inspired me to evolve it into Version 2.

In July, Peter introduced me to Brad Miller from Luther College in Iowa, who did his own port of Think Python called Learning with Python: Interactive Edition. Brad later generalized that resource into a platform called Runestone Interactive, which now hosts digital textbooks from well-known computing education researchers such as Mark Guzdial's group. Brad wanted to hack on Python Tutor to embed it within his interactive digital textbook so that students could play with visualizations as they read.

As the summer was winding down in September, Suzanne Rivoire from Sonoma State University (near San Francisco) told me that she had been using Peter's Python 3 port of Python Tutor in her introductory courses. I knew Suzanne a bit already since she worked in the office next to mine at Stanford when she was a Ph.D. student, and I was also friends with her younger sister. I was happy to know that I had a third user, but I also realized that I should make an official port to Python 3 instead of solely relying on Peter's mirror site hosted in South Africa. (I didn't end up doing that for another year, though, mostly due to me prioritizing finishing my Ph.D. and job hunting.)

I spent that summer interning at Google, and as I was moving to Harvard to begin the sixth and final year of my Ph.D., I found myself with one crucial month of spare time. (Recall that I created Python Tutor Version 1 in about a month over winter break, so that amount of time was enough to make a bout of concentrated progress.) Since I now had real users whom I could talk to, I decided to heavily revamp the Python Tutor interface to make it more usable. Throughout this process, I sent mockups and prototypes to my three users – Peter, Brad, and Suzanne – and they gave me valuable feedback from the perspective of professors who were using it to teach introductory programming courses. And since MIT was right next to Harvard, I also went over to Rob Miller's HCI group meetings to pitch my prototypes and get feedback from him and his students. (Little did I know that two years later I would return as Rob's postdoc.)

Version 2: October 2011

After a month of furious hacking, on October 4, 2011, I sent an email to a few dozen friends and colleagues announcing Version 2. Here is a screenshot from running on the same example code:

The biggest change from Version 1 was that the visualizations now explicitly illustrated pointer aliasing. Thus, x and y are shown here as actually pointing to the same list in memory.

I also made a template-based framework where an instructor can create practice problems. Learners can write code, run it against instructor-provided test cases, and then use Python Tutor to visually debug when they get something wrong:

(Unfortunately this feature atrophied as I focused more of my efforts on core visualizer development, but it's still there in a much slimmer form as the “Create test cases” button on the site.)

While this project started as a hobby, I now had an ulterior motive for polishing up Version 2 as much as possible: I wanted to get a full-time job working on tools for online education. Since I was starting my final year of Ph.D., I was starting to think seriously about what I wanted to do afterward. I was a bit burned out by my dissertation research direction (even though in hindsight I really loved it!), and there was something about online education that lit a spark in me. This was Fall 2011; the Big Three MOOC providers – Coursera, edX, Udacity – were on the verge of launching in the coming months. Something electrifying was in the air, and I sensed it. I wanted to show off Python Tutor v2 as my “portfolio project” when job hunting in the coming months.

Fortunately I didn't have to look too hard. Incidentally, I received a full-time software engineering job offer from Google the day after launching v2. I had been an intern there last summer and did a full-time interview at the end. As soon as my offer came in, I immediately emailed folks within Google who were doing education-related work to shop around Python Tutor.

My resume got bounced around internally within Google for a few weeks. Then I woke up one morning to a cold-email from Peter Norvig, who at the time was teaching the first Artificial Intelligence MOOC with Sebastian Thrun, which was the course that would eventually launch Udacity. Peter wrote:

Hi Philip, I got [your resume] from [X]. We had just this week been playing with your Python Tutor. We were trying to figure out what a good API would be to allow custom drawing/layout of objects (for example, drawing a binary tree and traversing it as a program execution unfolds).

I'm personally very interested in Education, and in exactly the kinds of things you are doing, so I'd love to talk with you.

-Peter Norvig

Long story short: We had a great series of conversations, and I signed up to join his group within Google Research in July 2012 when I planned to finish my Ph.D.

By the start of 2012, even though Python Tutor still barely had any users, there was enough buzz around the online education wave building up at the time that I felt passionate about continuing down this path for my career. I had no idea what exact sort of career I'd eventually have, or where I'd end up working, but I knew that I wanted to keep making headway in this domain.

Version 3: Summer 2012

Summer 2012 at Google was magical. Under Peter's unbelievably generous leadership, I was able to devote a large fraction of my working hours to Python Tutor from July to October 2012. I had a Unicorn Job for those four months. Every day was amazing.

Besides iterating on the design closely with Peter, I also worked a lot with John DeNero. At the time, John was a research scientist at Google who also taught the 1,000+ student introductory Python course at UC Berkeley! In 2014, he left Google to become a tenure-track teaching professor at UC Berkeley. I can't imagine a better person for that job since he was already doing it while working full-time at Google.

I coded a ton during those four months. John helped me (finally!) add support for Python 3 since he needed it for his Berkeley course and accompanying textbook. He also nudged me to make lots of detailed technical improvements that would help his own teaching, such as support for closures and higher-order functions. Peter and other colleagues suggested (now-central) features such as encapsulating state within an easily sharable URL and making the visualizations embeddable via iframes. I also rewrote the visualization engine using D3.

On September 18, 2012, I released Python Tutor Version 3, which is the version that's currently live on pythontutor.com (as of June 2016). Besides a bunch of cosmetic UI improvements ...

... it also visualizes heap-to-heap pointers so that it can render arbitrary linked data structures in a sensible way:

(v2 could do only stack-to-heap pointers, and v1 had no pointers.)

Another significant code improvement was encapsulating each visualizer instance into a self-contained JavaScript object. Thus, multiple visualizers could now be embedded within a single web page without interfering with one another, which was crucial for embedding in digital textbooks and online course materials. (In v1 and v2, only a single visualizer could be displayed on a page, since there was no encapsulation; all state was global!)

In terms of making the v3 release announcement, aside from emailing a few dozen friends and colleagues as usual, I now had huge leverage from being at Google. The Research at Google PR people were constantly looking to publicize interesting open-source projects that employees were working on, so I got them to write a blurb about Python Tutor and post it on their Google+ account. At the time, this account had over 153,000 followers, which gave Python Tutor instant worldwide exposure. They also featured it on the Google Research home page for a few months, which kept traffic flowing in. This was a pivotal moment for the project, and it wouldn't have been possible had I not been at Google and reached out to the right PR folks at the right time.

Best of all, this initial Google+ post attracted the attention of Guido van Rossum, the creator of Python, who rebroadcast it to his own legion of online fans. Guido was also working at Google at the time (he would leave for Dropbox soon afterward). I arranged to meet up with him in person and nervously watched as he played with Python Tutor. Funny enough, his first few attempts at writing Python code in the browser led to syntax errors:

But still, it felt good to get the thumbs-up from Guido himself!

It was now nearing the end of 2012, three years after I started this project as a winter break hobby back in December 2009. The Big Three MOOC providers – Coursera, edX, and Udacity – were fully booted up and aggressively trying to expand. Fortunately for me, they all used Python in their introductory programming courses. That fact, combined with the initial publicity from the Research at Google posts and ensuing viral spread on Internet news sites, provided the perfect mix of conditions for usage to skyrocket in the coming years. With zero money spent on advertising, in the next three years Python Tutor organically grew from almost no users to around two million users from over 180 countries.

Epilogue (for now)

There's so much more to this story than I have time to tell right now. Soon after releasing Python Tutor v3 in Fall 2012, I decided to leave Google to re-enter academia, pivoting my research focus to HCI and online learning. In the past four years, this tool has become an experimental platform for prototyping, deploying, and evaluating my research ideas, which have in turn led to academic publications and funded grants. For more details, read my 2015 faculty job application research statement.

One major implementation effort over the past two years has been expanding beyond Python. I was very lucky to have chosen Python back in 2010, but to increase the impact and longevity of this tool, I knew that it had to support more languages. So far I've implemented support for six other languages: Java, JavaScript, TypeScript, Ruby, C, and C++ (although the Java backend was originally written by David Pritchard and Will Gwozdz). Unfortunately I still haven't found a better project name yet, so “Python Tutor” will have to do for now.

Most recently, I've been trying to use Python Tutor to build visually-augmented REPLs and live programming environments for computing education. There are also 10,000 other ideas on my to-do list, most of which I'll probably never get to. So stay tuned to see what's coming up next!

Created: 2016-06-02
Last modified: 2016-06-02
Related pages tagged as software:
Related pages tagged as research: