Stanford Python程式課 - 第三週
上週 (第二週) 的課程主要為Python入門,介紹Expressions運算式、Control flow流程控制等,從While/If、Booleans、For Loops等,建立完整的 Python 核心基礎。
課程第三週學習目標
- Lesson 7: Functions Revisited 複習Functions
- Lesson 8: Core Complete 完整核心
- Lesson 9: Images 影像處理
|
| Code in Place第三週課程 Lesson 7: Functions |
Lesson 7: Functions Revisited
學習重點
- 如何定義function
- 透過參數輸入資料
- 回傳資料
Functions are Like Toasters!
使用「烤麵包機」,不需要知道「烤麵包機」是怎麼製造的 = 使用「別人寫的Function」,不需要知道「別人寫的Function」是怎麼完成的
使用「烤麵包機」,需要知道「烤麵包機」只接受什麼樣的麵包 = 使用「別人寫的Function」,需要知道「別人寫的Function」只接受什麼樣的參數
使用「烤麵包機」,知道「烤麵包機」會回傳烤好的麵包 = 使用「別人寫的Function」,知道「別人寫的Function」會回傳什麼樣的資料
YouTube課程影片
Lecture 7-1: Recap and Show
Lecture 7-2: Toaster are Fns
Lecture 7-3: Anatomy of a Fn
Lecture 7-4: Many Examples
Lecture 7-5: Decomp Show
點我下載課程講義
延伸閱讀Python Reader
Lesson 8: Core Complete完整核心
本節課程是最完整的Python核心基礎,包含參數、流程控制、Function間資訊傳遞,以及很重要的Doctest!
下面Lecture example程式碼中的Factorial、Doctest都有Doctest使用的範例可以參考。
學習重點
- Trace control flow 追蹤控制流程
- Doctest 除錯驗證
- Practice practice practice 不斷練習
|
| Code in Place Lesson 8: Core Complete學習目標 |
YouTube課程影片
Lecture 8-1: Intro
Lecture 8-2: Sentiment
Lecture 8-3: Factorial
Lecture 8-4: Add_five
Lecture 8-5: Doctests
Lecture 8-6: Rock Paper Scissors
點我下載課程講義
延伸閱讀Python Reader
Lecture Examples
Sentiment Analysis程式
import nltk.sentiment
analyzer = nltk.sentiment.SentimentIntensityAnalyzer()
def main():
while True:
user_text = input('? ')
score = get_sentiment(user_text)
reaction = get_reaction(score)
print(reaction)
print(score)
print('')
def get_reaction(score):
"""
Parameter score: a float between -1 and +1
Return: An emoji as a string!
"""
if score > 0.5:
return "🥰"
if score > 0:
return "🙂"
if score == 0:
return "😶"
if score < -0.5:
return "😢"
if score < 0:
return "😟"
def get_sentiment(user_text):
"""
Parameter user_text: any text (string)
Return: a sentiment score between -1 and +1 (float)
"""
# 1. pass the text into the analyzer.polarity_scores function, part of the nltk package
scores = analyzer.polarity_scores(user_text)
# 2. extract the sentiment score. Scores is a "dictionary" (covered on May 17th)
sentiment_score = scores['compound']
return sentiment_score
if __name__ == '__main__':
main()
Factorial程式
# Constant – visible to all functions
MAX_NUM = 9
def main():
# repeat for several values!
for i in range(MAX_NUM+1):
print(i, factorial(i))
def factorial(n):
"""
Calculates n factorial.
5 factorial is 5 * 4 * 3 * 2 * 1
>>> factorial(6)
720
>>> factorial(5)
120
>>> factorial(4)
24
>>> factorial(3)
6
>>> factorial(1)
1
>>> factorial(0)
1
"""
answer = 1
for i in range(1,n+1):
answer *= i
return answer
if __name__ == '__main__':
main()
Doctest程式
"""
Example of Doctest
"""
def main():
year = int(input("Enter a year to check leap year: "))
if is_leap_year(year):
print("Year "+str(year)+" is a leap year")
else:
print("Year "+str(year)+" is NOT a leap year")
def is_divisible(a, b):
"""
>>> is_divisible(20, 4)
True
>>> is_divisible(12, 7)
False
>>> is_divisible(10, 10)
True
"""
return a % b == 0
def is_leap_year(year):
"""
Returns Boolean indicating if given year is a leap year.
It is a leap year if the year is:
* divisible by 4, but not divisible by 100
OR
* divisible by 400
Doctests:
>>> is_leap_year(2001)
False
>>> is_leap_year(2020)
True
>>> is_leap_year(2000)
True
>>> is_leap_year(1900)
False
"""
# if the year is divisible by 400, it is a leap year!
if is_divisible(year, 400):
return True
# other wise its a leap year if its divisible by 4 and not 100
return is_divisible(year, 4) and not is_divisible(year, 100)
if __name__ == '__main__':
main()
Lesson 9: Images
Instagram其實是創辦人在CS106課程中學習了程式處理影像,才激發了創辦Instagram的動機!
學習重點
- 了解影像如何在程式中呈現
- 學習SimpleImage Library
- 撰寫操控影像的程式
YouTube課程影片
Lecture 9-1: Intro
Lecture 9-2: SimpleImage
Lecture 9-3: Image Examples
Lecture 9-4: Greenscreen
Lecture 9-5: Mirror
Lecture 9-6: Wrap
Lecture 9-7: Responsibility
點我下載課程講義
延伸閱讀Python Reader
安裝Pillow、下載 simpleimage.py
提供 Stanford 的 simpleimage.py 程式,請自行選取複製後儲存成 simpleimage.py ,在Pycharm ((IDE) 中執行課程的範例需要
- 安裝Pillow library
- 將 simpleimage.py 檔案放在PyCharm (IDE) 的project目錄內
延伸閱讀:Stanford Code in Place線上Python入門課程 - Week 2
延伸閱讀:Stanford Code in Place線上Python入門課程 - Week 1
延伸閱讀:從Stanford學習免費、但值一萬美元的程式設計課
|
| Pillow安裝方式,資料來源:Code in Place Lesson 9 Lecture Slides |
simpleimage.py:
#!/usr/bin/env python3
"""
Stanford CS106AP SimpleImage
Written by Nick Parlante, Sonja Johnson-Yu, and Nick Bowman.
-7/2019 version, has file reading, pix, foreach, hidden get/setpix
SimpleImage Features:
Create image:
image = SimpleImage.blank(400, 200) # create new image of size
image = SimpleImage('foo.jpg') # create from file
Access size
image.width, image.height
Get pixel at x,y
pix = image.get_pixel(x, y)
# pix is RGB tuple like (100, 200, 0)
Set pixel at x,y
image.set_pixel(x, y, pix) # set data by tuple also
Get Pixel object at x,y
pixel = image.get_pixel(x, y)
pixel.red = 0
pixel.blue = 255
Show image on screen
image.show()
The main() function below demonstrates the above functions as a test.
"""
import sys
# If the following line fails, "Pillow" needs to be installed
from PIL import Image
def clamp(num):
"""
Return a "clamped" version of the given num,
converted to be an int limited to the range 0..255 for 1 byte.
"""
num = int(num)
if num < 0:
return 0
if num >= 256:
return 255
return num
class Pixel(object):
"""
A pixel at an x,y in a SimpleImage.
Supports set/get .red .green .blue
and get .x .y
"""
def __init__(self, image, x, y):
self.image = image
self._x = x
self._y = y
def __str__(self):
return 'r:' + str(self.red) + ' g:' + str(self.green) + ' b:' + str(self.blue)
# Pillow image stores each pixel color as a (red, green, blue) tuple.
# So the functions below have to unpack/repack the tuple to change anything.
@property
def red(self):
return self.image.px[self._x, self._y][0]
@red.setter
def red(self, value):
rgb = self.image.px[self._x, self._y]
self.image.px[self._x, self._y] = (clamp(value), rgb[1], rgb[2])
@property
def green(self):
return self.image.px[self._x, self._y][1]
@green.setter
def green(self, value):
rgb = self.image.px[self._x, self._y]
self.image.px[self._x, self._y] = (rgb[0], clamp(value), rgb[2])
@property
def blue(self):
return self.image.px[self._x, self._y][2]
@blue.setter
def blue(self, value):
rgb = self.image.px[self._x, self._y]
self.image.px[self._x, self._y] = (rgb[0], rgb[1], clamp(value))
@property
def x(self):
return self._x
@property
def y(self):
return self._y
# color tuples for background color names 'red' 'white' etc.
BACK_COLORS = {
'white': (255, 255, 255),
'black': (0, 0, 0),
'red': (255, 0, 0),
'green': (0, 255, 0),
'blue': (0, 0, 255),
}
class SimpleImage(object):
def __init__(self, filename, width=0, height=0, back_color=None):
"""
Create a new image. This case works: SimpleImage('foo.jpg')
To create a blank image use SimpleImage.blank(500, 300)
The other parameters here are for internal/experimental use.
"""
# Create pil_image either from file, or making blank
if filename:
self.pil_image = Image.open(filename).convert("RGB")
if self.pil_image.mode != 'RGB':
raise Exception('Image file is not RGB')
self._filename = filename # hold onto
else:
if not back_color:
back_color = 'white'
color_tuple = BACK_COLORS[back_color]
if width == 0 or height == 0:
raise Exception('Creating blank image requires width/height but got {} {}'
.format(width, height))
self.pil_image = Image.new('RGB', (width, height), color_tuple)
self.px = self.pil_image.load()
size = self.pil_image.size
self._width = size[0]
self._height = size[1]
self.curr_x = 0
self.curr_y = 0
def __iter__(self):
return self
def __next__(self):
if self.curr_x < self.width and self.curr_y < self.height:
x = self.curr_x
y = self.curr_y
self.increment_curr_counters()
return Pixel(self, x, y)
else:
self.curr_x = 0
self.curr_y = 0
raise StopIteration()
def increment_curr_counters(self):
self.curr_x += 1
if self.curr_x == self.width:
self.curr_x = 0
self.curr_y += 1
@classmethod
def blank(cls, width, height, back_color=None):
"""Create a new blank image of the given width and height, optional back_color."""
return SimpleImage('', width, height, back_color=back_color)
@classmethod
def file(cls, filename):
"""Create a new image based on a file, alternative to raw constructor."""
return SimpleImage(filename)
@property
def width(self):
"""Width of image in pixels."""
return self._width
@property
def height(self):
"""Height of image in pixels."""
return self._height
def get_pixel(self, x, y):
"""
Returns a Pixel at the given x,y, suitable for getting/setting
.red .green .blue values.
"""
if x < 0 or x >= self._width or y < 0 or y >= self.height:
e = Exception('get_pixel bad coordinate x %d y %d (vs. image width %d height %d)' %
(x, y, self._width, self.height))
raise e
return Pixel(self, x, y)
def set_pixel(self, x, y, pixel):
if x < 0 or x >= self._width or y < 0 or y >= self.height:
e = Exception('set_pixel bad coordinate x %d y %d (vs. image width %d height %d)' %
(x, y, self._width, self.height))
raise e
self.px[x, y] = (pixel.red, pixel.green, pixel.blue)
def set_rgb(self, x, y, red, green, blue):
"""
Set the pixel at the given x,y to have
the given red/green/blue values without
requiring a separate pixel object.
"""
self.px[x, y] = (red, green, blue)
def _get_pix_(self, x, y):
"""Get pix RGB tuple (200, 100, 50) for the given x,y."""
return self.px[x, y]
def _set_pix_(self, x, y, pix):
"""Set the given pix RGB tuple into the image at the given x,y."""
self.px[x, y] = pix
def show(self):
"""Displays the image using an external utility."""
self.pil_image.show()
def make_as_big_as(self, image):
"""Resizes image to the shape of the given image"""
self.pil_image = self.pil_image.resize((image.width, image.height))
self.px = self.pil_image.load()
size = self.pil_image.size
self._width = size[0]
self._height = size[1]
def main():
"""
main() exercises the features as a test.
1. With 1 arg like flowers.jpg - opens it
2. With 0 args, creates a yellow square with
a green stripe at the right edge.
"""
args = sys.argv[1:]
if len(args) == 1:
image = SimpleImage.file(args[0])
image.show()
return
# Create yellow rectangle, using foreach iterator
image = SimpleImage.blank(400, 200)
for pixel in image:
pixel.red = 255
pixel.green = 255
pixel.blue = 0
# for pixel in image:
# print(pixel)
# Set green stripe using pix access.
pix = image._get_pix_(0, 0)
green = (0, pix[1], 0)
for x in range(image.width - 10, image.width):
for y in range(image.height):
image._set_pix_(x, y, green)
image.show()
if __name__ == '__main__':
main()
Lecture Examples
Imageexampless.py
"""
This program contains several examples of functions that
manipulate an image to show how the SimpleImage library works.
"""
from simpleimage import SimpleImage
def darker(image):
"""
Makes image passed in darker by halving red, green, blue values.
Note: changes in image persist after function ends.
"""
# Demonstrate looping over all the pixels of an image,
# changing each pixel to be half its original intensity.
for pixel in image:
pixel.red = pixel.red // 2
pixel.green = pixel.green // 2
pixel.blue = pixel.blue // 2
def red_channel(filename):
"""
Reads image from file specified by filename.
Changes the image as follows:
For every pixel, set green and blue values to 0
yielding the red channel.
Return the changed image.
"""
image = SimpleImage(filename)
for pixel in image:
pixel.green = 0
pixel.blue = 0
return image
def compute_luminosity(red, green, blue):
"""
Calculates the luminosity of a pixel using NTSC formula
to weight red, green, and blue values appropriately.
"""
return (0.299 * red) + (0.587 * green) + (0.114 * blue)
def grayscale(filename):
"""
Reads image from file specified by filename.
Change the image to be grayscale using the NTSC
luminosity formula and return it.
"""
image = SimpleImage(filename)
for pixel in image:
luminosity = compute_luminosity(pixel.red, pixel.green, pixel.blue)
pixel.red = luminosity
pixel.green = luminosity
pixel.blue = luminosity
return image
def main():
"""
Run your desired image manipulation functions here.
You should store the return value (image) and then
call .show() to visualize the output of your program.
"""
flower = SimpleImage('flower.png')
flower.show()
darker(flower)
flower.show()
red_flower = red_channel('flower.png')
red_flower.show()
grayscale_flower = grayscale('flower.png')
grayscale_flower.show()
if __name__ == '__main__':
main()
greenscreen.py
"""
This program shows an example of "greenscreening" (actually
"redscreening" in this case). This is where we replace the
pixels of a certain color intensity in a particular channel
(here, we use red) with the pixels from another image.
"""
from simpleimage import SimpleImage
INTENSITY_THRESHOLD = 1.6
def redscreen(main_filename, back_filename):
"""
Implements the notion of "redscreening". That is,
the image in the main_filename has its "sufficiently red"
pixels replaced with pixel from the corresponding x,y
location in the image in the file back_filename.
Returns the resulting "redscreened" image.
"""
image = SimpleImage(main_filename)
back = SimpleImage(back_filename)
for pixel in image:
average = (pixel.red + pixel.green + pixel.blue) // 3
# See if this pixel is "sufficiently" red
if pixel.red >= average * INTENSITY_THRESHOLD:
# If so, we get the corresponding pixel from the
# back image and overwrite the pixel in
# the main image with that from the back image.
x = pixel.x
y = pixel.y
image.set_pixel(x, y, back.get_pixel(x, y))
return image
def main():
"""
Run your desired image manipulation functions here.
You should store the return value (image) and then
call .show() to visualize the output of your program.
"""
original_stop = SimpleImage('stop.png')
original_stop.show()
original_leaves = SimpleImage('leaves.png')
original_leaves.show()
stop_leaves_replaced = redscreen('stop.png', 'leaves.png')
# stop_leaves_replaced = redscreen(original_stop, original_leaves)
stop_leaves_replaced.show()
if __name__ == '__main__':
main()
mirror.py
"""
File: mirror.py
---------------
This program shows an example of creating an image
that shows an original image and its mirror reflection
in a new image.
"""
from simpleimage import SimpleImage
def mirror_image(filename):
"""
Read an image from the file specified by filename.
Returns a new images that includes the original image
and its mirror reflection.
Returns the resulting "redscreened" image.
"""
image = SimpleImage(filename)
width = image.width
height = image.height
# Create new image to contain mirror reflection
mirror = SimpleImage.blank(width * 2, height)
for y in range(height):
for x in range(width):
pixel = image.get_pixel(x, y)
mirror.set_pixel(x, y, pixel)
mirror.set_pixel((width * 2) - (x + 1), y, pixel)
return mirror
def main():
"""
Run your desired image manipulation functions here.
You should store the return value (image) and then
call .show() to visualize the output of your program.
"""
original = SimpleImage('burrito.jpg')
original.show()
mirrored = mirror_image('burrito.jpg')
mirrored.show()
if __name__ == '__main__':
main()







2 comments
您好,看了您的文章加上code in place的課程收穫良多,但現在課程已經結束,無法再報名取得Ed的帳號,前兩週您的的文章裡有看到作業可以練習,week3就沒有看到assignments的題目,不知是否方便提供呢?謝謝!
回覆刪除抱歉先前沒看到留言,Assignment並不是每週課程都有,剛剛回去看了Code in Place網頁,一共只有三個Assignment,加最後的Final Project,Assignment 3是在 Week 5的課程文章內喔
刪除Final Project沒有限定題目,是學生自由發揮,最後的連結在此 https://codeinplace.stanford.edu/2021/showcase,有興趣可以參考大家的創作