8. คำสั่งเลือกทำงาน¶
Conditional Statements
https://drive.google.com/file/d/1GLbTTGfa2oLBckButZd9ZIblrjnJU30f/view?usp=sharing
8.1. จุดประสงค์รายสัปดาห์¶
อธิบายข้อมูลประเภท bool และเขียน Boolean expression
เขียนโปรแกรมเพื่อตัดสินใจโดยใช้คำสั่ง if ได้
เขียนโปรแกรมเพื่อการตัดสินใจโดยใช้ if-else ได้
เขียนโปรแกรมเพื่อการตัดสินใจโดยใช้ if-elif-elif-else ได้
เขียนโปรแกรมเพื่อจัดการข้อผิดพลาดตอน run ได้
เขียนโปรแกรมโดยใช้ nested if ตาม algorithms ที่กำหนดให้ได้
8.2. Boolean¶
ข้อมูลประเภทตรรกะ
ข้อมูลประเภทนี้มีได้สองค่าคือ True
(จริง) หรือ False
(เท็จ)
เท่านั้น เทียบได้กับ ประพจน์ (proposition) ในวิชาคณิตศาสตร์เต็มหน่วย
ประพจน์ (proposition)
ประโยคบอกเล่าที่มีเนื้อหาหรือความหมายที่บอกได้ว่าเป็นความจริงหรือความเท็จ เรียกว่า ค่าความจริง
พระอาทิตย์ขึ้นทิศตะวันออก
คำว่า 'Paul' มี 4 ตัวอักษร
$ 3.25 < 3.55 $
จำนวนตัวอักษรในคำว่า "พอล" มีจำนวนเท่ากับ จำนวนตัวอักษรในคำว่า "Paul"
len('พอล') < len("Paul")
เพรดิเคต (predicate)
ประโยคที่สามารถระบุค่าความจริงได้ ถ้าตัวแปรทุกตัวถูกระบุค่าความจริง
predicate นิยมเขียนพร้อม quantifier และ variable (ตัวแปร) เช่น \(\forall x P(x)\)
\(Q\) : สำหรับทุก ๆ จำนวนเต็ม \(x\) ถ้า \(x\) มีค่าน้อยกว่า -2 แล้ว \(x^2 \gt 4\)
\(\forall x \in Z (x \lt -1) \to x^2 \gt 4\)
8.2.1. 1. การประกาศ¶
p = True
q = False
r = len('พอล') > len('Paul')
x = -3
s = x**2 > 4
8.2.2. 2. ตัวดำเนินการ¶
Python |
Mathematics |
Meaning |
---|---|---|
|
\(\lt\) |
Less than |
|
\(\le\) |
Less than or equal to |
|
\(=\) |
Equal to |
|
\(\ge\) |
Greater than or equal to |
|
\(\gt\) |
Greater than |
|
\(\neq\) |
Not equal to |
ตัวอย่างการใช้งาน
x, y = 1, 2
p = x**2 < y
q = x**2 <= y**0.5
r = x**2 + 3*x == y
s = len('พอล') >= len('Paul')
t = len('พอล'*4) > 3*len('Paul')
u = (x**2 + 3*x + 2) != y
การตรวจสอบช่วงค่า
p = 0 < x < 5
q = -10 < x <= 10
8.2.3. Boolean Expression (Bool_Ex)¶
คำสั่งที่ประมวลผลออกมาได้เป็น True หรือ False
proposition - ประพจน์
predicate - ที่ตัวแปรทุกตัวมีค่า
8.2.4. การเชื่อม Bool_Ex: and, or, not
¶
p = 0 < x and x < 5
q = -10 < x and x <= 10
r = p or q
s = not (p and q) or r
8.3. Decision¶
Decision Control Structure
คำสั่งประเภทตั้งเงื่อนไขการทำงาน
คำสั่งที่เราเขียนถึงตอนนี้ทำงานเป็นแบบเรียงลำดับ sequential
อย่างไรก็ดีการทำงานแบบ sequential นี้ก็ไม่สามารถแก้ปัญหาได้ทั้งหมด บางกรณีก็อาจต้องใช้เงื่อนไขเลือกทำงาน
คำสั่งกำหนดเงื่อนไขการทำงาน(Control structures) ช่วยให้เรากำหนดเงื่อนไขการเรียกคำสั่งได้
8.3.1. ระบบแจ้งเตือนอุณหภูมิ 1¶
โปรแกรมแสดงข้อความแจ้งเตือนเมื่ออุณหภูมิเกินพิกัด
ถ้าอุณหภูมิเกิน 50 องศาให้แสดงข้อความว่าร้อนเกินไป
Algorithm
รับค่าอุณหภูมิ
t
ถ้าค่า
t
มากกว่า 50
แสดงข้อความ 'ร้อนเกินไป'
Implementation
t = float(input('กรอกอุณภูมิ: '))
if t > 50:
print('ร้อนเกินไป')
8.3.2. Extra - อ่านอุณหภูมิของ CPU core¶
ติดตั้ง package เสริม
เปิด gnome-terminal
แล้วพิมพ์
pip3 install --user psutil
คำสั่งอ่านอุณภูมิของ CPU
import psutil
alltemps = psutil.sensors_temperatures() # dict
coretemps = alltemps['coretemp'] # list
t = coretemps[1].current # อุณภูมิของ core 0
เขียนเป็นฟังก์ชัน
def coretemp(core_num):
import psutil
alltemps = psutil.sensors_temperatures()
coretemps = alltemps['coretemp']
return coretemps[core_num].current
โปรแกรมแจ้งเตือนอุณหภูมิของ CPU
t = coretemp(0)
if t > 50:
print('ร้อนเกินไป')
print('\a')
8.4. ระบบแจ้งเตือนอุณภูมิ 1 (One-way)¶

