8.6. Exercises¶
-
Add a print statement to Newton’s
sqrt
function that prints outbetter
each time it is calculated. Call your modified function with 25 as an argument and record the results.(ex_7_7)
121def newtonSqrt(n):
2approx = 0.5 * n
3better = 0.5 * (approx + n/approx)
4while better != approx:
5approx = better
6better = 0.5 * (approx + n/approx)
7print("Approx:", better)
8return approx
9
10
11print("Final approx:", newtonSqrt(25))
12
(miter_q1_answer)
-
Write a function
print_triangular_numbers(n)
that prints out the first n triangular numbers. A call toprint_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)
-
Write a function,
is_prime
, that takes a single integer argument and returnsTrue
when the argument is a prime number andFalse
otherwise.(ex_7_9)
111def is_prime(n):
2for i in range(2, n):
3if n % i == 0:
4return False
5return True
6
7print(is_prime(25))
8print(is_prime(7))
9print(is_prime(251))
10print(is_prime(20))
11
(miter_q3_answer)
-
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)
-
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)
651import random
2import turtle
3
4def moveRandom(wn, t):
5coin = random.randrange(0,2)
6if coin == 0:
7t.left(90)
8else:
9t.right(90)
10
11t.forward(50)
12
13def areColliding(t1, t2):
14if t1.distance(t2) < 2:
15return True
16else:
17return False
18
19def isInScreen(w, t):
20leftBound = - w.window_width() / 2
21rightBound = w.window_width() / 2
22topBound = w.window_height() / 2
23bottomBound = -w.window_height() / 2
24
25turtleX = t.xcor()
26turtleY = t.ycor()
27
28stillIn = True
29if turtleX > rightBound or turtleX < leftBound:
30stillIn = False
31if turtleY > topBound or turtleY < bottomBound:
32stillIn = False
33return stillIn
34
35t1 = turtle.Turtle()
36t2 = turtle.Turtle()
37wn = turtle.Screen()
38
39t1.shape('turtle')
40t2.shape('circle')
41
42leftBound = -wn.window_width() / 2
43rightBound = wn.window_width() / 2
44topBound = wn.window_height() / 2
45bottomBound = -wn.window_height() / 2
46
47t1.up()
48t1.goto(random.randrange(leftBound, rightBound),
49random.randrange(bottomBound, topBound))
50t1.setheading(random.randrange(0, 360))
51t1.down()
52
53t2.up()
54t2.goto(random.randrange(leftBound, rightBound),
55random.randrange(bottomBound, topBound))
56t2.setheading(random.randrange(0, 360))
57t2.down()
58
59
60while isInScreen(wn, t1) and isInScreen(wn, t2):
61moveRandom(wn, t1)
62moveRandom(wn, t2)
63
64wn.exitonclick()
65
(miter_q5_answer)
-
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)
-
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)
211import image
2
3img = image.Image("luther.jpg")
4newimg = image.EmptyImage(img.getWidth(), img.getHeight())
5win = image.ImageWin()
6
7for col in range(img.getWidth()):
8for row in range(img.getHeight()):
9p = img.getPixel(col, row)
10
11newred = 0
12green = p.getGreen()
13blue = p.getBlue()
14
15newpixel = image.Pixel(newred, green, blue)
16
17newimg.setPixel(col, row, newpixel)
18
19newimg.draw(win)
20win.exitonclick()
21
(miter_q7_answer)
-
Write a function to convert the image to grayscale.
(ex_7_16)
-
Write a function to convert an image to black and white.
(ex_7_17)
411import image
2
3def convertBlackWhite(input_image):
4grayscale_image = image.EmptyImage(input_image.getWidth(), input_image.getHeight())
5
6for col in range(input_image.getWidth()):
7for row in range(input_image.getHeight()):
8p = input_image.getPixel(col, row)
9
10red = p.getRed()
11green = p.getGreen()
12blue = p.getBlue()
13
14avg = (red + green + blue) / 3.0
15
16newpixel = image.Pixel(avg, avg, avg)
17grayscale_image.setPixel(col, row, newpixel)
18
19blackwhite_image = image.EmptyImage(input_image.getWidth(), input_image.getHeight())
20for col in range(input_image.getWidth()):
21for row in range(input_image.getHeight()):
22p = grayscale_image.getPixel(col, row)
23red = p.getRed()
24if red > 140:
25val = 255
26else:
27val = 0
28
29newpixel = image.Pixel(val, val, val)
30blackwhite_image.setPixel(col, row, newpixel)
31return blackwhite_image
32
33
34win = image.ImageWin()
35img = image.Image("luther.jpg")
36
37bw_img = convertBlackWhite(img)
38bw_img.draw(win)
39
40win.exitonclick()
41
(miter_q9_answer)
-
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)
-
Write a function to uniformly enlarge an image by a factor of 2 (double the size).
(ex_7_19)
261import image
2
3def double(oldimage):
4oldw = oldimage.getWidth()
5oldh = oldimage.getHeight()
6
7newim = image.EmptyImage(oldw * 2, oldh * 2)
8for row in range(oldh):
9for col in range(oldw):
10oldpixel = oldimage.getPixel(col, row)
11
12newim.setPixel(2*col, 2*row, oldpixel)
13newim.setPixel(2*col+1, 2*row, oldpixel)
14newim.setPixel(2*col, 2*row+1, oldpixel)
15newim.setPixel(2*col+1, 2*row+1, oldpixel)
16
17return newim
18
19img = image.Image("luther.jpg")
20win = image.ImageWin(img.getWidth()*2, img.getHeight()*2)
21
22bigimg = double(img)
23bigimg.draw(win)
24
25win.exitonclick()
26
(answer_7_11)
-
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)
-
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)
291import image
2
3def pixelMapper(oldimage, rgbFunction):
4width = oldimage.getWidth()
5height = oldimage.getHeight()
6newim = image.EmptyImage(width, height)
7
8for row in range(height):
9for col in range(width):
10originalpixel = oldimage.getPixel(col, row)
11newpixel = rgbFunction(originalpixel)
12newim.setPixel(col, row, newpixel)
13
14return newim
15
16def graypixel(oldpixel):
17intensitysum = oldpixel.getRed() + oldpixel.getGreen() + oldpixel.getBlue()
18aveRGB = intensitysum // 3
19newPixel = image.Pixel(aveRGB, aveRGB, aveRGB)
20return newPixel
21
22win = image.ImageWin()
23img = image.Image("luther.jpg")
24
25newim = pixelMapper(img, graypixel)
26newim.draw(win)
27
28win.exitonclick()
29
(miter_q13_answer)
-
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)
-
Research the Sobel edge detection algorithm and implement it.
(ex_7_23)
1051import image
2import math
3import 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
10sys.setExecutionLimit(20000)
11
12img = image.Image("luther.jpg")
13newimg = image.EmptyImage(img.getWidth(), img.getHeight())
14win = image.ImageWin()
15
16for x in range(1, img.getWidth()-1): # ignore the edge pixels for simplicity (1 to width-1)
17for 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
20Gx = 0
21Gy = 0
22
23# top left pixel
24p = img.getPixel(x-1, y-1)
25r = p.getRed()
26g = p.getGreen()
27b = p.getBlue()
28
29# intensity ranges from 0 to 765 (255 * 3)
30intensity = r + g + b
31
32# accumulate the value into Gx, and Gy
33Gx += -intensity
34Gy += -intensity
35
36# remaining left column
37p = img.getPixel(x-1, y)
38r = p.getRed()
39g = p.getGreen()
40b = p.getBlue()
41
42Gx += -2 * (r + g + b)
43
44p = img.getPixel(x-1, y+1)
45r = p.getRed()
46g = p.getGreen()
47b = p.getBlue()
48
49Gx += -(r + g + b)
50Gy += (r + g + b)
51
52# middle pixels
53p = img.getPixel(x, y-1)
54r = p.getRed()
55g = p.getGreen()
56b = p.getBlue()
57
58Gy += -2 * (r + g + b)
59
60p = img.getPixel(x, y+1)
61r = p.getRed()
62g = p.getGreen()
63b = p.getBlue()
64
65Gy += 2 * (r + g + b)
66
67# right column
68p = img.getPixel(x+1, y-1)
69r = p.getRed()
70g = p.getGreen()
71b = p.getBlue()
72
73Gx += (r + g + b)
74Gy += -(r + g + b)
75
76p = img.getPixel(x+1, y)
77r = p.getRed()
78g = p.getGreen()
79b = p.getBlue()
80
81Gx += 2 * (r + g + b)
82
83p = img.getPixel(x+1, y+1)
84r = p.getRed()
85g = p.getGreen()
86b = p.getBlue()
87
88Gx += (r + g + b)
89Gy += (r + g + b)
90
91# calculate the length of the gradient (Pythagorean theorem)
92length = math.sqrt((Gx * Gx) + (Gy * Gy))
93
94# normalise the length of gradient to the range 0 to 255
95length = length / 4328 * 255
96
97length = int(length)
98
99# draw the length in the edge image
100newpixel = image.Pixel(length, length, length)
101newimg.setPixel(x, y, newpixel)
102
103newimg.draw(win)
104win.exitonclick()
105
(miter_q15_answer)