< CS106A

Today: swap, int math, += shortcut, nested-loop image algorithms

PSA - What is "done" for a homework?

Thought For the Day: Image - Numbers - Code

Python Interpreter

Python Guide: Py Interpreter

Type code directly into Python at a >>> prompt, see what it produces. Very handy way to explore; we'll use this below to see how computer math works.

On parlante.org, use the hack mode interpreter page

>>> 23 + 6    # user types this
29            # see result

Math

For details, see Python Guide: Py Math

int and float

Math Operators: + - * /

>>> 2 + 3
5
>>> 2 + 3 * 4  # precedence
14

Division / → float

>>> 7 / 2
3.5
>>> 8 / 2
4.0

Int Division // → int

>>> 7 // 2
3
>>> 8 // 2
4

Relative Variable Change

Common "relative" pattern for a variable:

x = x + 1

Above increases the value of x by 1

e.g. Suppose x is 6. (1) First evaluate the right hand side, which comes to 7. (2) Then assign the 7 into x. This resolves the circularity with x appearing on both left and right by handling the right side first.

Relative Variable Shortcut: += *= //=

Shortcut operator to update a var: +=. The following is just a shorthand for x = x + 1

x += 1

Here's a shorthand for x = x * 2

x *= 2  # double x
>>> x = 10
>>> x += 3
>>> x
13
>>> x //= 2
>>> x
6

Image For Loop Structure

def red_channel(filename):
    image = SimpleImage(filename)
    for pixel in image:
        pixel.green = 0
        pixel.blue = 0
    return image
pixel var points to each pixel in turn

Image1 Code Demos

> Image1 Functions

Image2 Puzzles

> Image2 Puzzles

Swap

>>> x = 1
>>> y = 2
>>> x
1
>>> y
2
>>> temp = x
>>> x = y
>>> y = temp
>>> x
2
>>> y
1

After the above swap finishes:
after swap x is 2, y is 1, temp is 1


Image Coordinates

Load image into memory like this

image = SimpleImage(filename)
x,y grid of pixels for example image width=100 and height=50

for x in range(10):

# "list" is required here to display range
# as number series in brackets
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(5))
[0, 1, 2, 3, 4]
>>> list(range(1))       # just number 0
[0]
>>> list(range(0))       # no numbers!
[]
>>> for x in range(10):  # "foreach" works
...   print(x)
... 
0
1
2
3
4
5
6
7
8
9

Strategy Note: Detail Oriented

4 Image Range Problems

a. and b. are examples, c. is a key example, d. we may get to. > Image Range1

Previously we used foreach to access every pixel. Here we'll use nested-range loops - another form of iteration.

Understanding nested loops is step up in programming power.

a. Darker image-range Example

    image = SimpleImage(filename)
    for y in range(image.height):
        for x in range(image.width):
            pixel = image.get_pixel(x, y)

Note: How to Make 2 Pixels Look The Same?

b.red = a.red
b.green = a.green
b.blue = a.blue

b. mirror1

def mirror1(filename):
    """
    Code is provided - this is an example.
    Read the original image at the given filename.
    Create a new 'out' image twice as wide as the original.
    Copy the original image to the left half of out, leaving
    the right half blank (this is a halfway-point to the image2).
    """
    image = SimpleImage(filename)
    # SimpleImage.blank(width, height) - returns a new
    # image with size given in its 2 parameters.
    # Here, create out image with width * 2 or first image:
    out = SimpleImage.blank(image.width * 2, image.height)
    for y in range(image.height):
        for x in range(image.width):
            pixel = image.get_pixel(x, y)
            # left copy
            pixel_left = out.get_pixel(x, y)
            pixel_left.red = pixel.red
            pixel_left.green = pixel.green
            pixel_left.blue = pixel.blue
            # right copy
            # nothing!
    return out

c. mirror2

What is the dest x,y for each?
A: (0, 0)
B: (1, 0)
C: (2, 0)
D: (99, 0)
ABC Table Solution
A: (0, 0) dest: (199, 0)
B: (1, 0) dest: (198, 0)
C: (2, 0) dest: (197, 0)
D: (99, 0) dest: (100, 0)
Looking at above, work out that formula is
dest_x = out.width - 1 - x
alt: figure dest x,y for source points A B C

mirror2 Solution Code

def mirror2(filename):
    """
    Like mirror1, but also copy the original image
    to the right half of "out", but as a horizontally reversed
    mirror image. So the left half is a regular copy,
    and the right half is a mirror image.
    (Starter code does the left half).
    """
    image = SimpleImage(filename)
    out = SimpleImage.blank(image.width * 2, image.height)
    for y in range(image.height):
        for x in range(image.width):
            pixel = image.get_pixel(x, y)
            # left copy
            pixel_left = out.get_pixel(x, y)
            pixel_left.red = pixel.red
            pixel_left.green = pixel.green
            pixel_left.blue = pixel.blue
            # right copy
            # this is the key spot
            # have: pixel at x,y in image
            # want: pixel_right at ??? to write to
            pixel_right = out.get_pixel(out.width - 1 - x, y)
            pixel_right.red = pixel.red
            pixel_right.green = pixel.green
            pixel_right.blue = pixel.blue
    return out

Aside: Parameters

  bit.paint('blue')
-Now we have complicated examples, like this line:
  out.get_pixel(out.width - 1 - x, y)

d. shrink