to continue. (After that any entries made into the worksheet will be automatically saved, and you can re-load the partially-completed worksheet in future - at which point you will be asked to auto-save it again).
Preliminaries
Set the browser to Full Screen view, to give this worksheet, and your code, as much space as possible.
Select File > New to start a new program,
then select File > Auto Save and complete the dialog to ensure that your code is always saved.
Remember that you can use the Undo button (or Ctrl-z) to undo recent changes.
Remember that if the code editor has a tinted background it does not have focus and will not respond
to edits. To give it focus click within the editor. (If a program is running, you will need to stop it first.)
Use the auto-completion options as much as possible, because this reduces errors.
Use the Hints only when you need them - as all use of hints is recorded. Use of Help is encouraged and not recorded.
Use the Trim button periodically to remove leftover new code prompts.
Total hints used: /
Iteration 1: Draw a shape with 'turtle graphics'
Purpose of this worksheet
Our objective is to investigate the mathematical idea of a 'random walk'.
Imagine that you are standing in the centre of a circle with a radius of 10 paces.
But instead of walking straight to the edge, with each pace you make a random turn
- of up to to 90 degrees left or right. How many paces will it take to reach the edge?
If the turning is truly random then each attempt will take a different number: the picture below shows
three such paths taken:
Can we determine the average number of paces to reach the edge? Yes,
if we could perform the experiment many times.
And it turns out that being able to predict the average length of a different kinds of
random walk has significant applications in many different fields of study:
physics, biology, ecology, economics ..., even computer science. So we are going to build just such a simulation.
Make sure the code editor has focus i.e. has a white background.
From the new code options, press m to create an empty main routine.
Within the main routine add a let instruction, and edit its two fields to look like the following, making as much
use as possible of the options offered in the drop-down list (by cursoring down to the chosen item and pressing Enter)
because this reduces errors:
let tname be newTurtle()expression
This instruction creates a new 'Turtle' which we will be commanding to move around the Display holding a 'pen' that shows the path it has taken.
Turtle is a 'type' of thing and type names always begin with a capital letter
We have named this turtle t - picking a short name because we will be referring to it often and isn't likely
to be confused with anything else. We could have given it a longer name, and we will use longer names shortly. Names (also called 'identifiers') that we give
to things always begin with a lower-case letter. You'll also note that identifiers and types are shown in different colours in the editor.
The 'empty' brackets after Turtle are necessary, but don't worry about why they are needed just now
that will gradually become clearer. Note also that if you selected Turtle from the drop-down options you
will have seen a prompt (white characters) telling you that brackets were needed, like this:
let tname be expression()
at which point just pressing Tab will insert the prompted characters.
Whenever you see a question mark next to a field or instruction, clicking it will open the Help tab.
This may be useful when you start to write your own programs, but shouldn't be necessary in this worksheet.
Follow this by adding this call instruction:
call t.showprocedureName(arguments)
Noting that:
This instruction can be verbalised as 'call the show procedure on the turtle t'.
A procedure is a named piece of a code that makes a change to the system. This may also be referred to as a 'method' -
a procedure being a particular type of method.
This syntax - which takes the form of nameOfThing.methodName is known as a 'dotted method'. You'll be calling a
lot of dotted methods on the turtle t.
Methods are rendered in a different colour to identifiers and types.
Run the program, noting that:
the Display shows the turtle as a small green circle. When first created it is located in
the centre of the Display, with the 'x,y' coordinates of 0,0.
In turtle terms the Display measures 200 turtle units wide, and 150 turtle units deep.
The short black line on the turtle shows that it is currently heading North.
Having shown the turtle this program stops, so you can click on the code editor to give it focus
and resume editing the code.
Add three more instructions below the call:
call t.moveprocedureName(10arguments)call t.turnprocedureName(45arguments)call t.moveprocedureName(10arguments)
Here we again calling two different procedure methods on the turtle, their names suggesting what the turtle will do.
Both of these methods require you to specify a value (representing the distance to move, and the angle - in degrees - to turn, respectively)
which is placed within the brackets. That's what the brackets are for when using a method.
A value given to a method (within the brackets) is known as an 'argument' (the same term is used in Mathematics).
Later we will encounter methods that require more than one argument. Some methods - show for example -
don't require any arguments, but they still need the brackets.
then run the program again and make sure that you understand how the trail left by the turtle's pen corresponds to the three instructions that you added.
Delete the last call instruction by selecting the instruction and pressing Ctrl-Delete (or Ctrl-d.
In its place, add a for instruction and edit its fields to read this:
+for nvariableName from 1expression to 8expression step 1expressionnew code
A for instruction is a kind of 'loop' which will execute the instructions placed inside it a fixed number of times.
In this case it will execute them 8 times - counting from 1 to 8 inclusive.
We have to give a name to the 'counter' - in this case we have named it n.
Sometimes this counter will be used within the loop - if we need to know where we are in the counting. In this case, we are not going
to use it, though.
This looping activity is formally known in Computer Science as 'iteration'.
Move the two call instructions that move and turn the turtle inside the loop.
You may do this one at a time, or both together:
Select the instruction(s) to move
Press Ctrl-x to cut the instruction(s) to the clipboard
Select the new code prompt where you want to locate the cut instructions
Press Ctrl-v to paste the instructions
You should now have two call instructions inside the for loop, which will execute the pair of them 8 times.
Before you run the program, try to predict what you will see on the display. Then run the program.
Now modify the code to draw a 12-sided regular polygon.The loop will need to execute 12 times, and each turn will need to
be 1/12th of 360 degrees. You could work that one out for yourself,
but you can also just specify the turn instruction like this:
call t.turnprocedureName(360/12arguments)
In most places in code where a value can be specified, it is possible to specify an expression - such as 360/12,
or a far more complex expression - and that expression will be evaluated automatically and the result passed as the argument to the method.
Run the program and check that it draws what you expect.
Total hints used: /
Iteration 2 - Draw the circle with a radius of 10 paces
Returning to our problem we defined the specific random walk to be simulated as getting from the centre to the edge of a circle with a
radius of 10 paces. We now know how to draw a regular polygon and a circle may be described as a regular polygon with an infinite number of sides.
But since the display's resolution is not infinite we can get away with less than that! 360 sides, turning 1 degree each time should suffice.
Modify the for loop so that it executes 360 times.
Set the argument passed to the turn method to 1.
Now we need to calculate the length of the 'side' used for each of the 360 steps, we can use the following code, which reads very
like the way we would read out the calculation in mathematics:
let pacename be 5expressionlet radiusname be 10*paceexpressionlet sidename be 2*radius*pi/360expression
We need to calculate these values before we use them, so add these three new instructions at the top of the main.
Now change the argument passed into the move from 10 to side.
We'd also like get the circle centred on the display. To do this we need to start the turtle
by the circle's radius to the left of the centre, meaning that the x-coordinate will be -radius, still facing North.
The placeAt procedure method on the turtle
allows the turtle to be placed ar specific x,y coordinates without drawing a line from where it was before.
So above the for instruction, insert:call t.placeAtprocedureName(-radius, 0arguments)
noting that the placeAt requires two arguments, and these are separated by a comma)
Run the program and check that it draws a large circle that fits within the display. Note where the turtle finishes.
Total hints used: /
Iteration 3 - Draw a random walk
To simulate the random walk we need to repeatedly move the turtle one pace, and turn though a random angle of up to 90 degrees in
either direction (to turn to the left, just make the angle negative). The method random()
will generate a fractional number in the range 0 to 1, but there is also randomInt
('Int' being short for integer) that will generate a random whole number within a range specified by two integer arguments.
We could use another for for repetition, but the problem is that we don't know how many steps it will take
to get from the centre to the edge. What we need is a loop that executes as many times as is needed - until something decides
that it is time to stop. There are two such forms of loop: a while loop and a repeat loop, each
one optimised toward slightly different circumstances, but for this particular challenge they would work equally well,
so we'll just pick the first one.
After the last instruction within the main, add an instruction to place the turtle back in the centre of the circle.
Then add a while instruction, and notice that it has just one field
- to specify the condition for continuing:
+while conditionexpressionnew code
Within the while loop, add these two instructions:
call t.moveprocedureName(pacearguments)call t.turnprocedureName(randomInt(-90, 90)arguments)
Then run the program and observe the random walk. When it heads outside the visible display area press the Stop button.
What we want is for the random walk to continue only 'while' its distance from the centre is less than one radius.
If we know the x and y coordinates of the turtle at every point we could calculate the distance from the centre of the screen
using Pythagoras' theorem. The following tips will be useful:
We can read the current coordinates of the turtle by t.x and t.y
We can square a value using n^ - 'n raised to the power of 2'.
The method sqrt calculates the square root of its argument.
So, edit the condition field of the while loop to read:
sqrt(t.x^2 + t.y^2) < radius
Noting that:
Precedence for the arithmetic operators follows the same rules as in maths - which you might have learned as 'BIDMAS' or 'BODMAS'.
< is another operator which always evaluates to either true or false.
Run the program - more than once - checking that the random walk is different in each case, but halts when it reaches (or steps over)
the line of the circle.
Improve the program slightly with the following three 'tweaks', running the program between each one to check the changed output:
Just before the while loop add this instruction:
call t.penColourprocedureName(redarguments)
You should be able to predict how this will change the output.
Slow down the random walk a little to make the movement more visible. After the last instruction within the while loop
add the instruction:
call pauseprocedureName(100milliseconds)
which puts in a 100 millisecond pause - not very long but just enough to make the walk more obvious. Note that this instruction
does not say t.pause, because pause is not a procedure belonging
to a turtle - it is a 'freestanding' procedure, and can be used whether or not you are using turtle graphics.
Change the instruction that calls the show method on the turtle to calling its hide
method instead. You will find that it still produces the same set of marks, but no longer shows you the green turtle itself.
If you prefer to see the turtle, you can revert to show, and you may also adjust the argument
of the pause method to speed up, or slow down the movement.
Total hints used: /
Iteration 4 - simulate multiple walks
Our goal is to determine the average number of paces for a random walk to reach the edge of the circle.
So the next step is to perform multiple walks.
After the while loop add:
let numberOfWalksname be 3expression
then after that add a new for loop that counts from 1 to numberOfWalks. The counter may again be defined
as n because the loop that we used n in previously, has terminated by this point in the program.
.
Using Shift-↑ multi-select these three instructions:
call t.placeAtprocedureName(0, 0arguments)call t.penColourprocedureName(redarguments)+while sqrt(t.x^2 + t.y^2) < radiusconditioncall t.moveprocedureName(pacearguments)call t.turnprocedureName(randomInt(-90, 90)arguments)call pauseprocedureName(100milliseconds)end while
Then cut them and paste them inside the new for loop that you just created. Run the program and check that
it 'walks' from the centre to the edge three times.
Make the following tweaks:
Increase the number of attempts to 20.
Remove the instruction that pauses the program - as otherwise it will now run too slowly
Change the instruction that specifies the penColour changing red
to randomInt(black, white)
Before running the program, what do you think will happen to the colours of the walks? Run the program and see.
If you thought that randomInt(black, white) would result
in a random mix of black or white, or of many shades of grey, don't feel bad - both would seem quite logical! But why has it actually
produced a range of colours? The answer
is that each of the named (constant) colours (e.g. red) just holds an integer value in the range
0 (black) to 16,777,215 (white) - so it is possible to display 16+ million different colours. These are created from all the permutations of
mixing 256 shades of red, 256 shades of blue, and 256 shades of green.
This is known as the '24-bit RGB colour scheme' and is used throughout the web.
So our randomInt(black, white) has the same effect
as writing randomInt(0, 16777215)
.
Writing it as we did is easier to remember, and, arguably, makes the intention clearer.
Total hints used: /
Iteration 5 - Calculating the average number of paces
The first step to calculating the average is to count how many paces each walk takes. Immediately above
the while loop insert a new instruction:
variable pacesThisWalkname set to 0expression
What is the difference between writing this and using the let instruction that we have been doing thus far?
The answer is that a variable is intended to change in value - a let doesn't change.
We need pacesThisWalk to change because we will add 1 to it with each pace taken. So, now do that by adding
as the first instruction inside the while loop:
set pacesThisWalkvariableName to pacesThisWalk + 1expression
After the end while add, as a temporary check:
print pacesThisWalkexpression
and run the program. As each walk reaches the circle you should see the number of paces printed on the left-hand side of the display.
After this trial run, delete the print instruction
Now we need to calculate the total paces across all the attempts. So just above the start of the for loop
that executes the number of walks, define a new variable named totalPaces, also initially set to 0.
And inside the for loop, at the very end (after the end while) add:
set totalPacesvariableName to totalPaces + pacesThisWalkexpression
We need to calculate the average and present it on the display. This could be done with a single instruction
but using two instructions is a bit clearer. First calculate the average by adding these two instructions as final instructions in the main routine:
let averagename be totalPaces/numberOfWalksexpressionprint "Average: {average}"expression
Finally, for the small number of walks simulated it is inappropriate to quote the average number of paces to
so many decimal places. Edit the expression for calculating the average to the following, to round the result to just one decimal place:
(totalPaces/numberOfWalks).round(1)
Total hints used: /
Well done - you've now completed the worksheet.
If you have time left, try any of the following:
Simulate a larger number of walks e.g. 100. This will give a more accurate figure for the average number of paces.
Make the pace smaller but keep the circle's radius the same size as now.
The average number of paces to reach the edge will be larger. But does it increase in proportion? Try
three different values and plot the average against pace size.
Go back to the original values, but make a small change to the range of possible turn-angles between paces:
-60 to + 60 degrees, or -120 to + 120, say.
How does this change the average number of paces? Is the relationship linear?
Read more about the nature and application of Random Walks on Wikipedia.