Lab 2: Using functions to control shapes

The goals this week are to:

Good code organization saves you time and effort in the long run. It is essential whenever you collaborate with others and write any code professionally.


Tasks

L1. The setup

Create a Lab02 folder on your computer where you store CS151 projects and labs, hopefully somewhere that is backed up (e.g. in Dropbox, Google Drive, Microsoft One Drive, etc.)

Open VS Code. Create a new Python source code file calledlab2.py.

Open up a Terminal (e.g. Control+` in VS Code) and change the directory (cd) to the Lab02 folder.

L2. Good code organization

In lab2.py, write a function that draws a triangle. It should take in one parameter, side_length, which is the length (in pixels) of each of the sides. Important: Draw your triangle so that the turtle starts out at the lower-left corner. Remember, the turtle initially faces eastward.

Call your triangle function from main code (i.e. code that is not indented at the bottom of your file). Make sure that your code works (draws a triangle starting at the lower-left corner) by telling Python to run it using Terminal (i.e. python3 lab2.py).

Now look over your lab2.py file, including your triangle function, and make sure that it follows good code organization practice. It should have:

  1. Header comments (2 sets of triple quotes: '''Like this'''). Include filename, your name, course, semester, one line description of what the file does.
  2. Import statements (don't use from turtle import *, use the new way: import turtle)
  3. Function definitions are separated by two empty lines.
  4. Every function should have a docstring (''' style comment '''Like this''').
  5. At least one inline comment per function (# style).
  6. A comment indicating where 'main' code is going to appear (either style).
  7. Main code you want your program to execute.

Tip: You may want to speed up the turtle drawing by calling the speed function in main code. If you do, click the link and look at what the one integer parameter means and pick a value that works for you.

Reminders: Use the exitonclick turtle function call at the end of your file and use turtle.<function> to call any turtle function.*


L3. Moving the turtle anywhere

Let's make it possible to draw a triangle at any position on the canvas, not just starting at the middle (i.e. position (x, y) = (0, 0)).

L3a. Write a function called goto

Your goto function should take in two parameters: x and y. This will allow the turtle to go position x and y, no matter where it currently is on the canvas.

You can write this function in three steps:

  1. Call the turtle penup() function to make the turtle no longer "drag a virtual pen underneath it as it moves". In other words, moving the turtle won't result in drawing anything to the on-screen canvas (i.e. your canvas stays white as the turtle moves).
  2. Call the turtle goto(x, y) function to have the turtle jump to the new (x, y) coordinate given by the function parameter values.
  3. Call the turtle pendown() function so that the turtle will once again draw as it moves around.

Some more things to add to your function:

L3b. Test your goto function

In main code at the bottom of your file, call your goto function (move the turtle to a position of your choice), then have the turtle draw a triangle there. Repeat this a few times with different positions. You should end up with a canvas that looks something like this (your drawing will probably look different and that's ok!):

Remember: In main code, you want to call YOUR goto function, NOT the turtle's. So you should write commands like goto(140, 0) rather than turtle.goto(140, 0).

L3c. Why penup and pendown?

Before continuing, comment out both the penup and pendown commands in your goto function then run your program. What happens? Do you see why they are needed in goto?

Remember to uncomment them before continuing on to the next task!


L4. Positioning and scaling a simple shape

Let me know when you reach this point. We will discuss the strategy for drawing your shapes at any size (scale) and position.

L4a. Drawing a triangle at any position and scale

Write a new triangle2 function that has the following signature:

def triangle2(x, y, scale):

    '''Draws a triangle at any (`x`, `y`) position and scale (`scale`)

    By default, the side lengths are 100 (when `scale` = 1)

    '''

    # your code here

Your triangle2 function should "teleport" the turtle to the given location (x, y) position and draw a triangle with a side length equal to 100 pixels when the scale parameter is 1.

Guidelines:

L4b. Testing your triangle2 function

Comment out any existing function calls in main code that are not speed or exitonclick. Test triangle2 by calling it 3 times: with scale 1 (natural size), 2 (double natural size), and 3 (triple natural size).

Below is an example output. You do not need to make it look fancy; the important thing is that the triangles appear in different positions at the 3 sizes.


L5. Position and scale a compound shape

Video. Strategy for reusing shape functions (e.g. triangle2) to make a compound shape: a more complex shape made up of your simpler shapes arranged in different positions and/or scales.

L5a. Draw a hard-coded compound shape (triangleStack)

Let's assume that you have designed a shape (triangleStack) with hard-coded values that look good to you:

def triangleStack(x, y, scale):

    '''Draws three triangles on top of each other.

    Smaller triangles are placed on top of larger ones

    '''

    # Largest triangle

    triangle2(0, 0, 2)

    # Medium triangle in middle

    triangle2(50, 173.2, 1)

    # Small triangle on top of stack

    triangle2(75, 259.81, 0.5)

L5b. Convert hard-coded positions to offsets

We are going to convert the hard-coded compound shape (stack of three triangles) into a shape that we can move to any position and make any scale that we wish. We will do this in two stages.

First, convert the hard-coded positions to offsets. Make the lower-left corner of the first triangle (where the turtle starts out) "the origin" at (x, y) — i.e. has offset of (0, 0). Compute the offsets relative to (x, y).

When you're done, test it by commenting out existing main code and draw triangleStack at three positions: (x, y) = (-200, 0), (x, y) = (0, 0), and (x, y) = (200, 0). The scale parameter value does not matter right now. You should get this arrangement:

L5c. Scale the compound shape

The second and last step is to make the triangle stack resizable. Do this by multiplying the offsets and scales by scale.

When you're done, test it by modifying your existing main code:

You should get this arrangement:

Take a screenshot — this is Required Image 1 to be placed in your report.

Get started with project

Once you are done with each of the lab tasks, you may start on the project.