PY-1.1-BP1-MQ40

Objective

Let's begin by reviewing our objective.

Our goal is to create a Python script that sets up the Turtle environment and draws a complete square with each side being 100 pixels long.

Check the Specification

Next, we'll run pytest to see the failing tests. This confirms the engineering specification we need to meet.

Run the tests using the command pytest in your terminal.

Test Results:

  • test_draw_square_behavior

Implement `main.py`

Now, let's build the solution by following the TODO comments in main.py. Each task corresponds to a TODO in the file.

Step by step checklist:

  1. Set up the drawing window (screen) for the turtle.
  2. Create a turtle object.
  3. Instruct your turtle object to draw a square with 100-unit sides and 90-degree turns.

The following documentation sections are going to be helpful:

  • Setting Up The Screen (Canvas)
  • Creating a Turtle
  • Basic Movement
  • Turning
  • Drawing Shapes
  • Programming Concepts

Validate Your Work

With the code in place, let's run the tests again to validate our work.

Run the tests using the command pytest in your terminal.

Test Results:

  • test_draw_square_behavior All tests passed!

Documentation

Python Turtle Graphics Documentation

This document provides a reference for common commands and concepts used in Python's turtle graphics library.

1. Getting Started

To use the turtle library, it must be imported.

import turtle

2. Setting Up The Screen (Canvas)

The screen is the window where the turtle draws. You need to get a reference to it.

  • turtle.Screen(): Creates or returns the singleton screen object.
screen = turtle.Screen()
  • screen.setup(width, height): Sets the size of the screen window in pixels.
screen.setup(width=600, height=400)
  • screen.bgcolor(color_name_or_code): Sets the background color of the screen.
screen.bgcolor("lightgray")
  • screen.exitonclick(): Keeps the window open until the user clicks on it.
  • turtle.done(): A common way to keep the window open until manually closed.
  • screen.mainloop(): Starts the event loop, also keeping the window open. Used in more complex programs.
# At the end of your script:
screen.exitonclick() 
# OR
# turtle.done()

3. Creating a Turtle

The turtle is the object that moves and draws on the screen.

  • turtle.Turtle(): Creates a new turtle object.
my_turtle = turtle.Turtle()

4. Basic Movement

These commands move the turtle forward or backward in its current direction, drawing a line if the pen is down.

  • my_turtle.forward(distance): Moves the turtle forward by distance pixels.
    • Alias: my_turtle.fd(distance)
  • my_turtle.backward(distance): Moves the turtle backward by distance pixels.
    • Alias: my_turtle.bk(distance)
my_turtle.forward(100) # Draws a line 100 pixels long
my_turtle.backward(50) # Moves back 50 pixels

[ASSET: GIF showing a turtle moving forward, then backward]

5. Turning

These commands change the turtle's direction without moving it. Angles are measured in degrees.

  • my_turtle.left(angle): Turns the turtle left by angle degrees.
    • Alias: my_turtle.lt(angle)
  • my_turtle.right(angle): Turns the turtle right by angle degrees.
    • Alias: my_turtle.rt(angle)
my_turtle.left(90)  # Turns 90 degrees counter-clockwise
my_turtle.right(45) # Turns 45 degrees clockwise

[ASSET: GIF showing a turtle turning left, then right]

6. Pen Control

Control whether the turtle draws when it moves. By default, the pen is down.

  • my_turtle.penup(): Lifts the pen. The turtle will move without drawing.
    • Aliases: my_turtle.pu(), my_turtle.up()
  • my_turtle.pendown(): Puts the pen down. The turtle will draw when it moves.
    • Aliases: my_turtle.pd(), my_turtle.down()
my_turtle.penup()      # Stop drawing
my_turtle.forward(50)  # Move without drawing
my_turtle.pendown()    # Start drawing again
my_turtle.forward(50)  # Draw a line

[ASSET: GIF showing turtle moving with pen up, then putting pen down and drawing a line] ../assets/gif-turtle-penup-pendown.gif

7. Appearance

Change the look of the turtle's drawing or the turtle itself.

  • my_turtle.pencolor(color_name_or_code): Sets the drawing color. Can use color names (e.g., "red", "blue") or hex color codes (e.g., "#FF0000").
my_turtle.pencolor("green")
my_turtle.forward(100) # Draws a green line
  • my_turtle.speed(speed_value): Sets the turtle's animation speed.
    • 0: Fastest (no animation)
    • 1: Slowest
    • 10: Fast
    • Values between 1 and 10 increase speed.
