This task is part of project03 which is due at 23:00 EDT on 2023-09-26.
You have the option to work with a partner on this task if you wish. Working with a partner requires more work to coordinate schedules, but if you work together and make sure that you are both understanding the code you write, you will make progress faster and learn more.
You can download the starter code for this task using this link.
You can submit this task using this link.
Put all of your work for this task into the file
treeTops.py
(which is provided among the starter files)
For this problem set, you have a choice: you may complete this task OR
the highNotes task, but you do not need to complete both. treeTops (this
task) is graphics-oriented and works with turtle
graphics, while
highNotes is based on audio and
music instead, using the wavesynth
library.
This task will help you practice the material on custom functions and how to use several functions together to achieve a complicated result. It will also have you work with functions that have both side effects and return values.
In this task, your ultimate goal is to draw simulated twigs, branches, and ultimately trees, like these ones:
In addition to drawing the tree parts, your code will be able to calculate the highest point on each part, as marked by the dashed blue lines in the picture above.
You will accomplish this task by completing several subtasks. You should do these subtasks in order.
The size of a tree is determined by arguments to the tree
function:
The trunk, branch, and twig lengths, the trunk diameter, and the bark and
leaf colors. The following schematic shows the length of each part of a
tree, with the values for these arguments shown on the left. It also
shows the angles between different parts of the tree (which don't
change). The same distances and angles shown in this diagram are also
described below.
tree
, measured in degrees counterclockwise from due
East (which is the same way that setheading
works, and you must
use setheading
within tree
to set the
angle). Other angles are
all pre-determined, and they include:tree
. The branches and twigs each use a
pen size that's half of this trunk diameter. The leaves will be drawn
using the provided leaf
function, so you don't have to worry about
their diameters.tree
determine the lengths for the trunk, for the branches, and for
the twigs respectively. The length of each leaf is 1/2 the length of
the twig it's attached to.tree
.twig
First is the twig
function, which takes four
parameters: diameter, length, bark color, and
leaf color. It has to:
1. Draw a straight line using the specified pen size (i.e., diameter),
length, and bark color.
2. Draw two leaves at the end of this line,
at 20° left and right from the orientation of the line (using the
leaf
function).
3. Go back to where it started in terms
of both position and orientation, and make sure to leave the pen
down.
4. Return the height of the highest point on the twig
as its result value.
The first example shows how the twig
function should
work, including what it should draw, what it should print (due to
turtleBeads
) and what its result value should be. The provided
test_treeTops.py
file includes two tests for twig
. These tests and
the example below demonstrate that the 'top' of the tree doesn't account
for the pen width: the measured value is the highest point that the
turtle touches, regardless of how thick a line it draws. This is why the
blue lines in some demos are drawn below the top-most colored-in region.
Note that your printed output may appear in a different order from that
shown in the snippet if you draw things in a different order, but the
provided tests will accept any drawing order.
To figure out the highest point on the twig, you need to compute the
maximum out of three possibilities: the highest point on the first leaf,
the highest point on the second leaf, or the base of the twig (the point
in the middle of the twig cannot be the highest point, because one of the
other three points just mentioned would be higher). Because the leaf
function already returns the highest point between the two ends of the
leaf, your twig
function must use
max
to find the largest value
between these two results and the result of calling
ycor
.
ycor
is a turtle
function which returns
the Y-coordinate of the turtle's current position; you will need to make
sure that you call ycor
while the turtle is at the base of the twig.
branch
The branch
function draws a line and
then three twigs branching out from
that, and it needs to return the
y-coordinate of the highest point on the branch, just like twig
did. branch
has five parameters:
branch
must call twig
exactly three times, using the same diameter as it received and the
specified twig length, along with the bark and leaf colors. It must store
the results of these calls in variables, because it will need them to
compute the highest point using
ycor
to get the y-coordinate of
the base of the branch and using
max
to find the highest point
among that point and the top points returned by each twig.
As with twig
, branch
must put the turtle back where it
started when it is done.
This example shows what the branch
function should
draw, print, and return. We've provided one test in test_treeTops.py
that tests the branch function. As with twig, your parts may be drawn in
a different order, but this is fine as long as all of the correct pieces
get drawn (the provided test will accept any drawing order).
tree
Finally, you are ready to draw a tree. The tree
function has seven
parameters, which specify:
setheading
to point
the turtle in this direction before you start to draw the tree.The tree
function draws a line for the trunk, and then has four
branches in total, each of which is drawn
using the branch
function.
Unlike twig
and branch
, tree
does NOT have to put the turtle back
where it started when it is done, but like those functions, tree
must
return the y-coordinate of the highest point on the
tree. It must do this by using
max
to find the maximum among the
highest point returned by each branch, as well as the base of the tree
(measured using ycor
).
This tree
example shows what the tree should look like.
Note that:
noTrace
. If you do use
noTrace
, remember to use showPicture
.We have provided tests in test_treeTops.py
that use optimism
to check
both the results from your functions and parts of their printed output
(which serves to confirm what they draw, since optimism
can't check
turtle drawings directly). This testing code also draws dotted blue lines
based on the return values from your functions, if these are not in the
right places, then your returned top points may be wrong. The very first
image at the top of these instructions shows the correct
appearance for the turtle window if all tests are working correctly, but
you should also review the printed output in the Thonny shell to see if
it has any failure messages.
twig
,
branch
, and
tree
in order to confirm that
you're drawing the right thing.tree
must call
setheading
, neither
branch
nor
twig
should call
setheading
. These functions need to put the turtle back where it
started before they are done, even if they were called starting from
a position other than the default starting position, so setheading
would cause problems if they used it.Twig
This example shows what the twig function should draw, print, and return. It also includes some code to draw a blue line that illustrates the result value. As long as your result value is the same as the value shown here to within about 3 decimal places, that's good enough. Note that when the function is finished, the turtle is positioned back at the base of the twig, in the same place (and oriented in the same direction) that it started in. This is true for the following examples as well.
In []:Prints# Draw the twig: top = twig(10, 100, 'Sienna', 'SpringGreen2') # Show the turtle's position (it's back at the start) color('black') stamp() # Print a message and draw a line showing how high the top is print("The highest point is at y=" + str(round(top, 3))) teleport(-400, top) setheading(0) color('blue') pensize(0.5) fd(800) hideturtle()
A 10-pensize Sienna horizontal line from (0, 0) to (100, 0). A 25-pensize SpringGreen2 20° line from (100, 0) to (147, 17). A 25-pensize SpringGreen2 160° line from (100, 0) to (147, -17). The highest point is at y=17.101 A 0.5-pensize blue horizontal line from (-400, 17) to (400, 17).Image
Branch
This example shows what the branch function should draw, print, and return. As with the twig, it's okay if your result value differs by a small amount (e.g., less than .01). Note how the height of the top point is measured relative to the origin (y=0), rather than to the base of the branch (which is this case has a negative y coordinate).
In []:Prints# First, rotate a bit and back up lt(25) leap(-60) # Draw the branch: top = branch(12, 80, 50, 'Wheat4', 'DarkOliveGreen2') # Show the turtle's position (it's back at the start) color('black') stamp() # Print a message and draw a line showing how high the top is print("The highest point is at y=" + str(round(top, 3))) teleport(-400, top) setheading(0) color('blue') pensize(0.5) fd(800) hideturtle()
A 12-pensize Wheat4 25° line from (-54, -25) to (18, 8). A 12-pensize Wheat4 65° line from (18, 8) to (39, 54). A 12.5-pensize DarkOliveGreen2 85° line from (39, 54) to (41, 79). A 12.5-pensize DarkOliveGreen2 45° line from (39, 54) to (57, 71). A 12-pensize Wheat4 25° line from (18, 8) to (63, 30). A 12.5-pensize DarkOliveGreen2 45° line from (63, 30) to (81, 47). A 12.5-pensize DarkOliveGreen2 5° line from (63, 30) to (88, 32). A 12-pensize Wheat4 165° line from (18, 8) to (66, -4). A 12.5-pensize DarkOliveGreen2 5° line from (66, -4) to (91, -2). A 12.5-pensize DarkOliveGreen2 145° line from (66, -4) to (87, -19). The highest point is at y=78.673 A 0.5-pensize blue horizontal line from (-400, 79) to (400, 79).Image
Tree
This example shows what the tree function should draw, print, and return. Once again, your result value doesn't have to be perfectly exact, and the blue line illustrates the tree height. Notice that the turtle's final position (indicated by the black stamp) is NOT the same as its starting position.
In []:Prints# Setup teleport(0, -120) # Draw the tree top = tree(85, 18, 210, 140, 60, "Chocolate4", "Chartreuse2") # Show the turtle's position (it's back at the start) color('black') stamp() # Print a message and draw a line showing how high the top is print("The highest point is at y=" + str(round(top, 3))) teleport(-400, top) setheading(0) color('blue') pensize(0.5) fd(800) hideturtle()
A 18-pensize Chocolate4 85° line from (0, -120) to (18, 89). A 9-pensize Chocolate4 25° line from (18, 89) to (145, 148). A 9-pensize Chocolate4 65° line from (145, 148) to (171, 203). A 15-pensize Chartreuse2 85° line from (171, 203) to (173, 233). A 15-pensize Chartreuse2 45° line from (171, 203) to (192, 224). A 9-pensize Chocolate4 25° line from (145, 148) to (200, 174). A 15-pensize Chartreuse2 45° line from (200, 174) to (221, 195). A 15-pensize Chartreuse2 5° line from (200, 174) to (229, 176). A 9-pensize Chocolate4 165° line from (145, 148) to (203, 133). A 15-pensize Chartreuse2 5° line from (203, 133) to (233, 135). A 15-pensize Chartreuse2 145° line from (203, 133) to (228, 116). A 9-pensize Chocolate4 65° line from (18, 89) to (77, 216). A 9-pensize Chocolate4 105° line from (77, 216) to (62, 274). A 15-pensize Chartreuse2 125° line from (62, 274) to (45, 299). A 15-pensize Chartreuse2 85° line from (62, 274) to (65, 304). A 9-pensize Chocolate4 65° line from (77, 216) to (103, 270). A 15-pensize Chartreuse2 85° line from (103, 270) to (105, 300). A 15-pensize Chartreuse2 45° line from (103, 270) to (124, 292). A 9-pensize Chocolate4 25° line from (77, 216) to (132, 241). A 15-pensize Chartreuse2 45° line from (132, 241) to (153, 263). A 15-pensize Chartreuse2 5° line from (132, 241) to (162, 244). A 9-pensize Chocolate4 105° line from (18, 89) to (-18, 224). A 9-pensize Chocolate4 145° line from (-18, 224) to (-67, 259). A 15-pensize Chartreuse2 165° line from (-67, 259) to (-96, 267). A 15-pensize Chartreuse2 125° line from (-67, 259) to (-84, 283). A 9-pensize Chocolate4 105° line from (-18, 224) to (-33, 282). A 15-pensize Chartreuse2 125° line from (-33, 282) to (-51, 307). A 15-pensize Chartreuse2 85° line from (-33, 282) to (-31, 312). A 9-pensize Chocolate4 65° line from (-18, 224) to (7, 279). A 15-pensize Chartreuse2 85° line from (7, 279) to (10, 309). A 15-pensize Chartreuse2 45° line from (7, 279) to (29, 300). A 9-pensize Chocolate4 145° line from (18, 89) to (-96, 170). A 9-pensize Chocolate4 5° line from (-96, 170) to (-156, 164). A 15-pensize Chartreuse2 25° line from (-156, 164) to (-183, 152). A 15-pensize Chartreuse2 165° line from (-156, 164) to (-185, 172). A 9-pensize Chocolate4 145° line from (-96, 170) to (-146, 204). A 15-pensize Chartreuse2 165° line from (-146, 204) to (-175, 212). A 15-pensize Chartreuse2 125° line from (-146, 204) to (-163, 228). A 9-pensize Chocolate4 105° line from (-96, 170) to (-112, 227). A 15-pensize Chartreuse2 125° line from (-112, 227) to (-129, 252). A 15-pensize Chartreuse2 85° line from (-112, 227) to (-109, 257). The highest point is at y=312.272 A 0.5-pensize blue horizontal line from (-400, 312) to (400, 312).Image
=
or by defining a parameter for a function) you must also later use that variable as part of another expression. If you need to create a variable that you won't use, it must have the name _
, but you should only do this if absolutely necessary.twig
must return the correct result
twig
function is run must match the solution result.branch
must return the correct result
branch
function is run must match the solution result.tree
must return the correct result
tree
function is run must match the solution result.twig
net turtle movement
twig
net turtle movement
branch
net turtle movement
branch
net turtle movement
twig
draws leaves correctly.
leaf
made during a call to twig
, along with the argument given to leaf
. Regardless of order, these must match the correct positions and arguments.twig
draws leaves correctly.
leaf
made during a call to twig
, along with the argument given to leaf
. Regardless of order, these must match the correct positions and arguments. These checks will move the turtle from the default starting position before twig
is called.branch
draws leaves correctly.
leaf
made during a call to branch
, along with the argument given to leaf
. Regardless of order, these must match the correct positions and arguments.branch
draws leaves correctly.
leaf
made during a call to branch
, along with the argument given to leaf
. Regardless of order, these must match the correct positions and arguments. These checks will move the turtle from the default starting position before branch
is called.tree
draws leaves correctly.
leaf
made during a call to tree
, along with the argument given to leaf
. Regardless of order, these must match the correct positions and arguments.tree
draws leaves correctly.
leaf
made during a call to tree
, along with the argument given to leaf
. Regardless of order, these must match the correct positions and arguments. These checks will move the turtle from the default starting position before tree
is called.twig
with 4 parameters
def
to define twig
with 4 parametersycor
twig
with 4 parameters, call ycor
in at least one place.max
twig
with 4 parameters, call max
in at least one place.leaf
twig
with 4 parameters, call leaf
in exactly 2 places.twig
with 4 parameters
def
to define twig
with 4 parameterssetheading
twig
with 4 parameters, do not call setheading
, seth
, or setHeading
.branch
with 5 parameters
def
to define branch
with 5 parametersycor
branch
with 5 parameters, call ycor
in at least one place.max
branch
with 5 parameters, call max
in at least one place.twig
branch
with 5 parameters, call twig
in exactly 3 places.branch
with 5 parameters
def
to define branch
with 5 parameterssetheading
branch
with 5 parameters, do not call setheading
, seth
, or setHeading
.tree
def
to define tree
ycor
tree
, call ycor
in at least one place.max
tree
, call max
in at least one place.setheading
tree
, call setheading
, seth
, or setHeading
in at least one place.branch
tree
, call branch
in exactly 4 places.