Functions
ลองเขียนโปรแกรมแบบยังไม่มีฟังก์ชันกันก่อน
ให้เขียนโค้ดเพื่อคำนวณพื้นที่ของสี่เหลี่ยม, วงกลม, สามเหลี่ยม โดยใช้ค่าที่กำหนดให้ แล้วแสดงผลออกมา ดังนี้
Area of rectangle: (พื้นที่)
Area of circle: (พื้นที่)
Area of triangle: (พื้นที่)
Tip
พื้นที่วงกลม = \(\pi r^2\) (ใช้ \(\pi \approx 3.14\)) · พื้นที่สามเหลี่ยม = \(\tfrac{1}{2} \times \text{ฐาน} \times \text{สูง}\)
# Calculating the area of a rectangle
length_rect = 10
width_rect = 5
area_rect = length_rect * width_rect
print("Area of rectangle:", area_rect)
# Calculating the area of a circle
radius_circle = 7
area_circle = 3.14 * radius_circle * radius_circle
print("Area of circle:", area_circle)
# Calculating the area of a triangle
base_triangle = 6
height_triangle = 4
area_triangle = 0.5 * base_triangle * height_triangle
print("Area of triangle:", area_triangle)เขียนโปรแกรมคำนวณพื้นที่ที่ต้องใช้สำหรับการจัดสวน ประกอบด้วย
2x3 m. กับ 3x6 m.0.5 m. กับ 0.25 m.0.2 m. สูง 0.3 m.หาผลรวมของพื้นที่ทั้งหมด แล้วแสดงผลดังนี้
Total Area: (พื้นที่ทั้งหมด)
Note
เหมือนโจทย์ #2 แต่ปรับ landscape เป็นดังนี้
4x8 m.0.3 m. , 0.8 m. , 1 m.0.21 m. สูง 0.13 m.คิดก่อน: ต้องแก้ไขโค้ดกี่จุด? ถ้าสูตรพื้นที่วงกลมผิด ต้องตามแก้ทุกที่ที่คำนวณวงกลมเลยไหม?
Important
เห็นไหมว่าสูตรพื้นที่เดิม ๆ ถูกคัดลอกซ้ำ ๆ หลายจุด → เดี๋ยวเราจะแก้ปัญหานี้ด้วย ฟังก์ชัน
Task-A ถูกเขียนซ้ำหลายจุด → ถ้าต้องแก้ ต้องแก้ทุกที่
แต่ก็อย่า generalize จนเกินพอดี 😅

