Whilst reviewing / scoping* possible programming editor environments for the new level 1 courses, one of the things I was encouraged to look at was Philip Guo’s interactive Python Tutor.
According the the original writeup (Philip J. Guo. Online Python Tutor: Embeddable Web-Based Program Visualization for CS Education. In Proceedings of the ACM Technical Symposium on Computer Science Education (SIGCSE), March 2013), the application has an HTML front end that calls on on a backend debugger: “the Online Python Tutor backend takes the source code of a Python program as input and produces an execution trace as output. The backend executes the input program under supervision of the standard Python debugger module (
bdb), which stops execution after every executed line and records the program’s run-time state.”
The tutor itself allows you to step through code snippets a line at a time, displaying a trace of the current variable values.
Another nice feature of the Online Python Tutor, though it was a bit ropey when I first tried it out a few months ago, was the shared session support, that a learner and a tutor see, via a shared link, the same session, with an additional chat box allowing them to chat over the shared experience in realtime.
Whilst the Online Python Tutor allows URLs to saved programs (“tutorials”) to be generated and shared: link to the demo shown in the movie above. The code is actually passed via the URL.
One of the problems with the Online Python Tutor is that requires a network connection so that the code can be passed to the interpreter back end, executed to generate the code trace, and then passed back to the browser. It didn’t take long for folk to start embedding the tutor in an iframe to give a pseudo-traceability experience in the notebook context, but now the Online Python Tutor inspired nbtutor extension makes cell based tracing against the local python kernel possible**.
The nbtutor extension provides cell by cell tracing (when running a cell, all the code in the cell is executed, the trace returned, and then available for visualising. Note that all variables in scope are displayed in the trace, even if they have been set in other cells outside of the nbtutor magic. (I’m not sure if there’s a setting that allows you just to display the variables that are referenced within the cell?) It is also possible to clear all variables in the global scope via a magic parameter, with a prompt to confirm that you really do want to clear out all those variable values.
I’m not sure that the best way would be to go about framing nbtutor exercises in a Jupyter notebook context, but I note that the notebooks used to support the MPR213 (Programming and Information Technology) course from the Department of Mechanical and Aeronautical Engineering in the Faculty of Engineering, Built Environment and Information Technology at the University of Pretoria now include nbtutor examples.
* A cynic might say scoping in the sense not seriously considering anything other than the environments that had already been decided on before the course production process had really started… ;-) I also preferred BlockPy over Scratch, for example. My feeling was that if the OU was going to put developer effort in (the original claim was we wouldn’t have to put effort into Scratch, though of course we are because Scratch wasn’t quite right…) we could add more value to the OU and the community by getting involved with BlockPy, rather than a programming environment developed for primary school kids. Looking again at the “friendly” error messages that the BlockPy environment offers, I’m starting to wondering if elements of that could be reused for some IPython notebook magic…
** Again, I’m of the mind that were it 20 years ago, porting the Online Python Tutor to the Jupyter notebook context might have been something we’d have considered doing in the OU…
One of the things the OU seems to have gone in for big time lately is “learning design”, with all sorts of planning tools and who knows what to try and help us estimate student workloads.
One piece of internal research I saw suggested that we “adopt a University-wide standard for study speed of 35 words per minute for difficult texts, 70 words per minute for normal texts and 120 words per minute for easy texts”. This is complemented by a recommended level 1 (first year equivalent) 60:40 split between module-directed (course text) work and student-directed (activities, exercises, self-assessment questions, forum activity etc) work. Another constraint is the available study time per week – for a 30 CAT point course (300 hours study), this is nominally set at 10 hours study per week. I seem to recall that retention charts show that retention rates go down as mean study time goes up anywhere close to this…
One of the things that seems to have been adopted is the assumption that the first year equivalent study material should all be rated at the 35 words per minute level. For 60% module led work, at 10 hours a week, this gives approximately 35 * 60 * 6 ~ 1200 words of reading per week. With novels coming in around 500 words a page, that’s 20 pages of reading or so.
This is okay for dense text but we tend to write quite around with strong narrative, using relatively straightforward prose, explaining things a step at a time, with plenty of examples. Dense sentences are rewritten and the word count goes up (but not the reading rate… Not sure I understand that?)
As part of the production process, materials go through multiple drafts and several stages of critical reading by third parties. Part of the critical reading process is to estimate (or check) workload. To assist this, materials are chunked and should be provided with word counts and estimated study times. The authoring process uses Microsoft Word.
As far as I can tell, there is an increasing drive to segment all the materials and chunk them all to be just so, one more step down the line rigidly templated materials. For a level 1 study week, the template seems to be five sections per week with four subsections each, each subsection about 500 words or so. (That is, 10 to 20 blog posts per study week…;-)
I’m not sure what, if any, productivity tools there are to automate the workload guesstimates, but over coffee this morning I though I’d have a go at writing a Visual Basic macro to do do some of the counting for me. I’m not really familiar with VB, in fact, I’m not sure I’ve ever written a macro before, but it seemed to fall together okay if the document was structured appropriately.
To whit, the structure I adopted was: a section to separate each section and subsection (which meant I could count words in each section); a heading as the first line after a section break (so the word count could be associated with the (sub)section heading). This evening, I also started doodling a convention for activities, where an activity would include a line on its own of the form – Estimated study time: NN minutes – which could then be used as a basis for an activity count and an activity study time count.
Running the macro generates a pop up report and also inserts the report at the cursor insertion point. The report for a section looks something like this:
A final summary report also gives the total number of words.
It should be easy enough to also insert wordcounts into the document at the start of each section, though I’m not sure (yet) how I could put a placeholder in at the start of each section that the macro could update with the current wordcount each time I run it? (Also how the full report could just be updated, rather than appended to the document, which could get really cluttered…) I guess I could also create a separate Word doc, or maybe populate an Excel spreadsheet, with the report data.
Another natural step would be to qualify each subsection with a conventional line declaring the estimated reading complexity level, detecting this, and using it with a WPM rate to estimate the study time of the reading material. Things are complicated somewhat by my version of Word (on a Mac) not supporting regular expressions, but then, in the spirit of trying to build tools at the same level of complexity as the level at which we’re teaching, regex are probably out of scope (too hard, I suspect…)
To my mind, exploring such productivity tools is the sort of thing we should naturally do; at least, it’s the sort of thing that felt natural in a technology department. Computing seems different; computing doesn’t seem to be about understanding the technical world around us and getting our hands dirty with it. It’s about… actually, I’m not sure what it’s about. The above sketch really was a displacement activity – I have no misconceptions at all that the above will generate any interest at all, not even as a simple daily learning exercise (I still try to learn, build or create something new every day to keep the boredom away…) In fact, the “musical differences” between my view of the world and pretty much everyone else’s is getting to the stage where I’m not sure it’s tenable any more. The holiday break can’t come quickly enough… Roll on HoG at the weekend…
Sub WordCount() Dim NumSec As Integer Dim S As Integer Dim Summary As String Dim SubsectionCnt As Integer Dim SubsectionWordCnt As Integer Dim SectionText As String Dim ActivityTime As Integer Dim OverallActivityTime As Integer Dim SectionActivities As Integer Dim ParaText As String Dim ActivityTimeStr As String ActivityTime = 0 OverallActivityTime = 0 SectionActivities = 0 SubsectionCnt = 0 SubsectionWordCnt = 0 NumSec = ActiveDocument.Sections.Count Summary = "Word Count" & vbCrLf For S = 1 To NumSec SectionText = ActiveDocument.Sections(S).Range.Paragraphs(1).Range.Text For P = 1 To ActiveDocument.Sections(S).Range.Paragraphs.Count ParaText = ActiveDocument.Sections(S).Range.Paragraphs(P).Range.Text If InStr(ParaText, "Estimated study time:") Then ActivityTimeStr = ParaText ActivityTimeStr = Replace(ActivityTimeStr, "Estimated study time: ", "") ActivityTimeStr = Replace(ActivityTimeStr, " minutes", "") ActivityTime = ActivityTime + CInt(ActivityTimeStr) SectionActivities = SectionActivities + 1 End If Next If InStr(SectionText, "Section") = 1 Then OverallActivityTime = OverallActivityTime + OverallActivityTime Summary = Summary & vbCrLf & "SECTION SUMMARY" & vbCrLf _ & "Subsections: " & SubsectionCnt & vbCrLf _ & "Section Wordcount: " & SubsectionWordCnt & vbCrLf _ & "Section Activity Time: " & ActivityTime & vbCrLf _ & "Section Activity Count: " & SectionActivities & vbCrLf & vbCrLf SubsectionCnt = 0 SubsectionWordCnt = 0 ActivityTime = 0 SectionActivities = 0 End If Summary = Summary & "[Document Section " & S & "] " _ & SectionText _ & "Word count: " _ & ActiveDocument.Sections(S).Range.Words.Count _ & vbCrLf SubsectionCnt = SubsectionCnt + 1 SubsectionWordCnt = SubsectionWordCnt + ActiveDocument.Sections(S).Range.Words.Count Next Summary = Summary & vbCrLf & vbCrLf & "Overall document wordcount: " & _ ActiveDocument.Range.Words.Count Summary = Summary & vbCrLf & "Activity Time: " & ActivityTime & " minutes" MsgBox Summary Selection.Paragraphs(1).Range.InsertAfter vbCr & Summary & vbCrLf End Sub
PS I’ve no idea what idiomatic VB is supposed to look like; all the examples I saw seemed universally horrible… If you can give me any pointers to cleaning the above code up, feel free to add them in the comments…
PPS Thinks… I guess each section could also return a readability score? Does VB have a readability score function? VB code anywhere implementing readability scores?
One of the books I’m reading at the moment is Michael Hiltzik’s Dealers of Lightning: Xerox PARC and the Dawn of the Computer Age (my copy is second hand, ex-library stock…), birthplace to ethernet and the laser printer, as well as many of the computer user interactions we take for granted today. One thing I hadn’t fully appreciated was Xerox’s interests in publishing systems, which is in part what put it in mind for this post. The chapter I just finished reading tells of their invention of a modeless, WYSIWYG word processor, something that would be less hostile than the mode based editors of the time (I like the joke about accidentally entering command mode and typing edit – e: select entire document, d: delete selection, i:insert, t: the letter inserted. Oops – you just replaced your document with the letter t).
It must have been a tremendously exciting time there, having to invent the tools you wanted to use because they didn’t exist yet (some may say that’s still the case, but in a different way now, I think: we have many more building blocks at our disposal). But it’s still an exciting time, because while a lot of stuff has been invented, whether or not there is more to come, there are still ways of figuring out how to make it work easier, still ways of figuring out how to work the technology into our workflows in more sensible way, still many, many ways of trying to figure out how to use different bits of tech in combination with each other in order to get what feels like much more than we might reasonably expect from considering them as a set of separate parts, piled together.
One of the places this exploration could – should – take place is in education. Whilst at HE we often talk down tools in place of concepts, introducing new tools to students provides one way of exporting ideas embodied as tools into wider society. Tools like Jupyter notebooks, for example.
The more I use Jupyter notebooks, the more I see their potential as a powerful general purpose tool not just for reproducible research, but also as general purpose computational workbench and as a powerful authoring medium.
Enlightened publishers such as O’Reilly seem to have got on board with using interactive notebooks in a publishing context (for example, Embracing Jupyter Notebooks at O’Reilly) and colleges such as Bryn Mawr in the US keep coming up with all manner of interesting ways of using notebooks in a course context – if you know of other great (or even not so great) use case examples in publishing or education, please let me know via the comments to this post – but I still get the feeling that many other people don’t get it.
“Initially the reaction to the concept [of the Gypsy, GUI powered wordprocessor that was to become part of the Ginn publishing system] was ‘You’re going to have to drag me kicking and screaming,'” Mott recalled. “But everyone who sat in front of that system and used it, to a person, was a convert within an hour.”
Michael Hiltzik, Dealers of Lightning: Xerox PARC and the Dawn of the Computer Age, p210
For example, in writing computing related documents, the ability to show a line of code and the output of that code, automatically generated by executing the code, and then automatically inserted into the document, means that when writing code examples, “helpful corrections” by an over-zealous editor go out of the window. The human hand should go nowhere near the output text.
Similarly when creating charts from data, or plotting equations: the charts should be created from the data or the equation by running a script over a source dataset, or plotting an equation directly.
Again, the editor, or artist, should have no hand in “tweaking” the output to make it look better.
If the chart needs restyling, the artist needs to learn how to use a theme (like this?!) or theme generator rather then messing around with a graphics package (wrong sort of graphic). To add annotations, again, use code because it makes the graphic more maintainable.
There are also several toolkits around for creating other sorts of diagram from code, as I’ve written about previously, such as the tools provided on blockdiag.com:
Aside from making diagrams more easily maintainable, rendering them inline within a Jupyter notebook that also contains the programmatic “source code” for the diagram, written diagrams also provide a way in to the automatic generation of figure londesc text.
Electrical circuit schematics can also be written and embedded in a Jupyter notebook, as this Schemdraw example shows:
So far, I haven’t found an example of a schematic plotting library that also allows you to simulate the behaviour of the circuit from the same definition though (eg I can’t simulate(d, …) in the above example, though I could presumably parameterise a circuit definition for a simulation package and use the same parameter values to label a corresponding Schemdraw circuit).
There are some notations that are “executable”, though. For example, the sympy (symbolic Python) package lets you write texts using python variables that can be rendered either as a symbol using mathematical notation, or by their value.
(There’s a rendering bug in the generated Mathjax in the notebook I was using – I think this has been corrected in more recent versions.)
We can also use interactive widgets to help us identify and set parameter values to generate the sort of example we want:
Sympy also provides support for a wide range of calculations. For example, we can “write” a formula, render it using mathematical notation, and then evaluate it. A Jupyter notebook plugin (not shown) allows python statements to be included and executed inline, which means that expressions and calculations can be included – and evaluated – inline. Changing the parameters in an example is then easy to achieve, with the added benefit that the guaranteed correct result of automatically evaluating the modified expression can also be inlined.
(For interactive examples, see the notebooks in the sympy folder here; the notebooks are also runnable by launching a mybinder container – click on the launch:binder button to fire one up.)
It looks like there are also tools out there for converting from LateX math expressions to sympy equivalents.
As well as writing mathematical expressions than can be both expressed using mathematical notation, and evaluated as a mathematical expression, we can also write music, expressing a score in notational form or creating an admittedly beepy audio file corresponding to it.
(For an interactive example, run the midiMusic.ipynb notebook by clicking through on the launch:binder button from here.)
We can also generate audio files from formulae (I haven’t tried this in a sympy context yet, though) and then visualise them as data.
Packages such as librosa also seem to provide all sorts of tools for analysing an visualising audio files.
When we put together the Learn to Code MOOC for FutureLearn, which uses Jupyter notebooks as an interactive exercise environment for learners, we started writing the materials in (web pages for the FutureLearn teaching text, notebooks for the interactive exercises) in Jupyter notebooks. The notebooks can export as markdown, the FutureLearn publishing systems is based around content entered as a markdown, so we should have been able to publish direct from the notebooks to FutureLearn, right? Wrong. The workflow doesn’t support it: editor takes content in Microsoft Word, passes it back to authors for correction, then someone does something to turn it into markdown for FutureLearn. Or at least, that’s the OU’s publishing route (which has plenty of other quirks too…).
Or perhaps will be was the OU’s publishing route, because there’s a project on internally (the workshops around which I haven’t been able to make, unfortunately) to look at new authoring environments for producing OU content, though I’m not sure if this is intended to feed into the backend of the current route – Microsoft Word, Oxygen XML editor, OU-XML, HTML/PDF etc output – or envisages a different pathway to final output. I started to explore using Google docs as an OU XML exporter, but that raised little interest – it’ll be interesting to see what sort of authoring environment(s) the current project delivers.
(By the by, I remember being really excited about the OU-XML a publishing system route when it was being developed, not least because I could imagine its potential for feeding other use cases, some of which I started to explore a few years later; I was less enthused by its actual execution and the lack of imagination around putting it to work though… I also thought we might be able to use FutureLearn as a route to exploring how we might not just experiment with workflows and publishing systems, but also the tech – and business models around the same – for supporting stateful and stateless interactive, online student activities. Like hosting a mybinder style service, for example, or embedded interactions like the O’Reily Thebe demo, or even delivering a course as a set of linked Jupyter notebooks. You can probably guess how successful that’s been…)
So could Jupyter notebooks have a role to play in producing semi-automated content (automated, for example in the production of graphical objects and the embedding of automatically evaluated expressions)? Markdown support is already supported and it shouldn’t take someone too long (should it?!) to put together an nbformat exporter that could generate OU-XML (if that is still the route we’re going?)? It’d be interesting to hear how O’Reilly are getting on…
Erm… a Word document with some images and captions – styled as such:
Some basic IT knowledge – at least – it should be basic in what amounts to a publishing house:
The .docx file is just a zip file… That is, a compressed folder and its contents… So use the .zip…
So here’s the unzipped folder listing – can you spot the images?
The XML content of the doc – viewed in Firefox (drag and drop the file into a Firefox browser window). Does anything jump out at you?
Computers can navigate to the tags that contain the caption text by looking for the Caption style. It can be a faff associating the image captions with the images though (you need to keep tallies…) because the Word XML for the figure doesn’t seem to include the filename of the image… (I think you need to count your way through the images, then relate that image index number with the following caption block?)
So re: the email – if authors tag the captions and put captions immediately below an image – THE MACHINE CAN DO IT, if we give someone an hour or two to knock up the script and then probably months and months and months arguing about the workflow.
PS I’d originally screencaptured and directly pasted the images shown the above into a Powerpoint presentation:
I could have recaptured the screenshots, but it was much easier to save the Powerpoint file, change the .pptx suffix to .zip, unzip the folder, browse the unzipped Powerpoint media folder to see which image files I wanted:
and then just upload them directly to WordPress…
See also: Authoring Multiple Docs from a Single IPython Notebook for another process that could be automated but lack of imagination and understanding just blanks out.
For many years now, the OU has required students to have access to a computer in order to access online course materials and run course related software. A minimum specification computer is specified (2GB of RAM) and is supposedly platform neutral.
Putting together the headless TM351VM, which uses a virtual machine running on a host O/S, we needed to conform to this minimum spec; the VM we ended up with requires 1GB of RAM and takes up about 12-15GB of space (with gubbins), though it only needs at most about 8 GB of that.
In the previous post, I described how I recently got a Raspberry Pi Up and Running for the first time. And it got me thinking (again) about how we deliver software applications to students with the minimum of setup requirements.
1GB RAM…. 8-16 GB free space…
About the spec for a Raspberry Pi 3 with a cheap memory card?
So imagine this – students joining the university are given a Raspberry Pi 3 in a nicely branded box, along with an ethernet cable to attach it to their computer directly or to a wifi router; course software is designed to run as a service accessed via a browser, and to meet the Raspberry Pi 3 spec (which is on a par with what’s left over from a current min spec machine once its own O/S and background services have been taken into account).
The software for a particular course is issued on a course specific micro-SD card, supplied in a larger, OU and course branded SD card holder.
The micro-SD card contains a “course image” containing headless services that autorun on startup; the device is named with a suitably discoverable name – OU.local; a simple web server is found on the default http port and lists local URLs to locally running services on the PI and perhaps also links to the VLE and other online course resources. (This reminds me of the first browser based course materials I had a hand in in 1999 or so – an eSG – electronic study guide – that delivered locally installed HTML interactive content and linked applications, as well as links to online materials resources – for a mainly for print course (T396).)
The student plugs the course micro-SD card into the Pi, connects the pi to their computer or router via ethernet, switches the Pi on (i.e. plugs the power cable in) and goes to OU.local in their browser. Job done? [UPDATE: on a Mac, this is easy; in Windows… I’m not so sure? Bah…:-( Alternative is to plug pi into wifi router and then get student to try to find it’s IP address eg https://www.raspberrypi.org/documentation/remote-access/ip-address.md Or can a particular name alias (ou.local?) be requested from a wifi router (though that doesn’t feel very secure to me!)? Or we ship a tiny display such as the display-o-tron hat with Raspberry Pi that displays the IP address it’s allocated? That adds to the expense, but if it’s part of the packaging, that maybe offsets part of the case cost? UPDATE: or how about this – get the Raspberry Pi to speak it’s IP address.]
To improve robustness, the micro-SD card image could also run a process monitor to check necessary services were always running, and perhaps a control panel to allow students to monitor/start/stop/restart services if and as required.
To persist student created files, a named course USB stick plugged into the Pi and mounted at a known location would allow portability of files.
For each new course, with its own software, we just mail out a new micro-SD card with a course Pi image on it.
For the research student who possibly needs to run some slightly heavier weight applications that the Pi still has the computational oomph to run, we ship them cards that just run the application or application suites they need on starting up the Pi.
I know this idea has been mooted several times by various folk in the OU before (my recent tinkering was prompted by TM351 course colleagues Neil Smith and Alistair Willis that we could try a Pi as an alternative offering for TM351 students struggling to get the course software installed), but having had a bit of a play recently, it feels pretty tractable…
It’s looking as if the new level 1 courses won’t be making use of Jupyter notebooks (unless I can find a way of sneaking them in via the single unit I’be put together!;-) but I still think they’re worth spending time exploring for course material production as well as presentation.
So to this end, as I read through the materials being drafted by others for the course, I’ll be looking for opportunities to do the quickest of quick demos, whenever the opportunity arises, to flag things that might be worth exploring more in future.
So here’s a quick example. One of the nice design features of TM112, the second of the two new first level courses, is that it incorporates some mimi-project activities for students work on across the course. One of the project themes relates to music, so I wondered what doing something musical in a Jupyter notebook might look like.
The first thing I tried was taking the outlines of one of the activities – generating an audio file using python and MIDI – to see how the embedding might work in a notebook context, without the faff of having to generate an audio file from python and then find a means of playing it:
Yep – that seems to work… Poking around music related libraries, it seems we can also generate musical notation…
In fact, we can also generate musical notation from a MIDI file too…
(I assume the mappings are correct…)
So there may be opportunities there for creating simple audio files, along with the corresponding score, within the notebooks. Then any changes required to the audio file, as well as the score, can be effected in tandem.
I also had a quick go at generating audio files “from scratch” and then embedding the playable audio file
That seems to work too…
We can also plot the waveform:
This might be handy for a physics or electronics course?
As well as providing an environment for creating “media-ful” teaching resources, the code could also provide the basis of interactive student explorations. I don’t have a demo of any widget powered examples to hand in a musical context (maybe later!), but for now, if you do want to play with the notebooks that generated the above, you can do so on mybinder – http://mybinder.org/repo/psychemedia/ou-tm11n – in the midiMusic.ipynb and Audio.ipynb notebooks. The original notebooks are here: https://github.com/psychemedia/OU-TM11N
“Eating your own dogfood”, aka dogfooding, refers the practice of a company testing it’s own products by using them internally. At a research day held by Somerset College, a quote in a talk by Lorna Sheppard on Len Deighton’s cookbooks (yes, that Len Deighton…) from a 2014 Observer magazine article (Len Deighton’s Observer cookstrips, Michael Caine and the 1960s) caught my attention:
[G]enerally, you stand a better chance of succeeding in something if whatever you create, you also like to consume.
Implicit in this is the idea that you are also creating for a purpose.
In the OU engineering residential school currently running at the University of Bath, one of the four day long activities the students engage with is a robotics activity using Lego EV3 robots, where at each stage we try to build in a reason for adding another programming construct or learning how to work with a new sensor. That is, we try to motivate the learning by making it purposeful.
The day is structured around a series of challenges that allow students to develop familiarity with programming a Lego EV3 robot, adding sensors to it, logging data from the sensors and then interpreting the data. The activities are contextualised by comparing the work done on the Lego EV3’s with the behaviour of a Roomba robot vacuum cleaner – by the end of the morning, students will have programmed their robot to perform the majority of the Roomba’s control functions, including finding it’s way home to a homing beacon, as well as responding to touch (bumper), colour (line stopper) and proximity (infra-red and ultrasonic) sensors.
The day concludes with a challenge, where an autonomous robot must enter – and return from – a closed tunnel network, using sensors to collect data about the internal structure of the tunnel, as well identifying the location of a casualty who has an infra-red emergency beacon with them.
(The lids are placed on the tunnels so the students can’t see inside.)
As well as the partition walls (which are relocated each time the challenge is run, so I’m not giving anything away!), pipework and cables (aka coloured tape) also run through the tunnel and may be mapped by the students using a downward facing light sensor.
The casualty is actually a small wooden artist’s mannequin – the cuddly teddy we used to use does not respond well to the ultrasound sensor the students use to map the tunnel.
The data logged by the students include motor rotation data to track the robots progress, ultrasonic sensor data to map the walls, infra-red sensor data to find the emergency beacon and a light sensor to identify the cables/pipework.
The data collected looks something like this:
The challenge is then to map the (unseen by the students) tunnel network, and tell the robot’s story from the data.
The result is a narrative that describes the robot’s progress, and a map showing the internal structure of the tunnel:
If time allows, this can then be used as the basis for programming the robot to complete a rescue mission!
The strategies used by the students to log the data, and control the robot to send it into the tunnel and retrieve it safely again, are based on what they learned completing the earlier challenges set throughout the day.