Week 5 of Code in Place

It's the 2nd to last section!!! So bittersweet. For this week, we continued with using Canvas and introduced the idea of “animation.” So not what I would have done if I designed the course, but interesting.

This week’s section project goal was to write a program that draws a circle wherever the mouse is located on the screen, making “scribbles.”

In order to complete the section, students would need reviews of this week’s key concepts:

  • Graphics / Canvas

  • Animation loops

  • Mouse tracking

If you want to check it out at: bit.ly/cip-week4. It goes over our check in, a light review of the week’s key concepts and then we jump into coding!

Graphics / Canvas

Since we already did a review last week on Canvas, I did an even lighter review, just walking through the import statements and how “create_rectangle” is a “function” of canvas (the curriculum doesn’t go over classes, so no methods or objects are brought up). 

Animation loops

In lecture the idea of a “Animation loop” was introduced this week. They framed it as a “heartbeat.” So before the “heartbeat” any variables to set up the animation should be declared before the while loop and the while loop is the “heartbeat.” In the “heartbeat,” that is where one updating the “world:” where one should “draw” the next frame.

The idea of time.sleep() was presented as a way to “slow” the code down so people can “see” the animation; but it turns out that since code in place’s IDE is running the code in the browser’s main thread the browser freezes up due to a stack overflow, so by adding a pause into the program, it allows the browser to update.  

Mouse tracking

So Canvas provides a method to get the user’s mouse’s x and y coordinates. And students can use the “animation loop” to continuously update the x & y values of the mouse. There was an exercise that students should have already completed that would have had them use those methods, but I can’t assume that everyone has completed everything before section, so I simply introduced the idea, explained the code and showed them the gif beflow; noting that before the mouse is on the canvas the x, y coordinates are -1, -1. 

Coding

So the section’s goal was to write a program that “scribbles” circles as the user’s mouse goes over the canvas. I asked the student how we can “scope” the problem down or break the problem down to chunks. We started with just using the methods for the x,y coordinates and printing them out. Then made a circle using “hard coded” numbers to make sure that works. Then we combined the two and used the mouse’s x,y coordinates to create the circle.

A “strange” thing happened, where a circle was always created at the top left corner even before the mouse went over the canvas. So we explored and realized that before the mouse goes on the canvas the mouse’s coordinates are -1, -1. So students suggested using if statements and we explored how to chain conditions in an if statement. A student asked if changing and statements in an if statement was normal. I told them yes, but that I would create another function that returns a bool that contains the chain conditions so the main body of the code is more readable. Such a great question!

Check out a visualizer of what the code below does:  https://codeinplace.stanford.edu/cip3/share/ycK9nw5LcxwdNRm9GXkF 

from graphics import Canvas
import time


CANVAS_WIDTH = 300
CANVAS_HEIGHT = 300
CIRCLE_SIZE = 20
DELAY = 0.01
CIRCLE_COLOR = "purple"


def main():
    canvas = Canvas(CANVAS_WIDTH, CANVAS_HEIGHT)
    # your animation code here :) 

    while True: 
        # get mouse coordinates
        mouse_x = canvas.get_mouse_x()
        mouse_y = canvas.get_mouse_y()

        # check if the mouse is on the canvas
        if is_mouse_on_canvas(mouse_x, mouse_y):
            # create circle
            canvas.create_oval(mouse_x, mouse_y, (mouse_x + CIRCLE_SIZE), (mouse_y + CIRCLE_SIZE), CIRCLE_COLOR)
        
        # pause to allow browser to update 
        time.sleep(DELAY)


def is_mouse_on_canvas(mouse_x, mouse_y):
    """Returns a bool, True if the mouse is on the canvas"""
    if mouse_x > 0 and mouse_x < CANVAS_WIDTH and mouse_y > 0 and mouse_y < CANVAS_HEIGHT:
        return True
    else:
        return False


if __name__ == "__main__":
    main()

After we completed the goal for the section, another student asked how animations are stopped in “real life.” So we explored what would be the ideal conditions within this context. We came up with the idea that when a user’s mouse moves off the canvas it’s “done.” So I  suggested using a combination of a “flag” and break statement, which were two new concepts for students:

  • A flag in Python acts as a signal to the program to determine whether or not the program as a whole or a specific section of the program should run. In other words, you can set the flag to True and the program will run continuously until any type of event makes it False. Then the program, loop, or whatever you're using a flag for will stop. (video explaining flags)

  • Break statement - Break out of the loop by break keyword; this causes the process to move out of the loop and execute the next statement following the loop code. (source)

from graphics import Canvas
import time

CANVAS_WIDTH = 300
CANVAS_HEIGHT = 300
CIRCLE_SIZE = 20
DELAY = 0.01
CIRCLE_COLOR = "cyan"

def main():
    canvas = Canvas(CANVAS_WIDTH, CANVAS_HEIGHT)
    # my flag 
    started_drawing = False 
    
    while True: 
        # get mouse coordinates
        mouse_x = canvas.get_mouse_x()
        mouse_y = canvas.get_mouse_y()

        if is_mouse_on_canvas(mouse_x, mouse_y):

            started_drawing = True
        
            # create circle
            canvas.create_oval(mouse_x, mouse_y, (mouse_x + CIRCLE_SIZE), (mouse_y + CIRCLE_SIZE), CIRCLE_COLOR)
        
        time.sleep(DELAY)
        
        if started_drawing == True and mouse_x < 5:
            break
        
def is_mouse_on_canvas(mouse_x, mouse_y):
    """Returns a bool, True if the mouse is on the canvas"""
    if mouse_x > 0 and mouse_x < CANVAS_WIDTH and mouse_y > 0 and mouse_y < CANVAS_HEIGHT:
        return True
    else:
        return False


if __name__ == "__main__":
    main()

Thoughts

Students are getting more curious about what is possible – though due to the structure of the program, generally it’s men who are expressing this more. I don’t think that this type of course would have been very helpful for me when I started learning – it assumes that the students can and have the bandwidth to do independent learning, exploration. It also relies heavily on math which can scare people – I like math, but I remember feeling intimidated whenever math was used, even just creating functions that add or subtract (even though I’ve done statistics).  I feel strongly about this since this is an intro course, and so many times within the academic setting intro courses are designed to “weed” out folks – which for me is code for “we want a certain type of person, preferably someone with resources.” 

I still have 16 students, so no changes since last week. Students did ask me for suggestions on what to do next, which I’ll already started creating for them. It's a little bittersweet that next week will be our last section. 

Previous
Previous

Week 6 of Code in Place

Next
Next

Week 4 of Code in Place