my_turtle.speed(1) # Slow speed for observation
my_turtle.speed(0) # Fastest speed

[ASSET: GIF showing turtle drawing at different speeds] ../assets/gif-turtle-drawing-at-different-speeds.gif

  • my_turtle.hideturtle(): Makes the turtle icon invisible.
    • Alias: my_turtle.ht()
  • my_turtle.showturtle(): Makes the turtle icon visible.
    • Alias: my_turtle.st()
my_turtle.hideturtle() # Hide the turtle after drawing

8. Positioning

Move the turtle directly to a specific point on the screen using coordinates. The center of the screen is (0, 0).

  • my_turtle.goto(x, y): Moves the turtle to the point with coordinates (x, y).
    • Aliases: my_turtle.setpos(x, y), my_turtle.setposition(x, y)
my_turtle.penup()    # Lift pen before moving
my_turtle.goto(50, 50) # Move to coordinate (50, 50)
my_turtle.pendown()  # Put pen down to draw from here
my_turtle.forward(50) # Draw a line from (50, 50)

ASSET: GIF showing turtle moving to a coordinate

9. Drawing Shapes

Shapes are drawn by combining movement and turning commands.

  • Squares: 4 equal sides, 4 x 90-degree turns.
side_length = 100
for _ in range(4):
    my_turtle.forward(side_length)
    my_turtle.left(90) # Or right(90)

[ASSET: Animation of a square being drawn] ../assets/gif-turtle-drawing-square.gif

  • Triangles (Equilateral): 3 equal sides, 3 x 120-degree turns (exterior angle).
side_length = 100
for _ in range(3):
    my_turtle.forward(side_length)
    my_turtle.left(120) # Or right(120)

[ASSET: Animation of an equilateral triangle being drawn] ../assets/gif-turtle-drawing-triangle.gif

  • Rectangles: 2 pairs of equal sides, 4 x 90-degree turns.
width = 100
height = 50
for _ in range(2):
    my_turtle.forward(width)
    my_turtle.left(90)
    my_turtle.forward(height)
    my_turtle.left(90)

[ASSET: Animation of a rectangle being drawn] ../assets/gif-turtle-drawing-rectangle.gif

  • Circles:

  • my_turtle.circle(radius): Draws a circle with the given radius. The turtle starts drawing from the bottom of the circle.

my_turtle.circle(50) # Draws a circle with radius 50

[ASSET: Animation of a circle being drawn] ../assets/gif-turtle-drawing-circle.gif

10. Programming Concepts

Using fundamental programming concepts makes turtle drawings more efficient and dynamic.

  • Using Variables: Store values like lengths, colors, or angles in variables to make code readable and easy to modify.
line_color = "purple"
line_length = 75
turn_angle = 90

my_turtle.pencolor(line_color)
my_turtle.forward(line_length)
my_turtle.left(turn_angle)
line_color = "purple" line_length = 150
  • Repeating Actions with Loops (for loop): Execute a block of code multiple times. Useful for drawing shapes with repeating patterns (like squares or triangles) or drawing multiple similar objects.
# Repeat an action 5 times
for i in range(5):
    # Code inside the loop runs 5 times
    my_turtle.forward(50)
    my_turtle.right(60)

# Iterate over items in a list
colors = ["red", "orange", "yellow", "green", "blue"]
for color in colors:
    my_turtle.pencolor(color)
    my_turtle.forward(20)

[ASSET: GIF showing a shape drawn with a loop] ../assets/gif-turtle-shape-with-loop.gif

  • Organizing Code with Helper Functions: Break down complex drawing tasks into smaller, reusable functions.
def draw_square(t, size):
    """Draws a square with given size using turtle t."""
    for _ in range(4):
        t.forward(size)
        t.left(90)

# Use the function
artist = turtle.Turtle()
draw_square(artist, 80) # Draw a square of size 80
def draw_square(t, size): ...

11. Keeping the Window Open

After your script finishes drawing, the Turtle window will close immediately unless you tell it to wait.

  • screen.exitonclick(): Waits for you to click on the screen before closing.
  • turtle.done(): Similar to exitonclick(), often used at the end of a script.
  • screen.mainloop(): Also keeps the window open; used in event-driven Turtle programs.
# At the end of your script:
screen = turtle.Screen() # Get the screen object if not already in scope
screen.exitonclick()
# OR
# turtle.done()