Fig. 8.1 flowchart-01¶
คำสั่งภาษา Python
t = float(input('กรอกอุณภูมิ: '))
if t > 50:
print('ร้อนเกินไป')
8.5. Flowchart ระบบแจ้งเตือนอุณภูมิ 1b¶

Fig. 8.2 flowchart-01b¶
คำสั่งภาษา Python
t = float(input('กรอกอุณภูมิ: '))
if t > 50:
print('ร้อนเกินไป')
else:
print('อุณหภูมิปกติ')
8.6. ระบบแจ้งเตือนอุณหภูมิ 2 (Two-way)¶
โปรแกรมแสดงข้อความแจ้งเตือนเมื่ออุณหภูมิเกินพิกัดและต่ำกว่าพิกัด
ถ้าอุณหภูมิเกิน 30 องศาให้แสดงข้อความว่าร้อนเกินไป
ถ้าอุณหภูมิต่ำกว่า 10 องศาให้แสดงข้อความว่าหนาวเกินไป
8.6.1. ระบบแจ้งเตือนอุณหภูมิ 2a¶

Fig. 8.3 flowchart-02¶
คำสั่งภาษา Python
t = float(input('กรอกอุณหภูมิ: '))
if t > 30:
print('ร้อนเกินไป')
if t < 10:
print('เย็นเกินไป')
8.6.2. ระบบแจ้งเตือนอุณหภูมิ 2b¶

