High School Computation Day - PictureWorld Laboratory

Objective: To gain experience with functional programming in Python.

PictureWorld is an environment for composing geometric pictures from simple primitives. Here is a summary of the available functions, which will be explained in class:

empty       - the empty picture
patch(c)    - a rectangular patch of color c
tri(c)      - a triangle of color c

turn(p)     - rotate picture p 90 degrees clockwise
unturn(p)   - rotate picture p 90 degrees counterclockwise
turn180(p)  - rotate picture p 180 degrees

flipLR(p)   - mirror picture p about vertical axis (flip left/right)
flipTB(p)   - mirror picture p about horizontal axis (flip top/bottom)
flipDiag(p) - mirror picture p about diagonal axis

beside(p1, p2)  - arrange picture p1 to the left of picture p2
above(p1, p2)   - arrange picture p1 above picture p2
overlay(p1, p2) - arrange picture p1 on top of picture p2
Start by downloading and opening PictureWorld.zip. Right-click on this link and save it in your account folder ("guestXX" with the little house next to it). Then, use the finder to navigate to the folder "PictureWorld" within your account folder.

1. Warmup Exercises

As will be explained in class, add code to the file warmup.py to create the following picture:

Each of the four problems will create one quadrant of this picture.
  1. Define p1 using a blue patch and a red triangle
  2. Define p2 using a green patch and a yellow triangle. Try defining a variable to hold half of the picture.
  3. Define p3 using a magenta triangle. Try defining a function that returns four rotated copies of an arbitrary picture p.
  4. Define p4 using a cyan patch and a black triangle

2. A Quilt

The goal of this problem is to add code to the file quilt1.py to create the following quilt image:

Your only two building blocks are the familiar function patch(c) and a new function tris(c1, c2) defined in quilt1.py that returns two colored triangles. Here is an example of each:

patch(red)
    
tris(blue, green)

Divide, Conquer, and Glue

The key to solving this problem is to note that the picture can be decomposed into smaller pictures that are used more than once in the larger picture. For example, the upper right quadrant is a picture that we'll call yellowCorner:

The yellowCorner picture

The whole picture can be decomposed into four copies of yellowCorner that have different rotations. Once we figure out how to define the yellowCorner picture, we can combine four rotated copies of the picture to form the desired quilt picture. This is an excellent illustration of the important divide, conquer, and glue problem solving strategy:

  1. Divide the problem into subproblems. Here there is one subproblem: defining yellowCorner.
  2. Conquer the subproblems by solving them. In this case, the solution to the subproblem is a picture named yellowCorner.
  3. Glue the solutions to the subproblems together to form the solution to the whole problem. Here, we combine four rotated versions of yellowCorner to construct the quilt.

But how do we solve the problem of defining the yellowCorner picture? By applying the divide, conquer, and glue strategy again! In this case, yellowCorner naturally decomposes into two pictures:

yellowRedTris
     

redCorner

Here are the divide, conquer, and glue steps in this case:

  1. Divide the problem into subproblems. Here there are two subproblems: defining yellowRedTris and defining redCorner.
  2. Conquer the subproblems by solving them. In this case, the solutions to the subproblems are pictures named yellowRedTris and redCorner.
  3. Glue the solutions to the subproblems together to form the solution to the whole problem. Here, we combine three copies of redCorner with yellowRedTris to form yellowCorner.

We can continue to use divide, conquer, and glue to decompose the pictures into smaller and smaller pictures. When does the process stop? When we get to pictures so small that they are trivial to solve! In this case the trivial pictures are those generated by the patch(c) and tris(c1, c2) functions.

Auxiliary Functions

A general principle of computer science is "never write any piece of code more than once". If you find yourself writing the same or similar code more than once in your program, you should instead write functions that capture the patterns of the repeated code and use the functions instead. In class I will suggest some functions that will come in handy for this pattern


3. Another Quilt

In case there is still time (or if you want to work more on your own later on), here is another quilt challenge for you:

Add code to the file quilt2.py to create this image. Strive to make your code as clear and understandable as possible. You should study the quilt carefully to find repeated visual patterns that you can capture by writing auxiliary functions. It is a particularly good idea for some of your auxiliary functions to be parameterized over colors. For example, the four quadrants of the above quilt are rotated versions of the same visual pattern; the only difference between these patterns is their color scheme. This structure should be apparent in your code.

The only primitive pictures you should need are the empty picture and the picture generated by the tris(c1, c2) function. You can combine these via PictureWorld functions and auxiliary functions to construct the above picture.