At My Fingertips
Rapid Playground
Did you just start the "Multiplicity" curriculum?
If yes, welcome!
If no, you may want to go to the "Multiplicity" curriculum and start it, and come to this activity from there. If you start this activity from within a curriculum, you will be nicely guided along a learning path.
In the activities of the "Multiplicity" curriculum you will learn about repetitive data and repetitive computation. This includes concepts like lists (repetitive data) and loops (repetitive computation). But this is not all! You also will learn about more modern concepts, such as Python's for comprehensions, and the ideas of mapping, filtering, and reducing repetitive data.
The activities in this "Multiplicity" curriculum assume that you already understand the basic Python programming concepts and the basic ideas behind the PyTamaro library. If you are not sure you do, we strongly recommend you first complete the "Welcome to PyTamaro" curriculum. After that, come back here to learn the superpower behind repetition.
This activity takes you on a whirlwind tour: you will learn how to write very little code that makes the computer do a lot of work. How? By writing some code and then telling Python to repeat that code many times. You write just one piece of code. But the program, when it runs, will execute that piece of code many times.
By the end of this activity you will have seen how to get the computer to repeat things, and along the way you will have explored a program that can produce this colorflul flower:
You probably saw that the flower is composed of a number of petals. 12 petals, to be exact.
When things repeat—like the petals in the above flower—a programmer always wonders about the similarities and the differences between the repeated parts.
Yes, all petals have the same shape (an ellipse), and they all have the same size. But they have different colors. And they are rotated by different angles.
So, we have identified the repeated part: the petal. Let's write a function to produce an individual petal!
def petal(....) -> Graphic:
...
The function should produce a Graphic and return it.
The differences we previously identified between all those petals can help us to think about possible parameters. We need to be able to create petals with different colors and with different rotation angles! So, do we need exactly these two parameters? Not necessarily!
In fact, the color and rotation angles are related.
Each angle corresponds to a specific color.
So it's enough to just provide angle
as a parameter,
and to let the petal
function produce the corresponding color.
PyTamaro provides various functions to create colors. Check out the documentation of the hsv_color function (hover over the name). It contains the same image of a hue-saturation-value cylinder you see above. If you go around the periphery of the cylinder, you get all the colors of the rainbow. The colors of the petals of our color flower correspond to twelve angles around this color cylinder (twelve "hues"): 0 is red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, and 300 is magenta. To be a bit fancy, we use a semi-transparent color (opacity around 0.5), so the leaves will be partially see-through, and we will be able to see the underlying leaves.
If we also want to allow flowers of different diameters,
then our petal
function also needs a parameter to specify the size
(we can then compute the width and height of the ellipse from the given size).
We like our petal so much that we want to put it in a frame and hang it on our wall. Here is a function that creates such a framed petal!
No, seriously, we write this function for another reason: Depending on the rotation angle the petal graphic has a different width and height. In the following sections we want to create animations with petal graphics, and for that we need all graphics to have the exact same sizes. Thus, we now write a function, framed_petal
that creates petals that it places in a frame that has the same width and height no matter how the petal's ellipse is rotated.
The last line in the code above creates one single value, the framed petal graphic, and it shows that single value by calling show_graphic
.
One reddish petal rotated by 15 degrees. Great... But where's the repetition!?!
Our flower consists of 12 petals.
We can produce them with 12 calls of our petal
function.
If we want, we can store the 12 petals (values of type Graphic
) in a list.
We can literally write a list by writing a [
to start the list,
then writing the 12 values, separated by commas,
and then writing a ]
to end the list.
The following code does that.
The code contains 12 calls to framed_petal
.
Each call produces a value of type Graphic
.
We package these 12 values in a list by surrounding them with square brackets.
And we bind that list to a name, manually_enumerated_petals
.
You should see a colorful animation. Let's focus on the code we wrote to create the list of 12 petals. This is a lot of "repetitive" code. Isn't there a way to get a list of petals without having to enumerate each and every one?
Couldn't we get the computer to do 12 things, without us having to write 12 things? Couldn't we just write one thing and have the computer repeat it 12 times?
Of course we can!
In Python you can repeat the contents of a list N
times by multiplying the list by N
.
Here, we create a list containing a single petal,
and we multiply it by 12,
so we get a list containing 12 petals.
How short and sweet is that!
But what's going on?? It just shows one red ellipse, and nothing seems to change!
If you run this code, you get 12 identical petals, all of them red, all of them rotated by 0 degrees.
If you animate the list of these 12 graphics, all identical, what you see in the animation doesn't really ever change. It looks like a single image.
We don't really want 12 identical petals!
We want 12 petals with different angles. The angles should be 0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, and 330 degrees. We don't need 360 degrees, because that's the same point on the circle as 0 degrees, and we already have 0 degrees.
Python has a beautiful way to create a sequence of regularly spaced numbers like this:
the range
function.
The above call to the range
function produces a range of integer numbers,
starting at 0,
ending just before 360,
and stepping by 30.
We then convert this range into a list and print it.
Great, we have a list of numbers. But we need a list of (framed) petals! Python provides a fantastic feature to map from a list of something (e.g., numbers) to a list of something else (e.g., graphics). This feature is called a for-comprehension.
This should output our original animation. But with much less code!
The for-comprehension goes over all values in the given list (angles
).
For each value (e.g., 0, 30, 60, ...), it assigns that value to the name angle
,
and then it calls framed_petal(100, angle)
.
This is 12 different calls to framed_petal
—framed_petal(100, 0)
, framed_petal(100, 30)
, framed_petal(100, 60)
, ..., framed_petal(100, 330)
—in one short expression!
You may already have heard of the term loop. Loops are probably the best known programming language concept to perform repetitive computations. Python's for-loops are similar to for-comprehensions; they can do more than you can do with a comprehension, but they require you to write a bit more code.
If you run this code, you get the same animation.
The first line of code creates an empty list (with []
).
Then next line specifies a loop that will go through all the elements of the angles list.
The loop will repeat the code written (and indented) in the subsequent line.
That code is called the body of the loop.
The loop will repeat the body for each angle.
Each time the body executes, it will call framed_petal
to create a framed petal with the desired angle,
and it will call append
,
to append the created petal graphic to the list.
Thus, with each iteration of the loop (each execution of the body),
the list known as petals_via_loop
will grow by one petal.
Once the loop has processed all 12 angles,
the list will contain 12 graphics.
Now that we have a way to produce the list of needed petals, we just need to compose the petals into a single graphic, our flower.
This kind of repetitive computation—taking a list of values and producing a single result—is called reduction. We can use a for-loop to reduce a list. We start with an empty graphic. In each iteration of the loop we combine the graphic we have (initially empty) with one petal.
The name flower_so_far
refers to the composite graphic we have so far.
Initially it refers to the empty graphic,
then to the graphic consisting of the composition of the first (red) petal
on top of the result so far (empty graphic),
then to the graphic consisting of the composition of the second (orange) petal on top of the result so far (red petal),
then to the graphic consisting of the composition of the third (yellow) petal on top of the result so far (orange on red),
and so on.
In the end, it will refer to the composition of all the petals.
Let's implement the flower
function so that it constructs a colorful flower with an arbitrary number of petals and a given radius.
Do you see the call to range(petal_count)
?
It has only one argument:
this call is equivalent to range(0, petal_count, 1)
.
If the range starts with 0 and the step between values is 1,
it is common to use this "shortcut" and to just provide a single argument.
Yes, the body of the flower
function contains two for-comprehensions:
to map from indices to angles,
and to map from angles to petals.
And it contains one for-loop:
to reduce the list of petals into a single graphic.
Are the colors for the three-petal flower somehow familiar? Have you heard of the RGB color model?
What about the colors for the six-petal flower? Have you heard of CMY?
You encountered many new concepts in this activity. Your head might be spinning like a rotating flower! Don't worry. The subsequent activities of the "Multiplicity" curriculum will explain the key concepts more thoroughly. And they will give you many opportunities to create your own lists and to implement your own repetitive computations, to create more and more elaborate graphics with very little code.
Repetition is how you get a benefit from programming. Without repetition, you would have to explicitly write every small step the program has to do. It would probably take you more time to write the steps down, than to perform them by hand! With repetition, you write some step once, and then you write some information about how many times the computer should repeat that step. And then you sit back and enjoy the computer doing all that repetitive work for you!
This activity has been created by LuCE Research Lab and is licensed under CC BY-SA 4.0.
Color Flower
PyTamaro is a project created by the Lugano Computing Education Research Lab at the Software Institute of USI
Privacy Policy • Platform Version c08406b (Wed, 20 Nov 2024 12:30:00 GMT)