Fig. 8.4 flowchart-02b¶
คำสั่งภาษา Python
t = float(input('กรอกอุณหภูมิ: '))
if t > 30:
print('ร้อนเกินไป')
else:
print('เย็นเกินไป')
8.7. Note: รูปแบบคำสั่ง if
¶
if bool_ex:
statements
ใน statements จะมีกี่คำสั่งก็ได้
statements ใน if จะต้องเยื้องเข้าข้างในด้วยการเคาะหนึ่ง tab
8.8. หารากของสมการกำลังสอง¶
รากของสมการกำลังสองที่อยู่ในรูปแบบ \(f(x) = ax^2 + bx + c\) โดยที่ \(a, b, c\) เป็นค่าคงที่ นั้นสามารถหารากของสมการที่เป็นจำนวนจริงได้ก็ต่อเมื่อ \(b^2 - 4ac \ge 0\)
โจทย์
จงเขียนโปรแกรมเพื่อหารากของสมการ \(f(x) = ax^2 + bx + c\)
Algorithm
รับค่า a, b, c
คำนวณหาค่า \(r = b^2 - 4ac\)
แสดงค่ารากของสมการทั้งสองคือ
\(r_1 = \frac{-b + r}{2a}\)
\(r_2 = \frac{-b - r}{2a}\)
Implementation
a = float(input('a: '))
b = float(input('b: '))
c = float(input('c: '))
r = b**2 - 4*a*c
r1 = (-b + r) / (2 * a)
r2 = (-b - r) / (2 * a)
print( r1, r2 )
เขียนเป็นฟังก์ชัน
def solve(a, b, c):
r = b**2 - 4*a*c
r1 = (-b + r) / (2 * a)
r2 = (-b - r) / (2 * a)
print( r1, r2 )
Testing
solve(1,0,-4)
solve(-3,1,1)
solve(2,-12,7)
8.9. Input Error¶
solve(1, 1, 2)
solve(1, 2, 3)
8.10. Two-way เพื่อการตรวจสอบ 1¶
def solve(a, b, c):
r = b**2 - 4*a*c
if r >= 0:
r1 = (-b + r) / (2 * a)
r2 = (-b - r) / (2 * a)
print( r1, r2 )
else:
print( 'ไม่มีรากของสมการในระบบจำนวนจริง' )
8.10.1. Mutually Exclusive - if/else
¶
สองเงื่อนไขที่มีค่าความจริงตรงกันข้ามกันเสมอ
เงื่อนไขหนึ่งเป็นจริงแล้วอีกเงื่อนไขจะเป็นเท็จ
8.11. Two-way เพื่อการตรวจสอบ 2¶
def solve(a, b, c):
r = b**2 - 4*a*c
if r < 0:
print( 'ไม่มีรากของสมการในระบบจำนวนจริง' )
else:
r1 = (-b + r) / (2 * a)
r2 = (-b - r) / (2 * a)
print( r1, r2 )
8.12. Multi-way Decision¶
ถ้าทดสอบโดยเรียกใช้ solve(1,2,1)
ควรจะแสดงแค่ค่าเดียว
เนื่องจากในทางคณิตศาสตร์สมการนี้มีรากของสมการเดียว คือ 1
การตรวจสอบว่าสมการใดมีรากของสมการเดียวในกรณี \(r = 0\)
เราสามารถเพิ่ม เงื่อนไขของฟังก์ชัน เป็น 3 ทางได้ดังนี้
8.12.1. Multi-way 1¶
def solve(a, b, c):
r = b**2 - 4*a*c
if r < 0:
print( 'ไม่มีรากของสมการในระบบจำนวนจริง' )
elif r == 0:
r1 = (-b + r) / (2 * a)
print( 'สมการมีรากเดียวคือ ', r1 )
else:
r1 = (-b + r) / (2 * a)
r2 = (-b - r) / (2 * a)
print( 'สมการมีสองรากคือ ', r1, r2 )
8.12.2. Multi-way 2 ด้วยวิธี nested¶
Two-way in Two-way
def solve(a, b, c):
r = b**2 - 4*a*c
if r < 0:
print( 'ไม่มีรากของสมการในระบบจำนวนจริง' )
else:
if r == 0:
r1 = (-b + r) / (2 * a)
print( 'สมการมีรากเดียวคือ ', r1 )
else:
r1 = (-b + r) / (2 * a)
r2 = (-b - r) / (2 * a)
print( 'สมการมีสองรากคือ ', r1, r2 )
8.13. Multi-way Decision¶
if Bool_Ex1:
statements
elif Bool_Ex2:
statements
elif Bool_Ex3:
statements
elif Bool_Ex4:
statements
else:
statements
Note
นำมาเขียน mutually exclusive กี่เงื่อนไขก็ได้
การทำงาน
ไล่ตรวจสอบเงื่อนไขไปเรื่อยๆ
จนกว่าจะเจอเงื่อนไขที่เป็นจริง
จึงจะทำตามคำสั่งในเงื่อนไขนั้นแล้วข้ามเงื่อนไขที่เหลือไป
ถ้าไม่มีเงื่อนไขไหนเป็นจริงเลยและมี else จะทำคำสั่งในเงื่อนไข else
การเขียน multi-way decision จะมี หรือ ไม่มี else ก็ได้
8.14. SA - แปลงคะแนนเป็น เกรด¶
โจทย์
จงเขียนโปรแกรมเพื่อแปลงคะแนน score
ให้เป็น grade
ตามเงื่อนไขต่อไปนี้
ต่ำสุด | |
งสุด | gr |
de | |
---|---|---|
0 |
50 |
F |
50 |
60 |
D |
60 |
70 |
C |
70 |
80 |
B |
80 |
100 |
A |
ตัวอย่างข้อมูลนำเข้า-ส่งออก
score |
grade |
---|---|
0 |
F |
49 |
F |
49.99 |
F |
50 |
D |
78 |
B |
8.14.1. Solution - SA¶
Solution 1
score = float(input('คะแนน: '))
if score < 50:
print('F')
elif score < 60:
print('D')
elif score < 70:
print('C')
elif score < 80:
print('B')
else:
print('A')
Solution 2
score = float(input('คะแนน: '))
if 0 < score < 50:
print('F')
elif 50 <= score < 60:
print('D')
elif 60 <= score < 70:
print('C')
elif 70 <= score < 80:
print('B')
else:
print('A')
8.15. EX1001 - Grraderr¶
โจทย์
จงเขียนโปรแกรมเพื่อแปลงไฟล์คะแนนดิบให้เป็นเกรดของแต่ละรายวิชา
ตัวอย่างข้อมูลนำเข้า
0,50,60,70,80,100
5
6111440005,19,22.5,9.2,13
6111440001,20,23.0,9.5,14
6111440003,18,25.0,8.5,13
6111440002,15,22.0,10,12
6111440004,20,27.0,9,15
ตัวอย่างข้อมูลส่งออก
6111440005,C
6111440001,C
6111440003,C
6111440002,D
6111440004,B
8.16. EX1002 - GPAS¶
โจทย์
จงเขียนโปรแกรมเพื่อหาเกรดเฉลี่ยรวมจากเกรดที่เป็นตัวอักษร F, D, D+, C, C+, B, B+, A
โดยตารางการเทียบเกรดเป็นดังนี้
F = 0
D = 1
D+ = 1.5
C = 2
C+ = 2.5
B = 3
B+ = 3.5
A = 4
หมายเหตุ: จำนวนหน่วยกิตทุกวิชาเท่ากัน
ตัวอย่างข้อมูลนำเข้า
B
C
D+
B+
A
ตัวอย่างข้อมูลส่งออก
2.8
ตัวอย่างการคำนวณ
เกรด |
gpa |
---|---|
B |
3 |
C |
2 |
D+ |
1.5 |
B+ |
3.5 |
A |
4 |
ผลรวมคือ \(\frac{3+2+1.5+3.5+4}{5} = \frac{14.0}{5} = 2.8\)
8.17. EX1003 - GRADEWALK¶
โจทย์
เอเคเป็นอาจารย์วิชาหนึ่งซึ่งต้องการประกาศเกรด แต่ต้องการให้นักศึกษาหาใช้เชาว์ปัญญาในการหาเกรดของตัวเอง
วันประกาศเกรด นักศึกษาแต่ละคนจะได้ไฟล์ที่
บรรทัดแรกระบุขนาดตาราง n,m โดย n ระบุจำนวนบรรทัด m ระบุจำนวนเกรดในแต่ละบรรทัด
n บรรทัด ถัดมาเป็นตารางของเกรดเต็มไปด้วยเกรด A, B, C, D หรือ F
บรรทัดถัดจากตารางจะบอกตำแหน่งเริ่มต้น ระบุบรรทัด (r) และตำแหน่งอักขระ (c) จากด้านซ้ายที่เริ่มต้นในบรรทัดเพื่อเป็นจุดเริ่มต้นในการค้นหาเกรดจริง r และ c คั่นด้วย
,
2 บรรทัดถัดไปบอกทิศ (W=ขึ้น/S=ลง/A=ซ้าย/D=ขวา) และจำนวนก้าว
n
การก้าวเดินตามทิศทางที่ระบุ ข้อมูลคั่นด้วย,
เช่น
W,3 \(\to\) หมายถึง ก้าวขึ้นไปด้านบน 3 บรรทัด D,4 \(\to\) หมายถึง ก้าวไปทางขวา 4 ตัวอักษร
หมายเหตุ r และ c เริ่มนับที่ 0
ตัวอย่างข้อมูลนำเข้า
5,20
AAAAABBBBBCCCCCFFFFF
DDDDDDACBCCDDFFFAAAB
FFFFFFCCCBAAAACCFFFD
AACCCDDDBBBFFFFDDDFC
BBBCDDBBCAAAFDCBAAFC
4,6
W,3
D,4
ตัวอย่างข้อมูลส่งออก
C
ลำดับการค้นหา
ตำแหน่งเริ่มต้น 4,6
AAAAABBBBBCCCCCFFFFF
DDDDDDACBCCDDFFFAAAB
FFFFFFCCCBAAAACCFFFD
AACCCDDDBBBFFFFDDDFC
BBBCDD_BCAAAFDCBAAFC
W,3
ก้าวขึ้น 3 บรรทัด
AAAAABBBBBCCCCCFFFFF
DDDDDD_CBCCDDFFFAAAB
FFFFFFCCCBAAAACCFFFD
AACCCDDDBBBFFFFDDDFC
BBBCDDBBCAAAFDCBAAFC
D,4
ก้าวขวา 4 ตัวอักษร
AAAAABBBBBCCCCCFFFFF
DDDDDDACBC_DDFFFAAAB
FFFFFFCCCBAAAACCFFFD
AACCCDDDBBBFFFFDDDFC
BBBCDDBBCAAAFDCBAAFC
เกรดที่ยืนอยู่ตอนนี้คือ
C
8.18. Exception Handling¶
การจัดการข้อผิดพลาด
ในโปรแกรมหาแก้สมการ \(ax^2 + bx + c = 0\) เราใช้คำสั่ง if
เพื่อตรวจสอบค่า r
ป้องกันไม่ให้เกิดข้อผิดพลาดตอนรัน (run-time error)
เมื่อค่า r
เป็นลบ
โดยปกติแล้วโปรแกรมทั่วไปจะใช้ decision structures เพื่อเขียนเงื่อนไขป้องกันข้อผิดพลาดทุกกรณีที่จะเป็นไปได้
Note ฟังก์ชันส่วนใหญ่สำหรับการค้นหาจะส่งค่าพิเศษออกมาเมื่อเกิดข้อผิดพลาดหรือค้นไม่พบ เช่น -1
sentence = 'Anna is a pretty princess.'
sentence.find('pretty')
sentence.find('lady')
Try/Except
โปรแกรมต้องตรวจสอบหลายกรณี โปรแกรมจะมีหลายเงื่อนไข ทำความเข้าใจได้ยาก ภาษาโปรแกรมใหม่ๆ จะมีรูปแบบคำสั่งที่ช่วยลดจำนวนเงื่อนไขในการเขียนเพื่อรองรับข้อผิดพลาด
try:
<body>
except XError:
<handler>
ไม่ต้องใช้เงื่อนไขตรวจทุกขั้นตอน
import math
try:
a,b,c=int(input("a")),int(input("b")),int(input("c"))
r = math.sqrt(b * b - 4 * a * c)
r1 = (-b + r) / (2 * a)
r2 = (-b - r) / (2 * a)
print('r1 = ', r1)
print('r2 = ', r2)
except ValueError:
print('No real roots')
รูปและการทำงาน
try:
try-statements
except ErrorType:
except-statements
ลองทำคำสั่งที่อยู่ใน try-statements
ถ้าไม่เกิด error ที่อยู่ใน except-statements
โปรแกรมจะไม่ crash (หยุดการทำงาน)
try-except ใช้กับ error ได้หลายชนิดช่วยให้โปรแกรมไม่ crash
คำสั่ง try จะมีได้หลาย except โดย except แต่ละตัวจะเหมือนกับ elif (เข้าไปทำอันใดอันหนึ่ง)
except อันสุดท้ายที่ไม่ระบุ Error จะเหมือนกับ else นั่นคือทำคำสั่งในกรณีที่ Error ไม่ตรงกับ except ใดก่อนหน้านี้เลย
ถ้า error ไม่ตรงกับ except ใดเลย โปรแกรมจะ crash
เราสามารถตั้งชื่อ error ได้ (ใส่ชื่อหลัง Error)
8.19. SA - วิเคราะห์ Max of Three¶
หาค่าที่มากที่สุดจากตัวเลข 3 ตัว
Algorithm
รับค่า 3 ตัวเลข
x1, x2, x3
หาค่าสูงสุด max3(x1, x2, x3)
Solution 1
def max3(x1, x2, x3):
if x1 >= x2 >= x3:
print(x1)
elif x2 >= x1 >= x3:
print(x2)
else
print(x3)
ถูกต้องหรือไม่?
Solution 2
def max3(x1, x2, x3):
if x1 >= x2 and x1 >= x3:
print(x1)
elif x2 >= x1 and x2 >= x3:
print(x2)
else
print(x3)
ถูกต้องหรือไม่?
Solution 3
def max3(x1, x2, x3):
if x1 >= x2:
if x1 >= x3:
print(x1)
else:
print(x3)
else:
if x2 >= x3:
print(x2)
else:
print(x3)
ถูกต้องหรือไม่?
Solution 4 > sentinel
maxval = x1
if x2 > maxval:
maxval = x2
if x3 > maxval:
maxval = x3
print( maxval )
Solution 5 > builtin function
maxval = max(x1, x2, x3)
print( maxval )
8.20. ข้อคิด - lesson learnt¶
วิธีแก้มีมากกว่า 1 วิธี > อย่ารีบด่วนเขียนคำสั่งตามวิธีที่คิดได้วิธีแรก ให้คิดหาวิธีอื่นให้รอบคอบก่อน
สิ่งแรกคือหา algorithm ที่เหมาะสม แล้วดู
clarity-ชัดเจน
simplicity-เข้าใจง่าย
efficiency-ประสิทธิภาพ
scalability-นำไปใช้กับกรณีอื่นได้
elegance-ความเลิศหรู
หาแนวคิดที่สามารถนำไปใช้ในกรณีทั่วไปได้ (คิดทำ package/library)
Don't re-invent the wheel.
หา package/libarary ที่มีอยู่แล้ว
ศึกษาแนวทางการเขียน หลักความคิด จาก libary ที่เป็นที่นิยม
เอาแนวคิดมา apply
8.21. EX1004 - STATUS¶
โจทย์
จงเขียนโปรแกรมเพื่อแจ้งเตือนสถานะนักศึกษาจากไฟล์รวมเกรดนักศึกษา
สถานะนักศึกษาคิดจาก เกรดเฉลี่ย และ จำนวนหน่วยกิต ดังนี้
ถ้าจำนวนหน่วยกิตน้อยกว่า 60
ถ้าเกรดเฉลี่ย น้อยกว่า 1.50 สถานะคือ 'DISMISSAL'
ถ้าเกรดเฉลี่ย มากกว่าหรือเท่ากับ 1.50 แต่น้อยกว่า 2.00 สถานะคือ 'WARN'
ถ้าเกรดเฉลี่ย มากกว่าหรือเท่ากับ 2.00 สถานะคือ 'NORMAL'
ถ้าจำนวนหน่วยกิตมากกว่าหรือเท่ากับ 60
ถ้าเกรดเฉลี่ย น้อยกว่า 1.75 สถานะคือ 'DISMISSAL'
ถ้าเกรดเฉลี่ย มากกว่าหรือเท่ากับ 1.75 แต่น้อยกว่า 2.00 สถานะคือ 'WARN'
ถ้าเกรดเฉลี่ย มากกว่าหรือเท่ากับ 2.00 แต่น้อยกว่า 3.25 สถานะคือ 'NORMAL'
ถ้าเกรดเฉลี่ย มากกว่าหรือเท่ากับ 3.25 แต่น้อยกว่า 3.50 สถานะคือ 'SECOND CLASS HONOR'
ถ้าเกรดเฉลี่ย มากกว่าหรือเท่ากับ 3.50 สถานะคือ 'FIRST CLASS HONOR'
รูปแบบข้อมูล
ตัวเลขระบุจำนวนรายวิชา (n)
n บรรทัดที่เหลือจะมีข้อมูลผลการเรียนระบุจำนวนหน่วยกิต (c) และเกรดที่ได้ (g) โดยที่ c และ g คั่นด้วย ,
หมายเหตุ โดยตารางการเทียบเกรดเป็นดังนี้
F = 0
D = 1
D+ = 1.5
C = 2
C+ = 2.5
B = 3
B+ = 3.5
A = 4
ตัวอย่างข้อมูลนำเข้า
14
3,B
3,B
3,B
3,B
2,C+
1,D
3,B
3,A
2,B+
3,A
3,B
2,A
3,B+
3,A
ตัวอย่างข้อมูลส่งออก
NORMAL