ที่มา: xkcd #974 — “The General Problem” (CC BY-NC 2.5)
แยกงานซ้ำ ๆ ออกมาเป็นฟังก์ชัน แล้วเรียกใช้ซ้ำได้
What is a function?
การกำหนดและตั้งชื่อให้กับกลุ่มของชุดคำสั่งที่ทำงานร่วมกัน อยู่ในรูปแบบ
def คือ คีย์เวิร์ดสำหรับการนิยามฟังก์ชันfunction_name คือ ชื่อฟังก์ชัน ซึ่งเป็นไปตามกฎการตั้งชื่อparameter_list คือ รายการข้อมูลที่ต้องส่งให้ฟังก์ชัน ฟังก์ชันจึงจะทำงานได้ (อินพุต)result คือ ตัวแปรเก็บผลลัพธ์ ซึ่งจะถูกส่งคืนด้วยคำสั่ง return (เอาต์พุต)การนิยามฟังก์ชัน ต้องทำไว้ก่อนบรรทัดที่จะเรียกใช้งานฟังก์ชันนั้นเสมอ (หลักการเดียวกับการประกาศตัวแปรก่อนใช้)
1 # Function definition
2 def functionA(x, y, z):
3 statement_1
4 ...
5 result = ...
6 return result
7 # end-of-function definition
8
9 # Main program
10 print('Program starts here!!!')
11 n = int(input('Enter data: '))
12
13 # Function call
14 y = functionA(n, 10, [2.5, 2.0])
15 print(f'Result: {y:.2f}')ลำดับการทำงาน
functionA() ใน บรรทัดที่ 14 จึงเริ่มประมวลผลฟังก์ชัน
บรรทัดที่ 2-6) โดย x=n, y=10, z=[2.5, 2.0]result จะถูกส่งไปให้ตัวแปร y ในโปรแกรมหลักมีทั้งอินพุต (parameter) และเอาต์พุต (return)
ให้เขียนฟังก์ชันเพื่อคำนวณพื้นที่ของสี่เหลี่ยม, วงกลม, สามเหลี่ยม ตั้งชื่อว่า area_rectangle, area_circle, area_triangle
แต่ละฟังก์ชันรับพารามิเตอร์ที่ต้องใช้คำนวณ แล้วคืนค่า (return) พื้นที่ออกมา
จากนั้นเรียกใช้ฟังก์ชันเพื่อแสดงผล
Area of rectangle: (พื้นที่)
Area of circle: (พื้นที่)
Area of triangle: (พื้นที่)
def area_rectangle(length, width):
return length * width
def area_circle(radius):
return 3.14 * radius * radius
def area_triangle(base, height):
return 0.5 * base * height
# Using functions
print("Area of rectangle:", area_rectangle(10, 5))
print("Area of circle:", area_circle(7))
print("Area of triangle:", area_triangle(6, 4))ทำโจทย์เดียวกับ #2 (จัดสวน) แต่รอบนี้ให้ใช้ฟังก์ชันคำนวณพื้นที่ที่เขียนเองจาก #4
2x3 m. กับ 3x6 m.0.5 m. กับ 0.25 m.0.2 m. สูง 0.3 m.หาผลรวมพื้นที่ทั้งหมด แล้วแสดง Total Area: (พื้นที่ทั้งหมด)
def area_rectangle(length, width):
return length * width
def area_circle(radius):
return 3.14 * radius * radius
def area_triangle(base, height):
return 0.5 * base * height
total_area = area_rectangle(2, 3) + area_rectangle(3, 6) \
+ area_circle(0.5) + area_circle(0.25) \
+ area_triangle(0.2, 0.3)
print("Total Area:", total_area)Tip
ผลลัพธ์เท่ากับ #2 แต่โค้ดอ่านง่ายกว่า และถ้าสูตรพื้นที่ผิด แก้แค่ในฟังก์ชันจุดเดียว
ฟังก์ชัน mySumAvg — รับ 3 ตัว (x, y, z) และคืนค่า 2 ตัว (sm, avg)
Note
ฟังก์ชัน mySumAvg2 — รับ List 1 ตัว (data) และคืนค่าเป็น List ที่สร้างจาก sm และ avg
Note
ทบทวน: List (Module 4)
เขียนฟังก์ชันคำนวณพื้นที่และเส้นรอบรูปของส่วนประกอบต่าง ๆ ในสวน (ค่าเหมือน #5)
คิดก่อน: จะออกแบบฟังก์ชันให้คืนทั้ง 2 ค่า (area, perimeter) พร้อมกันอย่างไร?
แสดงผล
Total Area: (พื้นที่ทั้งหมด)
Total Perimeter: (เส้นรอบรูปทั้งหมด)
Tip
เส้นรอบรูปวงกลม = \(2\pi r\) · สี่เหลี่ยม = \(2(l+w)\) · สามเหลี่ยมมุมฉาก = \(b + h + \sqrt{b^2+h^2}\)
def rectangle(length, width):
area = length * width
perimeter = 2 * (length + width)
return area, perimeter
def circle(radius):
area = 3.14 * radius * radius
perimeter = 2 * 3.14 * radius
return area, perimeter
def triangle(base, height):
area = 0.5 * base * height
perimeter = base + height + (base**2 + height**2)**0.5
return area, perimeter
parts = [rectangle(2, 3), rectangle(3, 6),
circle(0.5), circle(0.25), triangle(0.2, 0.3)]
total_area = 0
total_peri = 0
for a, p in parts:
total_area += a
total_peri += p
print("Total Area:", total_area)
print("Total Perimeter:", total_peri)Note
ฟังก์ชันไม่จำเป็นต้องมี return หรือ parameter เสมอไป
calculateEquation — รับ x, y แต่ไม่มี return (พิมพ์ผลลัพธ์อยู่ภายในฟังก์ชันเอง)
Note
ทบทวน: input().split() (Module 3)
เมื่อมีฟังก์ชันแล้ว การเรียกใช้ซ้ำ ๆ ทำได้ง่ายด้วย for-loop
printLine — ไม่มีพารามิเตอร์ และไม่คืนค่า ใช้พิมพ์เส้นคั่นซ้ำ ๆ
Parameter passing & return value
call ส่งพารามิเตอร์เข้าฟังก์ชัน → ฟังก์ชันทำงาน → return คืนค่ากลับมายังโปรแกรมหลัก
myPrintString(cnt) — รับ cnt, รับข้อความจากผู้ใช้ แล้ววนพิมพ์ข้อความ cnt รอบmyGraphic(ch, cnt) — รับ ch, cnt; for-loop ด้านนอกขึ้นบรรทัดใหม่, ด้านในพิมพ์ตามเงื่อนไขNote
ทบทวน: while-loop (Module 6) · for-loop (Module 7)
return หลายแห่งreturnscorereturn หลายแห่ง: การเรียกใช้และผลลัพธ์def myGrade(score):
if score < 0 or score > 100:
print("Invalid score!:", score)
return 'X'
elif score >= 80: return 'A'
elif score >= 70: return 'B'
elif score >= 60: return 'C'
elif score >= 50: return 'D'
else: return 'F'
# Main program
scores = [78, 92, 48, 75, 155, 75]
grades = []
for s in scores:
grades.append(myGrade(s)) # เก็บค่าที่ returnNote
ทบทวน: if-elif-else (Module 5) · list (Module 4a)
return vs พิมพ์ในฟังก์ชันแบบ A — return ค่ากลับไป
ฟังก์ชันส่งเกรดกลับ — ไม่พิมพ์อะไรเลย
แบบ B — assign แล้ว print ในฟังก์ชัน
ฟังก์ชันพิมพ์เอง — ไม่ส่งค่ากลับ
✅ ค่าถูกเก็บใน g → เอาไปคิดต่อได้
Important
ฟังก์ชันที่ไม่มี return จะคืนค่า None เสมอ — เอาไปเก็บ ไปเทียบ หรือไปคำนวณต่อไม่ได้
Tip
หลักคิด: ให้ฟังก์ชันคำนวณแล้ว return ส่วนการ print ปล่อยให้โปรแกรมหลักตัดสินใจเอง — ฟังก์ชันแบบนี้นำกลับมาใช้ซ้ำได้มากกว่า
()เขียนแค่ชื่อฟังก์ชัน = ยังไม่ได้เรียกใช้ — ต้องมี () ต่อท้ายเสมอ
Warning
เขียน printLine เฉย ๆ ก็ไม่มีอะไรเกิดขึ้น และไม่ฟ้อง error ด้วย — ต้องเขียน printLine() เท่านั้น
() (ต่อ)คิดก่อน: โค้ดนี้พิมพ์อะไรออกมา?
พิมพ์ Not an A — เพราะ g เป็นตัวฟังก์ชัน ไม่ใช่ 'A' โปรแกรมไม่ error แต่ผลลัพธ์ผิด → บั๊กแบบนี้หายาก ต้องระวังตอนเขียน
Local vs Global variables
ตัวแปรภายใน (Local Variable)
ตัวแปรภายนอก (Global Variable)
ในมองออกได้ · นอกมองเข้าไม่ได้ — ฟังก์ชันอ่าน global ได้ แต่ตัวแปร local ออกนอกฟังก์ชันไม่ได้
x เป็น Global (ประกาศนอกทุกฟังก์ชัน) → เรียกใช้ในฟังก์ชันได้y เป็น Local ของ myFunction() → รู้จักเฉพาะในฟังก์ชันนี้y1 เป็น Local ของ myFunction() → เรียกใช้นอกฟังก์ชันไม่ได้x บรรทัดนอกฟังก์ชัน เป็น Global ; x ในฟังก์ชันเป็น Local (คนละตัว ไม่เกี่ยวกัน)x ถึงไม่เปลี่ยน?x = 3 ในฟังก์ชัน สร้างตัวแปรใหม่ ในขอบเขตของฟังก์ชัน — ไม่ได้ไปแก้ global x
x ที่เป็น parameter ก็เป็น Local ของฟังก์ชัน (คนละตัวกับ global x)x เกิดขึ้นตอน x = myFunction(x) นอกฟังก์ชันฟังก์ชัน (Function)
print, sum, …) และ user-definedนิยาม & เรียกใช้
def name(params): … return resultรูปแบบฟังก์ชัน
return ได้หลายแห่ง — จบทันทีที่พบขอบเขตตัวแปร (Scope)
Tip
แบ่งโปรแกรมใหญ่เป็นฟังก์ชันเล็ก ๆ → เขียนง่าย, debug ง่าย, ใช้ซ้ำได้
Note
ต่อ Module 10: List Comprehension และ 2D Arrays 👉
🏠 259201 — Module 9 | ภาควิชาวิศวกรรมคอมพิวเตอร์ คณะวิศวกรรมศาสตร์ มหาวิทยาลัยเชียงใหม่