Helping Learners Look at Their Code

One of the ideas I’m using the Subject Matter Authoring With Jupyter Notebooks online textbook to riff around is the notion (which will be familiar to long time readers of this blog) of sharing the means of asset production with students. In many cases, the asset production I am interested in relates to the creation of media assets or content that is used to support or illustrate teaching and/or learning material.

For example, one well known graphical device for helping explain a simple algorithm or process is a flow chart. Here’s an example from an OpenLearn unit on Computers and compute systems:

The image may have been drawn using a flowchart generation package, or “freehand” by an artist in a generic drawing package.

Here’s the same flow chart (originally generated in SVG form) produced by another production route, the flowchart.js Javascript package:

The chart was created from a script with a particular syntax:

st=>start: start
in1=>inputoutput: Accept data from sensor
op1=>operation: Transform sensor data to display data format
out1=>inputoutput: Send display data to display
e=>end: end

st->in1->op1->out1->e

To begin with, each element is defined using a construction of the form: uniqueIdentifier=>blocktype: label. (Note that the space after the colon following the blocktype is required or the diagram won’t be laid out properly.) The relationship describing how the various blocks are connected is then described using their unique identifiers.

Using a piece of simple IPython magic (flowchart_js_jp_proxy_widget), we can create a simple tool for rendering flowcharts created using flowchart.js in a Jupyter notebook, or defining the production of an image asset in an output document format such as an HTML textbook or a PDF document generated from the notebook “source” using a publishing tool such as Jupyter Book.

(In a published output created using Jupyter Book, we could of course hide or remove the originating script from the final document and just display the flow chart.)

To update the flowchart all that is required is that we update the script and rerun it (or reflow the document if we are creating a published format).

One other thing we notice about the OpenLearn document is that it links to a long description of the diagram, which is required for accessibility purposes. Only, in this case, it doesn’t…:

(I really do need to get around to hacking together an OU-XML quality report tool that would pick up things like that… I assume there are such tools internally — the OU-XML gold master format has been around for at least 15 years — but I’ve never seen one, and working on one of my own would help my thinking re: OU-XML2ipynb or OU-XML2MyST conversions anyway.)

A very literal long description might have taken the form of something like “A flow chart diagram showing a particular process. A rounded start block connects to an input/output block (a parallelogram) labeled ‘Accept data from sensor’…” and so on. In one sense, just providing the flowchart.js source would provide an unsighted user with all the information contained in the diagram, albeit in a slightly abstract form. But it’s not hard to see how we might be able to automate the creation of a simple text creation script from the flowchart description. (That is left as an exercise for the reader… Please post a link to your solution in the comments!;-) Or if you know of any reference material with best practice guidance for generating long descriptions of flow charts in particular, and diagrams in general, for blind users, please let me know, again via the comments.)

So, that’s an example of how we can use text based tools to generate simple flow charts. Here’s another example, taken from here:

Simple flow chart (via pyflowchart docs)

This diagram is not ideal: the if a block feels a bit clunky, we might take issue with the while operation block not being cast into a decision loop (related issue – and me not reading the docs! This is a feature, not a bug, an automated simplification that can be disabled…), and why is the print() statement a subroutine? But it’s a start. And given the diagram has been generated from a script, if we don’t like the diagram, we can easily make changes to it by editing the script and improving on it.

At this point, it’s also worth noting that the script the image was generated was itself generated from a Python function defintion using the pyflowchart Python package:

The script is slightly harder to read than the original example, not least in the way the unique identifiers are designed, but it’s worth remembering this is currently generated primarily for a machine, rather than a person, to read. (We could create simple unique identifiers, for example, if we wanted to make the script more palatable to human readers.)

Whilst the script may not be ideal, it does function as a quick first draft that an author can work up. As with many automation tools, they are most effective when used by a human performing a task in order to support that task, rather than instead of a human performing that task (in this case, the task of producing a flowchart diagram).

We can also generate the diagram from a function in a Jupyter notebook code cell using a bit of IPython magic:

Creating a flowchart with pyflowchart magic

On my to do list is to update the magic to alternatively display the flowchart.js diagram generating script as well as optionally execute the code in the magicked code cell (at the moment, the code is not executed in the notebook Python kernel environment). And having a look at automatically generating human readable text descriptions.

It’s not just functions that we can render into flowcharts either. We can also render flowcharts from simpler scripts:

(Thinks: it might be nice if we could add a switch to add start and stop blocks to top and tail this sort of flowchart. Or maybe allow a pass statement at the very start or end of very end of a code fragment to get rewritten as start/stop block as appropriate.

So, here we have a couple of tools that can be used:

  • to generate a generative text description of an algorithm defined using Python code from an abstract syntax tree (AST) representation of the code;
  • to render a media asset (a flow chart diagram) from a generative text description.

So that’s the means of production part.

We can use this means of production to help support the creation of flowcharts in a relatively efficient and straightforward way. The lower the overhead or cost to doing something the more likely we are to do it, or at least, the more likely we are to consider doing it because of the fewer blockers to actually doing it. So this sort of route, this means of production, makes it easier for us to make use of graphical flow charts to illustrate materials if we want to.

If we want to.

Or how about if a student wants to?

With an automated means of production available, it becomes easier to create additional examples that we might make optionally available (either in final rendered form, or in a generated form, from a generative scripts) that some students might find useful.

But if we make the means of production available to students, then it means that they can generate their own examples. And check their own work.

Take the case of self-assessment activities generated around flowcharts. We might imagine:

  • asking a learner to identify which flowchart of several describes a particular code fragment;
  • which code fragment of several implements a particular flowchart;
  • what a flowchart for a particular code fragment might look like;
  • what a piece of code implementing an alogirithm described in a provided flow chart might look like.

In each of the above cases, we can use a generative code2flowchart method to help implement such an activity. (Note that we can’t go directly from flowchart to code, though we may be able to use the code to flowchart route to workaround that in some cases with a bit of creative thinking…)

In addition, my providing learners with the means of production for generaing flowcharts, they can come up with their own exercises and visualise their own arbitrary code in a flowchart format to self-check their own work or understanding. Whether folk really can be said to be “visual learners” or not, sometimes it can help drawing things out, seeing them represented in visual form, and reading the story back from what the diagram appears to be saying.

And if we can also get a simple flowchart script to human readable text generator going, we can provide yet another different way of looking at (which is to say, reading), the code text. And as with many accessibility tools, that can be useful for everyone, not just the learner who needs an alternative format in order to be able to access the materials in a useful and useable (which is to say, a meaningful) way.

PS Finally, it’s worth noting the some of the layouts that flowchart.js generates are a bit broken. Some people will use this to argue that “because it breaks on these really weird edge cases and doesn’t do everything properly, we shouldn’t use it for anything, even the things it does work well on”. This is, unfortunately, an all-too-common response in an organisation with a formal process mentality that also belies a misunderstanding of using automation instead of rather than by and in support of. There are two very obvious retorts to this: firstly, the flowchart.js code is open, so if we spot something is broken we can fix it (erm, like I haven’t) and make it better for everyone (and which will in turn encourage more people to use it and more people to spot and fix broke things); secondly, the flowchart.js code which the author has presumably ensured is logically correct, can be used to generate a “first draft” SVG document that an artist could rearrange on the page so that it looks nice, without changing the shape, labels or connectedness of the represented objects which are a matter of correctness and convention and which the artist should not be allowed to change.

Author: Tony Hirst

I'm a Senior Lecturer at The Open University, with an interest in #opendata policy and practice, as well as general web tinkering...