8.6. Exercises

  1. Add a print statement to Newton’s sqrt function that prints out better each time it is calculated. Call your modified function with 25 as an argument and record the results.

    (ex_7_7)

    12
     
    1
    def newtonSqrt(n):
    2
        approx = 0.5 * n
    3
        better = 0.5 * (approx + n/approx)
    4
        while better != approx:
    5
            approx = better
    6
            better = 0.5 * (approx + n/approx)
    7
            print("Approx:", better)
    8
        return approx
    9
    10
    11
    print("Final approx:", newtonSqrt(25))
    12

    (miter_q1_answer)

    Show Comments
  1. Write a function print_triangular_numbers(n) that prints out the first n triangular numbers. A call to print_triangular_numbers(5) would produce the following output:

    1       1
    2       3
    3       6
    4       10
    5       15
    

    (hint: use a web search to find out what a triangular number is.)

    (ex_7_8)

  1. Write a function, is_prime, that takes a single integer argument and returns True when the argument is a prime number and False otherwise.

    (ex_7_9)

    11
     
    1
    def is_prime(n):
    2
        for i in range(2, n):
    3
            if n % i == 0:
    4
                return False
    5
        return True
    6
    7
    print(is_prime(25))
    8
    print(is_prime(7))
    9
    print(is_prime(251))
    10
    print(is_prime(20))
    11

    (miter_q3_answer)

    Show Comments
  1. Modify the walking turtle program so that rather than a 90 degree left or right turn the angle of the turn is determined randomly at each step.

    (ex_7_14)

  1. Modify the turtle walk program so that you have two turtles each with a random starting location. Keep the turtles moving until one of them leaves the screen.

    (ex_7_13)

    65
     
    1
    import random
    2
    import turtle
    3
    4
    def moveRandom(wn, t):
    5
        coin = random.randrange(0,2)
    6
        if coin == 0:
    7
            t.left(90)
    8
        else:
    9
            t.right(90)
    10
    11
        t.forward(50)
    12
    13
    def areColliding(t1, t2):
    14
        if t1.distance(t2) < 2:
    15
            return True
    16
        else:
    17
            return False
    18
    19
    def isInScreen(w, t):
    20
        leftBound = - w.window_width() / 2
    21
        rightBound = w.window_width() / 2
    22
        topBound = w.window_height() / 2
    23
        bottomBound = -w.window_height() / 2
    24
    25
        turtleX = t.xcor()
    26
        turtleY = t.ycor()
    27
    28
        stillIn = True
    29
        if turtleX > rightBound or turtleX < leftBound:
    30
            stillIn = False
    31
        if turtleY > topBound or turtleY < bottomBound:
    32
            stillIn = False
    33
        return stillIn
    34
    35
    t1 = turtle.Turtle()
    36
    t2 = turtle.Turtle()
    37
    wn = turtle.Screen()
    38
    39
    t1.shape('turtle')
    40
    t2.shape('circle')
    41
    42
    leftBound = -wn.window_width() / 2
    43
    rightBound = wn.window_width() / 2
    44
    topBound = wn.window_height() / 2
    45
    bottomBound = -wn.window_height() / 2
    46
    47
    t1.up()
    48
    t1.goto(random.randrange(leftBound, rightBound),
    49
            random.randrange(bottomBound, topBound))
    50
    t1.setheading(random.randrange(0, 360))
    51
    t1.down()
    52
    53
    t2.up()
    54
    t2.goto(random.randrange(leftBound, rightBound),
    55
            random.randrange(bottomBound, topBound))
    56
    t2.setheading(random.randrange(0, 360))
    57
    t2.down()
    58
    59
    60
    while isInScreen(wn, t1) and isInScreen(wn, t2):
    61
        moveRandom(wn, t1)
    62
        moveRandom(wn, t2)
    63
    64
    wn.exitonclick()
    65

    (miter_q5_answer)

    Show Comments
  1. Modify the previous turtle walk program so that the turtle turns around when it hits the wall or when one turtle collides with another turtle (when the positions of the two turtles are closer than some small number).

    (ex_7_12)

  1. Write a function to remove all the red from an image.

    For this and the following exercises, use the luther.jpg photo.

    (ex_7_15)

    21
     
    1
    import image
    2
    3
    img = image.Image("luther.jpg")
    4
    newimg = image.EmptyImage(img.getWidth(), img.getHeight())
    5
    win = image.ImageWin()
    6
    7
    for col in range(img.getWidth()):
    8
        for row in range(img.getHeight()):
    9
            p = img.getPixel(col, row)
    10
    11
            newred = 0
    12
            green = p.getGreen()
    13
            blue = p.getBlue()
    14
    15
            newpixel = image.Pixel(newred, green, blue)
    16
    17
            newimg.setPixel(col, row, newpixel)
    18
    19
    newimg.draw(win)
    20
    win.exitonclick()
    21

    (miter_q7_answer)

    Show Comments
  1. Write a function to convert the image to grayscale.

    (ex_7_16)

  1. Write a function to convert an image to black and white.

    (ex_7_17)

    41
     
    1
    import image
    2
    3
    def convertBlackWhite(input_image):
    4
        grayscale_image = image.EmptyImage(input_image.getWidth(), input_image.getHeight())
    5
    6
        for col in range(input_image.getWidth()):
    7
            for row in range(input_image.getHeight()):
    8
                p = input_image.getPixel(col, row)
    9
    10
                red = p.getRed()
    11
                green = p.getGreen()
    12
                blue = p.getBlue()
    13
    14
                avg = (red + green + blue) / 3.0
    15
    16
                newpixel = image.Pixel(avg, avg, avg)
    17
                grayscale_image.setPixel(col, row, newpixel)
    18
    19
        blackwhite_image = image.EmptyImage(input_image.getWidth(), input_image.getHeight())
    20
        for col in range(input_image.getWidth()):
    21
            for row in range(input_image.getHeight()):
    22
                p = grayscale_image.getPixel(col, row)
    23
                red = p.getRed()
    24
                if red > 140:
    25
                    val = 255
    26
                else:
    27
                    val = 0
    28
    29
                newpixel = image.Pixel(val, val, val)
    30
                blackwhite_image.setPixel(col, row, newpixel)
    31
        return blackwhite_image
    32
    33
    34
    win = image.ImageWin()
    35
    img = image.Image("luther.jpg")
    36
    37
    bw_img = convertBlackWhite(img)
    38
    bw_img.draw(win)
    39
    40
    win.exitonclick()
    41

    (miter_q9_answer)

    Show Comments
  1. Sepia Tone images are those brownish colored images that may remind you of times past. The formula for creating a sepia tone is as follows:

    newR = (R × 0.393 + G × 0.769 + B × 0.189)
    newG = (R × 0.349 + G × 0.686 + B × 0.168)
    newB = (R × 0.272 + G × 0.534 + B × 0.131)
    

    Write a function to convert an image to sepia tone. Hint: Remember that rgb values must be integers between 0 and 255.

    (ex_7_18)

  1. Write a function to uniformly enlarge an image by a factor of 2 (double the size).

    (ex_7_19)

    26
     
    1
    import image
    2
    3
    def double(oldimage):
    4
        oldw = oldimage.getWidth()
    5
        oldh = oldimage.getHeight()
    6
    7
        newim = image.EmptyImage(oldw * 2, oldh * 2)
    8
        for row in range(oldh):
    9
            for col in range(oldw):
    10
                oldpixel = oldimage.getPixel(col, row)
    11
    12
                newim.setPixel(2*col, 2*row, oldpixel)
    13
                newim.setPixel(2*col+1, 2*row, oldpixel)
    14
                newim.setPixel(2*col, 2*row+1, oldpixel)
    15
                newim.setPixel(2*col+1, 2*row+1, oldpixel)
    16
    17
        return newim
    18
    19
    img = image.Image("luther.jpg")
    20
    win = image.ImageWin(img.getWidth()*2, img.getHeight()*2)
    21
    22
    bigimg = double(img)
    23
    bigimg.draw(win)
    24
    25
    win.exitonclick()
    26

    (answer_7_11)

    Show Comments
  1. After you have scaled an image too much it looks blocky. One way of reducing the blockiness of the image is to replace each pixel with the average values of the pixels around it. This has the effect of smoothing out the changes in color. Write a function that takes an image as a parameter and smooths the image. Your function should return a new image that is the same as the old but smoothed.

    (ex_7_20)

  1. Write a general pixel mapper function that will take an image and a pixel mapping function as parameters. The pixel mapping function should perform a manipulation on a single pixel and return a new pixel.

    (ex_7_21)

    29
     
    1
    import image
    2
    3
    def pixelMapper(oldimage, rgbFunction):
    4
        width = oldimage.getWidth()
    5
        height = oldimage.getHeight()
    6
        newim = image.EmptyImage(width, height)
    7
    8
        for row in range(height):
    9
            for col in range(width):
    10
                originalpixel = oldimage.getPixel(col, row)
    11
                newpixel = rgbFunction(originalpixel)
    12
                newim.setPixel(col, row, newpixel)
    13
    14
        return newim
    15
    16
    def graypixel(oldpixel):
    17
        intensitysum = oldpixel.getRed() + oldpixel.getGreen() + oldpixel.getBlue()
    18
        aveRGB = intensitysum // 3
    19
        newPixel = image.Pixel(aveRGB, aveRGB, aveRGB)
    20
        return newPixel
    21
    22
    win = image.ImageWin()
    23
    img = image.Image("luther.jpg")
    24
    25
    newim = pixelMapper(img, graypixel)
    26
    newim.draw(win)
    27
    28
    win.exitonclick()
    29

    (miter_q13_answer)

    Show Comments
  1. When you scan in images using a scanner they may have lots of noise due to dust particles on the image itself or the scanner itself, or the images may even be damaged. One way of eliminating this noise is to replace each pixel by the median value of the pixels surrounding it.

    (ex_7_22)

  1. Research the Sobel edge detection algorithm and implement it.

    (ex_7_23)

    105
     
    1
    import image
    2
    import math
    3
    import sys
    4
    5
    # Code adapted from http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/image-processing/edge_detection.html
    6
    # Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
    7
    8
    # this algorithm takes some time for larger images - this increases the amount of time
    9
    # the program is allowed to run before it times out
    10
    sys.setExecutionLimit(20000)
    11
    12
    img = image.Image("luther.jpg")
    13
    newimg = image.EmptyImage(img.getWidth(), img.getHeight())
    14
    win = image.ImageWin()
    15
    16
    for x in range(1, img.getWidth()-1):  # ignore the edge pixels for simplicity (1 to width-1)
    17
        for y in range(1, img.getHeight()-1): # ignore edge pixels for simplicity (1 to height-1)
    18
    19
            # initialise Gx to 0 and Gy to 0 for every pixel
    20
            Gx = 0
    21
            Gy = 0
    22
    23
            # top left pixel
    24
            p = img.getPixel(x-1, y-1)
    25
            r = p.getRed()
    26
            g = p.getGreen()
    27
            b = p.getBlue()
    28
    29
            # intensity ranges from 0 to 765 (255 * 3)
    30
            intensity = r + g + b
    31
    32
            # accumulate the value into Gx, and Gy
    33
            Gx += -intensity
    34
            Gy += -intensity
    35
    36
            # remaining left column
    37
            p = img.getPixel(x-1, y)
    38
            r = p.getRed()
    39
            g = p.getGreen()
    40
            b = p.getBlue()
    41
    42
            Gx += -2 * (r + g + b)
    43
    44
            p = img.getPixel(x-1, y+1)
    45
            r = p.getRed()
    46
            g = p.getGreen()
    47
            b = p.getBlue()
    48
    49
            Gx += -(r + g + b)
    50
            Gy += (r + g + b)
    51
    52
            # middle pixels
    53
            p = img.getPixel(x, y-1)
    54
            r = p.getRed()
    55
            g = p.getGreen()
    56
            b = p.getBlue()
    57
    58
            Gy += -2 * (r + g + b)
    59
    60
            p = img.getPixel(x, y+1)
    61
            r = p.getRed()
    62
            g = p.getGreen()
    63
            b = p.getBlue()
    64
    65
            Gy += 2 * (r + g + b)
    66
    67
            # right column
    68
            p = img.getPixel(x+1, y-1)
    69
            r = p.getRed()
    70
            g = p.getGreen()
    71
            b = p.getBlue()
    72
    73
            Gx += (r + g + b)
    74
            Gy += -(r + g + b)
    75
    76
            p = img.getPixel(x+1, y)
    77
            r = p.getRed()
    78
            g = p.getGreen()
    79
            b = p.getBlue()
    80
    81
            Gx += 2 * (r + g + b)
    82
    83
            p = img.getPixel(x+1, y+1)
    84
            r = p.getRed()
    85
            g = p.getGreen()
    86
            b = p.getBlue()
    87
    88
            Gx += (r + g + b)
    89
            Gy += (r + g + b)
    90
    91
            # calculate the length of the gradient (Pythagorean theorem)
    92
            length = math.sqrt((Gx * Gx) + (Gy * Gy))
    93
    94
            # normalise the length of gradient to the range 0 to 255
    95
            length = length / 4328 * 255
    96
    97
            length = int(length)
    98
    99
            # draw the length in the edge image
    100
            newpixel = image.Pixel(length, length, length)
    101
            newimg.setPixel(x, y, newpixel)
    102
    103
    newimg.draw(win)
    104
    win.exitonclick()
    105

    (miter_q15_answer)

    Show Comments
Next Section - 9. Strings