Python – Exception Handling(Try, Except และ Finally)
ทำความรู้จักกับ exception
ในบทนี้เราจะมาพูดถึงขั้นตอนในการเขียนคำสั่งเพื่อดักจับข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นได้ในโปรแกรมที่เราเขียนขึ้นมาใช้งาน จากบทที่แล้ว ที่เราได้พูดถึงชนิดของข้อผิดพลาดที่มีให้ใช้งานกันใน python(built-in exception) ซึ่งเมื่อเกิดข้อผิดพลาดในระหว่างการดำเนินการคำสั่งต่างๆ ก็จะมีการแจ้งข้อผิดพลาดนั้นออกมา โดยสามารถจะมีรูปแบบที่เฉพาะเจาะจงตามชนิดของข้อผิดพลาดนั้นๆ หรืออาจจะมีรูปแบบอธิบายข้อผิดพลาดแบบกว้างๆ ก็ได้
เมื่อเกิดข้อผิดพลาด(exceptions) ขึ้นในระหว่างการดำเนินการทำคำสั่ง หากเรามีการเขียนคำสั่งเพื่อจัดการกับข้อผิดพลาดได้ถูกต้องและครอบคลุมถึงชนิดข้อผิดพลาดดังกล่าว และมีการปรับคำสั่งรองรับให้เหมาะสม เราสามารถจะข้ามขั้นตอนที่ทำให้เกิดข้อผิดพลาดนั้นไป และไปทำงานในคำสั่งส่วนอื่นๆ หรืออาจจะให้โปรแกรมหยุดการทำงานแต่ก็แจ้งรายละเอียดข้อผิดพลาดที่เหมาะสมและเข้าใจง่ายได้ แต่หากเราไม่มีการเขียนคำสั่งเพื่อจัดการกับข้อผิดพลาดเลย อาจจะส่งผลให้โปรแกรมที่ดำเนินการอยู่หยุดลงทันที โดยไม่ได้ทำการบันทึกข้อมูลสำคัญ, จัดการกับข้อมูลที่ได้ประมวลผลก่อนหน้า หรือ ปรับข้อความให้เหมาะสมเผื่อให้ผู้ใช้งานสามารถเข้าใจถึงข้อผิดพลาดได้ง่าย
ตัวอย่างเช่น ถ้าหากมีการเขียนโปรแกรมให้ฟังก์ชัน A เรียกใช้ฟังก์ชัน B ซึ่งเรียกใช้ฟังก์ชัน C อีกที แล้วมีข้อผิดพลาดเกิดขึ้นในฟังก์ชัน C
ถ้าภายในฟังก์ชัน C มีการเขียนคำสั่งเพื่อจัดการข้อผิดพลาด โดยอาจเป็นการระบุค่าที่เหมาะสม หรือปรับอัลกอริทึมให้เหมาะสม แล้วแจ้งข้อมูลข้อผิดพลาดนั้นและวิธีแก้ไขให้ผู้ใช้ทราบเพื่อเป็นข้อมูล ก็สามารถข้ามไปทำคำสั่งอื่นๆ ต่อไปได้โดยไม่หยุดการทำงานของโปรแกรม
แต่ถ้าไม่มีการเขียนคำสั่งเพื่อจัดการข้อผิดพลาด(handle exception) ไว้ในฟังก์ชัน C การดำเนินการคำสั่งอื่นๆในฟังก์ชัน C ก็จะหยุดลง แล้วแจ้งข้อผิดพลาดดังกล่าวต่อไปยังฟังก์ชัน B และ A ตามลำดับ และถ้าในโปรแกรมไม่มีการเขียนส่วนรองรับข้อผิดพลาดไว้เลย โปรแกรมจะหยุดการทำงานทันที โดยข้อมูลที่ถูกประมวลผลมาตั้งแต่ฟังก์ชัน A หรือ B ก็จะอาจจะยังไม่ถูกจัดเก็บอย่างถูกต้องด้วย
โดยในบทนี้เราจะมาทำความเข้าใจถึงวิธีต่างๆ ในการเขียนโปรแกรมและมีการดักจับข้อผิดพลาด สำหรับตัวอย่างในบทนี้ จะทำการสร้างข้อมูลระยะทางที่ได้จากการเคลื่่อนที่ของวัตถุ(S) โดยใช้สมการของการเคลื่อนที่โดยเราทราบความเร็วต้น(u), ความเร่งคงที่(a) และ เวลาที่ใช้ในการสังเกตุ(t) เมื่อได้ข้อมูลระยะทางดังกล่าวแล้ว เราจะนำข้อมูลนั้นมาแสดงเป็นกราฟเส้น โดยมีขั้นตอนดังนี้
-
ระบุสมการการเคลื่อนที่สำหรับคำนวณระยะทาง(S) ที่วัตถุจะเคลื่อนที่ได้ภายในช่วงเวลาที่ระบุ(t) โดยทราบความเร็วต้นของวัตถุ(u) และ ทราบความเร่งคงที่ของการเคลื่อนที่(a) จากสมการ:
S = ut + 1/2at2
S: ระยะทางทั้งหมดของการเคลื่อนที่จากช่วงเวลาที่ระบุ(เมตร)
u: ความเร็วเริ่มต้นของการเคลื่อนที่(เมตร/วินาที)
a: ความเร่งคงที่ของการเคลื่อนที่(เมตร/วินาที2)
t: ระยะเวลาที่ทำการสังเกตุ(วินาที) - นำสมการการเคลื่อนที่ดังกล่าวมาสร้างเป็นฟังก์ชันเพื่อใช้ในการคำนวณ
# ฟังก์ชันสำหรับคำนวณระยะทางจากข้อมูลความเร็วต้น, ความเร่งและเวลา def calculate_distance(initial_velocity, acceloration, time): distance = initial_velocity*time + (1.0/2.0)*acceloration*math.pow(time, 2) return distance
-
เขียนคำสั่งเพื่อขอรับข้อมูลความเร็วต้น(u), ความเร่งคงที่ของการเคลื่อนที่(a) , เวลาทั้งหมดที่ใช้สังเกตุการณ์(t)

- เขียนฟังก์ชันเพื่อทำการตรวจสอบข้อมูลที่รับเข้ามา ว่าเป็นข้อมูลในรูปแบบที่ถูกต้องหรือไม่ โดยข้อมูลความเร็วต้น(u) และความเร่งคงที่ของการเคลื่อนที่(a) จะต้องเป็นข้อมูลที่สามารถแปลงเป็นตัวเลขทศนิยมได้ ส่วนข้อมูลเวลาทั้งหมดที่ใช้สังเกตุการณ์(t) จะต้องเป็นข้อมูลที่สามารถแปลงเป็นตัวเลขจำนวนเต็มได้
# ฟังก์ชันสำหรับแปลงค่าข้อมูลที่ได้รับจาก console ให้เป็นตัวเลขจำนวนเต็ม def convert_to_int(value): # ใช้ try...except เพื่อทำการตรวจสอบข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นในระหว่างการแปลงค่าข้อมูล try: value = int(value) return value # ดักจับข้อผิดพลาดในการระบุค่าข้อมูลผิดรูปแบบ except: print( "Error: Input value is invalid. Please input specify input as integer.") sys.exit(1) # ฟังก์ชันสำหรับแปลงค่าข้อมูลที่ได้รับจาก console ให้เป็นตัวเลขทศนิยม def convert_to_float(value): # ใช้ try...except เพื่อทำการตรวจสอบข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นในระหว่างการแปลงค่าข้อมูล try: value = float(value) return value # ดักจับข้อผิดพลาดในการระบุค่าข้อมูลผิดรูปแบบ except: print( "Error: Input value is invalid. Please input specify input as float.") sys.exit(1)
-
สร้างชุดข้อมูลที่ได้จากการคำนวณระยะทางที่เดินทางได้ เมื่อเวลาผ่านไปในแต่ละวินาที จากช่วงเวลาที่ระบุ โดยสมการการเคลื่อนที่ที่ระบุข้างต้น

-
นำข้อมูลดังกล่าวมาสร้างเป็นกราฟเส้นแสดงความสัมพันธ์ระหว่างระยะทางที่เดินทางได้กับเวลา

การเขียนคำสั่งเพื่อดักจับข้อผิดพลาดในรูปแบบต่างๆ
-
การดักจับข้อผิดพลาด
เราสามารถเขียนคำสั่งเพื่อทำการดักจับข้อผิดพลาดที่อาจเกิดขึ้นในโปรแกรมด้วยการใช้คำสั่งในรูปแบบ try…except…
try # กลุ่มคำสั่งโดยทั่วไปซึ่งอาจส่งผลให้เกิดข้อผิดพลาดได้ except: # กลุ่มคำสั่งที่ดำเนินการเมื่อเกิดข้อผิดพลาดต่างๆ ขึ้น
โดยการดำเนินการต่างๆ ที่อาจจะส่งผลทำให้เกิดข้อผิดพลาดได้ จะถูกเขียนอยู่ภายในบล๊อกของ try และคำสั่งในส่วนที่จะให้ดำเนินการหลังจากตรวจพบข้อผิดพลาด จะถูกเขียนไว้ในบล๊อกของ except และสามารถจะแสดงข้อมูลที่เป็นสาเหตุให้เกิดข้อผิดพลาดนี้ได้ภายในบล๊อก except นี้ด้วย
โดยผู้พัฒนาจะต้องตัดสินใจเองตามความเหมาะสมว่า ภายในโปรแกรมน่าจะมีข้อผิดพลาดเกิดขึ้นในส่วนใดบ้าง, มีข้อผิดพลาดในรูปแบบไหน และจะเขียนคำสั่งเพื่อจัดการข้อผิดพลาดดังกล่าวได้อย่างไร
ตัวอย่างการใช้งาน
# -*- coding: utf-8 -*- # เรียกใช้งานไลบรารี่ math เพื่อใช้งานฟังก์ชันสำหรับเลขยกกำลัง import math # เรียกใช้งานไลบรารี่ sys เพื่อใช้งานฟังก์ชัน exit สำหรับออกจากโปรแกรม import sys # เรียกใช้งานไลบรารี่ matplotlib เพื่อนำข้อมูลที่สร้างขึ้นมาพล๊อตเป็นกราฟเส้น # แสดงความสัมพันธ์ข้อมูล import matplotlib.pyplot as plt # ฟังก์ชันสำหรับคำนวณระยะทางจากข้อมูลความเร็วต้น, ความเร่งและเวลา def calculate_distance(initial_velocity, acceloration, time): distance = initial_velocity*time + (1.0/2.0)*acceloration*math.pow(time, 2) return distance # ฟังก์ชันสำหรับแปลงค่าข้อมูลที่ได้รับจาก console ให้เป็นตัวเลขจำนวนเต็ม def convert_to_int(value): # ใช้ try...except เพื่อทำการตรวจสอบข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นในระหว่างการแปลงค่าข้อมูล try: value = int(value) return value # ดักจับข้อผิดพลาดในการระบุค่าข้อมูลผิดรูปแบบ except: print( "Error: Input value is invalid. Please input specify input as integer.") sys.exit(1) # ฟังก์ชันสำหรับแปลงค่าข้อมูลที่ได้รับจาก console ให้เป็นตัวเลขทศนิยม def convert_to_float(value): # ใช้ try...except เพื่อทำการตรวจสอบข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นในระหว่างการแปลงค่าข้อมูล try: value = float(value) return value # ดักจับข้อผิดพลาดในการระบุค่าข้อมูลผิดรูปแบบ except: print( "Error: Input value is invalid. Please input specify input as float.") sys.exit(1) # เรียกใช้งานฟังก์ชัน input() เพื่อทำการขอรับข้อมูลความเร็วต้น, ความเร่งคงที่ # เวลาที่ใช้สังเกตุการณ์ จากทาง console u_input = input("Input initial velocity(u): ") a_input = input("Input constant acceleration(a): ") t_input = input("Input total time(t): ") # ทำการแปลงข้อมูลความเร็วต้นให้เป็นข้อมูลชนิดตัวเลขทศนิยม u = convert_to_float(u_input) # 0 m/s # ทำการแปลงข้อมูลความเร่งคงที่ให้เป็นข้อมูลชนิดตัวเลขทศนิยม a = convert_to_float(a_input) # 4 m/s^2 # ทำการแปลงข้อมูลเวลาที่ใช้ในการสังเกตุการณ์ให้เป็นข้อมูลชนิดตัวเลขจำนวนเต็ม t = convert_to_int(t_input) # second # ทำการสร้างข้อมูลช่วงเวลาจากเวลาวินาทีที่ 0 ถึงวินาทีที่ทำการระบุ time_range = range(t+1) # ทำการคำนวณเพื่อสร้างชุดข้อมูลของระยะทางที่เคลื่อนที่ได้ในแต่ละช่วงเวลา # จากข้อมูลเวลา, ความเร็วต้น และความเร่งคงที่ที่ทำการระบุ distance_by_time = [] for second in time_range: s = calculate_distance(u, a, second) distance_by_time.append( s ) # นำข้อมูลระยะทางที่เคลื่อนที่ได้ และช่วงเวลามาพล๊อตเป็นข้อมูลในรูปแบบกราฟเส้น plt.plot(time_range, distance_by_time) plt.xlabel('time(second)') plt.ylabel('distance(metre)') title_text = "Distances by time with known parameters(u, a, t)\n u={}, a={}, t={}".format(u, a, t) plt.title(title_text) plt.show()จากตัวอย่าง โปรแกรมจะขอรับข้อมูลของความเร็วต้น, ความเร่งคงที่และเวลาที่สังเกตุการณ์จากทาง console จากนั้นจะทำการตรวจสอบข้อมูลดังกล่าวว่าอยู่ในรูปแบบที่ถูกต้องหรือไม่
หากเป็นข้อมูลในรูปแบบที่ถูกต้อง โปรแกรมจะทำการสร้างข้อมูลของระยะทางที่วัตถุเคลื่อนที่ได้ในแต่ละช่วงเวลา ตามข้อมูลที่ระบุ แล้วจึงใช้ข้อมูลดังกล่าวในการพล๊อตออกมาเป็นกราฟเส้น
แต่หากข้อมูลดังกล่าวอยู่ในรูปแบบที่ไม่ถูกต้อง โปรแกรมดำเนินการคำสั่งที่กำหนดไว้เมื่อเกิดข้อผิดพลาด โดยทำการแจ้งรายละเอียดข้อผิดพลาดให้สามารถเข้าใจง่ายขึ้นแล้วหยุดการทำงานของโปรแกรม




-
การดักจับข้อผิดพลาดแบบเฉพาะเจาะจงตามรูปแบบที่เกิดข้อผิดพลาด
เราสามารถดักจับข้อผิดพลาดที่อาจเกิดขึ้นในระหว่างรันคำสั่ง แบบระบุข้อผิดพลาดให้เฉพาะเจาะจงเป็นชนิดๆ ไปได้ เพื่อที่จะทำให้เราสามารถจะเขียนโปรแกรมรองรับข้อผิดพลาดในแต่ละรูปแบบแยกเป็นส่วนๆ ให้เหมาะสมตามข้อผิดพลาดที่เกิดขึ้นได้ โดยเราอาจจะดักจับข้อผิดพลาดแยกเป็นแต่ละชนิดเดี่ยวๆ หรือดักจับข้อผิดพลาดโดยจับกลุ่มกันหลายชนิดที่มีรูปแบบคล้ายกัน
ตัวอย่างการใช้งาน# -*- coding: utf-8 -*- # เรียกใช้งานไลบรารี่ math เพื่อใช้งานฟังก์ชันสำหรับเลขยกกำลัง import math # เรียกใช้งานไลบรารี่ sys เพื่อใช้งานฟังก์ชัน exit สำหรับออกจากโปรแกรม import sys # เรียกใช้งานไลบรารี่ matplotlib เพื่อนำข้อมูลที่สร้างขึ้นมาพล๊อตเป็นกราฟเส้น # แสดงความสัมพันธ์ข้อมูล import matplotlib.pyplot as plt # ฟังก์ชันสำหรับคำนวณระยะทางจากข้อมูลความเร็วต้น, ความเร่งและเวลา def calculate_distance(initial_velocity, acceloration, time): distance = initial_velocity*time + (1.0/2.0)*acceloration*math.pow(time, 2) return distance # ฟังก์ชันสำหรับแปลงค่าข้อมูลที่ได้รับจาก console ให้เป็นตัวเลขจำนวนเต็ม def convert_to_int(value): # ใช้ try...except เพื่อทำการตรวจสอบข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นในระหว่างการแปลงค่าข้อมูล try: value = int(value) return value # ดักจับข้อผิดพลาดในการระบุค่าข้อมูลผิดรูปแบบ except ValueError as e: print( "Error: Input value is invalid. Please input specify input as integer.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในการระบุชนิดของตัวแปรไม่ถูกต้อง except TypeError as e: print( "Error: Input value is invalid. Please input specify input as integer.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในรูปแบบอื่นๆ นอกเหนือจากที่ระบุข้างต้น except Exception as e: print( "Error: Input value is invalid." ) print( str(e) ) sys.exit(1) # ฟังก์ชันสำหรับแปลงค่าข้อมูลที่ได้รับจาก console ให้เป็นตัวเลขทศนิยม def convert_to_float(value): # ใช้ try...except เพื่อทำการตรวจสอบข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นในระหว่างการแปลงค่าข้อมูล try: value = float(value) return value # ดักจับข้อผิดพลาดในการระบุค่าข้อมูลผิดรูปแบบ except ValueError as e: print( "Error: Input value is invalid. Please input specify input as float.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในการระบุชนิดของตัวแปรไม่ถูกต้อง except TypeError as e: print( "Error: Input value is invalid. Please input specify input as float.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในรูปแบบอื่นๆ นอกเหนือจากที่ระบุข้างต้น except Exception as e: print( "Error: Input value is invalid.") print( str(e) ) sys.exit(1) # เรียกใช้งานฟังก์ชัน input() เพื่อทำการขอรับข้อมูลความเร็วต้น, ความเร่งคงที่ # เวลาที่ใช้สังเกตุการณ์ จากทาง console u_input = input("Input initial velocity(u): ") a_input = input("Input constant acceleration(a): ") t_input = input("Input total time(t): ") # ทำการแปลงข้อมูลความเร็วต้นให้เป็นข้อมูลชนิดตัวเลขทศนิยม u = convert_to_float(u_input) # 0 m/s # ทำการแปลงข้อมูลความเร่งคงที่ให้เป็นข้อมูลชนิดตัวเลขทศนิยม a = convert_to_float(a_input) # 4 m/s^2 # ทำการแปลงข้อมูลเวลาที่ใช้ในการสังเกตุการณ์ให้เป็นข้อมูลชนิดตัวเลขจำนวนเต็ม t = convert_to_int(t_input) # second # ทำการสร้างข้อมูลช่วงเวลาจากเวลาวินาทีที่ 0 ถึงวินาทีที่ทำการระบุ time_range = range(t+1) # ทำการคำนวณเพื่อสร้างชุดข้อมูลของระยะทางที่เคลื่อนที่ได้ในแต่ละช่วงเวลา # จากข้อมูลเวลา, ความเร็วต้น และความเร่งคงที่ที่ทำการระบุ distance_by_time = [] for second in time_range: s = calculate_distance(u, a, second) distance_by_time.append( s ) # นำข้อมูลระยะทางที่เคลื่อนที่ได้ และช่วงเวลามาพล๊อตเป็นข้อมูลในรูปแบบกราฟเส้น plt.plot(time_range, distance_by_time) plt.xlabel('time(second)') plt.ylabel('distance(metre)') title_text = "Distances by time with known parameters(u, a, t)\n u={}, a={}, t={}".format(u, a, t) plt.title(title_text) plt.show()จากตัวอย่าง โปรแกรมจะขอรับข้อมูลของความเร็วต้น, ความเร่งคงที่และเวลาที่สังเกตุการณ์จากทาง console จากนั้นจะทำการตรวจสอบข้อมูลดังกล่าวว่าอยู่ในรูปแบบที่ถูกต้องหรือไม่
หากเป็นข้อมูลในรูปแบบที่ถูกต้อง โปรแกรมจะทำการสร้างข้อมูลของระยะทางที่วัตถุเคลื่อนที่ได้ในแต่ละช่วงเวลา ตามข้อมูลที่ระบุ แล้วจึงใช้ข้อมูลดังกล่าวในการพล๊อตออกมาเป็นกราฟเส้น
แต่หากข้อมูลดังกล่าวอยู่ในรูปแบบที่ไม่ถูกต้อง โปรแกรมดำเนินการคำสั่งที่กำหนดไว้เมื่อเกิดข้อผิดพลาด โดยทำการแจ้งรายละเอียดข้อผิดพลาดให้สามารถอ่านเข้าใจได้ง่ายแล้วหยุดการทำงานของโปรแกรม




-
การสร้างข้อผิดพลาดขึ้นเอง
เราสามารถสร้างข้อผิดพลาดขึ้นมาใช้งานเองในโปรแกรมได้ ได้โดยใช้คีย์เวิร์ด raise เพื่อทำการสร้างข้อผิดพลาดขึ้นหากมีข้อมูลไม่เหมาะสม และสามารถระบุข้อมูลสำหรับระบุรายละเอียดข้อผิดพลาดเพิ่มเติมลงไปได้
ตัวอย่างการใช้งาน# -*- coding: utf-8 -*- # เรียกใช้งานไลบรารี่ math เพื่อใช้งานฟังก์ชันสำหรับเลขยกกำลัง import math # เรียกใช้งานไลบรารี่ sys เพื่อใช้งานฟังก์ชัน exit สำหรับออกจากโปรแกรม import sys # เรียกใช้งานไลบรารี่ matplotlib เพื่อนำข้อมูลที่สร้างขึ้นมาพล๊อตเป็นกราฟเส้น # แสดงความสัมพันธ์ข้อมูล import matplotlib.pyplot as plt # ฟังก์ชันสำหรับคำนวณระยะทางจากข้อมูลความเร็วต้น, ความเร่งและเวลา def calculate_distance(initial_velocity, acceloration, time): distance = initial_velocity*time + (1.0/2.0)*acceloration*math.pow(time, 2) return distance # ฟังก์ชันสำหรับแปลงค่าข้อมูลที่ได้รับจาก console ให้เป็นตัวเลขจำนวนเต็ม def convert_to_int(value): # ใช้ try...except เพื่อทำการตรวจสอบข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นในระหว่างการแปลงค่าข้อมูล try: value = int(value) if(value < 0): raise Exception("Error: Input value should be greater than 0.") return value # ดักจับข้อผิดพลาดในการระบุค่าข้อมูลผิดรูปแบบ except ValueError as e: print( "Error: Input value is invalid. Please input specify input as integer.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในการระบุชนิดของตัวแปรไม่ถูกต้อง except TypeError as e: print( "Error: Input value is invalid. Please input specify input as integer.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในรูปแบบอื่นๆ นอกเหนือจากที่ระบุข้างต้น except Exception as e: print( str(e) ) sys.exit(1) # ฟังก์ชันสำหรับแปลงค่าข้อมูลที่ได้รับจาก console ให้เป็นตัวเลขทศนิยม def convert_to_float(value): # ใช้ try...except เพื่อทำการตรวจสอบข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นในระหว่างการแปลงค่าข้อมูล try: value = float(value) if(value < 0): raise Exception("Error: Input value should be greater than 0.") return value # ดักจับข้อผิดพลาดในการระบุค่าข้อมูลผิดรูปแบบ except ValueError as e: print( "Error: Input value is invalid. Please input specify input as float.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในการระบุชนิดของตัวแปรไม่ถูกต้อง except TypeError as e: print( "Error: Input value is invalid. Please input specify input as float.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในรูปแบบอื่นๆ นอกเหนือจากที่ระบุข้างต้น except Exception as e: print( str(e) ) sys.exit(1) # เรียกใช้งานฟังก์ชัน input() เพื่อทำการขอรับข้อมูลความเร็วต้น, ความเร่งคงที่ # เวลาที่ใช้สังเกตุการณ์ จากทาง console u_input = input("Input initial velocity(u): ") a_input = input("Input constant acceleration(a): ") t_input = input("Input total time(t): ") # ทำการแปลงข้อมูลความเร็วต้นให้เป็นข้อมูลชนิดตัวเลขทศนิยม u = convert_to_float(u_input) # 0 m/s # ทำการแปลงข้อมูลความเร่งคงที่ให้เป็นข้อมูลชนิดตัวเลขทศนิยม a = convert_to_float(a_input) # 4 m/s^2 # ทำการแปลงข้อมูลเวลาที่ใช้ในการสังเกตุการณ์ให้เป็นข้อมูลชนิดตัวเลขจำนวนเต็ม t = convert_to_int(t_input) # second # ทำการสร้างข้อมูลช่วงเวลาจากเวลาวินาทีที่ 0 ถึงวินาทีที่ทำการระบุ time_range = range(t+1) # ทำการคำนวณเพื่อสร้างชุดข้อมูลของระยะทางที่เคลื่อนที่ได้ในแต่ละช่วงเวลา # จากข้อมูลเวลา, ความเร็วต้น และความเร่งคงที่ที่ทำการระบุ distance_by_time = [] for second in time_range: s = calculate_distance(u, a, second) distance_by_time.append( s ) # นำข้อมูลระยะทางที่เคลื่อนที่ได้ และช่วงเวลามาพล๊อตเป็นข้อมูลในรูปแบบกราฟเส้น plt.plot(time_range, distance_by_time) plt.xlabel('time(second)') plt.ylabel('distance(metre)') title_text = "Distances by time with known parameters(u, a, t)\n u={}, a={}, t={}".format(u, a, t) plt.title(title_text) plt.show()จากตัวอย่าง โปรแกรมจะขอรับข้อมูลของความเร็วต้น, ความเร่งคงที่และเวลาที่สังเกตุการณ์จากทาง console จากนั้นจะทำการตรวจสอบข้อมูลดังกล่าวว่าอยู่ในรูปแบบที่ถูกต้องหรือไม่
หากเป็นข้อมูลในรูปแบบที่ถูกต้อง โปรแกรมจะทำการสร้างข้อมูลของระยะทางที่วัตถุเคลื่อนที่ได้ในแต่ละช่วงเวลา ตามข้อมูลที่ระบุ แล้วจึงใช้ข้อมูลดังกล่าวในการพล๊อตออกมาเป็นกราฟเส้น
แต่หากข้อมูลดังกล่าวอยู่ในรูปแบบที่ไม่ถูกต้อง โปรแกรมดำเนินการคำสั่งที่กำหนดไว้เมื่อเกิดข้อผิดพลาด โดยทำการแจ้งรายละเอียดข้อผิดพลาดให้อ่านแล้วเข้าใจได้ง่ายแล้วจึงหยุดการทำงานของโปรแกรม
โดยเราจะมีการเพิ่มรายละเอียดสำหรับตรวจสอบข้อมูลเวลาที่สังเกตุการณ์เพิ่มขึ้น โดยหากข้อมูลเวลาที่รับเข้าไปมาค่าน้อยกว่า 0 โปรแกรมจะสร้างข้อผิดพลาดขึ้นแล้วทำการแจ้งข้อผิดพลาดและหยุดการทำงานของโปรแกรม




-
การใช้ try…finally
เราสามารถใช้งาน try…finally เพื่อให้โปรแกรมทำคำสั่งที่อยู่ในบล๊อก finally เสมอไม่ว่าชุดคำสั่งที่ถูกเขียนในบล๊อก try จะมีข้อผิดพลาดหรือไม่
ตัวอย่างเช่น หากเราทำการเปิดไฟล์เอาไว้ แล้วระหว่างทำการอ่าน/เขียน ข้อมูลกับไฟล์ดังกล่าวเกิดข้อผิดพลาดขึ้น เราควรที่จะทำการปิดไฟล์เพื่อคืนทรัพยาการให้กับระบบให้เรียบร้อยไม่ว่าระหว่างดำเนินการกับไฟล์จะเกิดข้อผิดพลาดขึ้นหรือไม่
ตัวอย่างการใช้งาน# -*- coding: utf-8 -*- # เรียกใช้งานไลบรารี่ math เพื่อใช้งานฟังก์ชันสำหรับเลขยกกำลัง import math # เรียกใช้งานไลบรารี่ sys เพื่อใช้งานฟังก์ชัน exit สำหรับออกจากโปรแกรม import sys # เรียกใช้งานไลบรารี่ matplotlib เพื่อนำข้อมูลที่สร้างขึ้นมาพล๊อตเป็นกราฟเส้น # แสดงความสัมพันธ์ข้อมูล import matplotlib.pyplot as plt # เรียกใช้งานไลบรารี่ json เพื่อใช้งานฟังก์ชัน dumps ในการแปลงข้อมูล json # เให้อยู่ในรูปแบบข้อความ import json # ฟังก์ชันสำหรับคำนวณระยะทางจากข้อมูลความเร็วต้น, ความเร่งและเวลา def calculate_distance(initial_velocity, acceloration, time): distance = initial_velocity*time + (1.0/2.0)*acceloration*math.pow(time, 2) return distance # ฟังก์ชันสำหรับแปลงค่าข้อมูลที่ได้รับจาก console ให้เป็นตัวเลขจำนวนเต็ม def convert_to_int(value): # ใช้ try...except เพื่อทำการตรวจสอบข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นในระหว่างการแปลงค่าข้อมูล try: value = int(value) if(value < 0): raise Exception("Error: Input value should be greater than 0.") return value # ดักจับข้อผิดพลาดในการระบุค่าข้อมูลผิดรูปแบบ except ValueError as e: print( "Error: Input value is invalid. Please input specify input as integer.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในการระบุชนิดของตัวแปรไม่ถูกต้อง except TypeError as e: print( "Error: Input value is invalid. Please input specify input as integer.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในรูปแบบอื่นๆ นอกเหนือจากที่ระบุข้างต้น except Exception as e: print( str(e) ) sys.exit(1) # ฟังก์ชันสำหรับแปลงค่าข้อมูลที่ได้รับจาก console ให้เป็นตัวเลขทศนิยม def convert_to_float(value): # ใช้ try...except เพื่อทำการตรวจสอบข้อผิดพลาดในรูปแบบต่างๆ ที่อาจเกิดขึ้นในระหว่างการแปลงค่าข้อมูล try: value = float(value) if(value < 0): raise Exception("Error: Input value should be greater than 0.") return value # ดักจับข้อผิดพลาดในการระบุค่าข้อมูลผิดรูปแบบ except ValueError as e: print( "Error: Input value is invalid. Please input specify input as float.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในการระบุชนิดของตัวแปรไม่ถูกต้อง except TypeError as e: print( "Error: Input value is invalid. Please input specify input as float.") print( str(e) ) sys.exit(1) # ดักจับข้อผิดพลาดในรูปแบบอื่นๆ นอกเหนือจากที่ระบุข้างต้น except Exception as e: print( str(e) ) sys.exit(1) # เรียกใช้งานฟังก์ชัน input() เพื่อทำการขอรับข้อมูลความเร็วต้น, ความเร่งคงที่ # เวลาที่ใช้สังเกตุการณ์ จากทาง console u_input = input("Input initial velocity(u): ") a_input = input("Input constant acceleration(a): ") t_input = input("Input total time(t): ") # ทำการแปลงข้อมูลความเร็วต้นให้เป็นข้อมูลชนิดตัวเลขทศนิยม u = convert_to_float(u_input) # 0 m/s # ทำการแปลงข้อมูลความเร่งคงที่ให้เป็นข้อมูลชนิดตัวเลขทศนิยม a = convert_to_float(a_input) # 4 m/s^2 # ทำการแปลงข้อมูลเวลาที่ใช้ในการสังเกตุการณ์ให้เป็นข้อมูลชนิดตัวเลขจำนวนเต็ม t = convert_to_int(t_input) # second # ทำการสร้างข้อมูลช่วงเวลาจากเวลาวินาทีที่ 0 ถึงวินาทีที่ทำการระบุ time_range = range(t+1) # ทำการคำนวณเพื่อสร้างชุดข้อมูลของระยะทางที่เคลื่อนที่ได้ในแต่ละช่วงเวลา # จากข้อมูลเวลา, ความเร็วต้น และความเร่งคงที่ที่ทำการระบุ distance_by_time = [] for second in time_range: s = calculate_distance(u, a, second) distance_by_time.append( s ) # นำข้อมูลระยะทางที่เคลื่อนที่ได้ และช่วงเวลามาพล๊อตเป็นข้อมูลในรูปแบบกราฟเส้น plt.plot(time_range, distance_by_time) plt.xlabel('time(second)') plt.ylabel('distance(metre)') title_text = "Distances by time with known parameters(u, a, t)\n u={}, a={}, t={}".format(u, a, t) plt.title(title_text) plt.show() # ทำการเขียนข้อมูลที่ถูกสร้างขึ้นลงไฟล์ชื่อ data.txt try: # ทำการเปิดไฟล์เพื่อจะเขียนข้อมูล f = open('data.txt', 'w', encoding='utf-8') # เตรียมข้อมูลระยะทางที่คำนวณได้ข้อมูลที่ถูกป้อนเข้ามาทาง console ในรูปแบบ JSON เพื่อเขียนลงไฟล์ data = {'initial_velocity': u, 'acceleration':a, "distance_at_time":[]} # ทำการเพิ่มข้อมูลระยะทางที่วัตถุเคลื่อนที่ได้เมื่อเวลาผ่านไป for idx in range(len(time_range)): item = {'time': time_range[idx], 'distance': distance_by_time[idx]} data["distance_at_time"].append(item) # ทำการแปลงข้อมูลจาก JSON ให้อยู่ในรูปแบบข้อความเพื่อเตรียมเขียนลงไฟล์ json_txt = json.dumps(data, ensure_ascii=False, indent=4) # ทำการเขียนข้อมูลลงไฟล์ f.write(json_txt) finally: # ทำการปิดไฟล์ที่ถูกเปิดใช้งาน โดยคำสั่งนี้จะถูกเรียกใช้งานเสมอไม่ว่าคำสั่งในบล๊อก try จะเกิดข้อผิดพลาดหรือไม่ f.close()จากตัวอย่าง โปรแกรมจะขอรับข้อมูลของความเร็วต้น, ความเร่งคงที่และเวลาที่สังเกตุการณ์จากทาง console จากนั้นจะทำการตรวจสอบข้อมูลดังกล่าวว่าอยู่ในรูปแบบที่ถูกต้องหรือไม่
หากเป็นข้อมูลในรูปแบบที่ถูกต้อง โปรแกรมจะทำการสร้างข้อมูลของระยะทางที่วัตถุเคลื่อนที่ได้ในแต่ละช่วงเวลา ตามข้อมูลที่ระบุ แล้วจึงใช้ข้อมูลดังกล่าวในการพล๊อตออกมาเป็นกราฟเส้น
แต่หากข้อมูลดังกล่าวอยู่ในรูปแบบที่ไม่ถูกต้อง โปรแกรมดำเนินการคำสั่งที่กำหนดไว้เมื่อเกิดข้อผิดพลาด โดยทำการแจ้งรายละเอียดข้อผิดพลาดทีอ่านแล้วเข้าใจได้ง่ายแล้วหยุดการทำงานของโปรแกรม
จากข้อมูลที่เราสร้างขึ้นมาข้างต้น เราจะเขียนคำสั่งเพิ่มเติมเพื่อเขียนข้อมูลดังกล่าวลงไปในไฟล์เพื่อเก็บไว้ใช้งานต่อไป แต่เนื่องจากระหว่างขั้นตอนหลังจากทำการเปิดไฟล์ แล้วทำการเขียนข้อมูลลงไฟล์นั้นอาจจะมีข้อผิดพลาดเกิดขึ้นได้ เราจึงมีการเขียนคำสั่งปิดไฟล์เพื่อคืนทรัพยาการให้ระบบในบล๊อก finally ด้วยเพื่อให้แน่ใจว่าทุกครั้งที่มีการเปิดไฟล์ขึ้นมาใช้งาน ไม่ว่าจะมีข้อผิดพลาดเกิดขึ้นหรือไม่จะมีการปิดไฟล์นี้เสมอ
ถ้าโปรแกรมสามารถบันทึกไฟล์ได้โดยไม่มีข้อผิดพลาด ข้อมูลที่ถูกบันทึกในไฟล์ “data.txt” จะอยู่ในรูปแบบ
{ "initial_velocity": 15.0, "acceleration": 4.0, "distance_at_time": [ { "time": 0, "distance": 0.0 }, { "time": 1, "distance": 17.0 }, { "time": 2, "distance": 38.0 }, { "time": 3, "distance": 63.0 }, { "time": 4, "distance": 92.0 }, { "time": 5, "distance": 125.0 }, { "time": 6, "distance": 162.0 }, { "time": 7, "distance": 203.0 }, { "time": 8, "distance": 248.0 }, { "time": 9, "distance": 297.0 }, { "time": 10, "distance": 350.0 }, { "time": 11, "distance": 407.0 }, { "time": 12, "distance": 468.0 }, { "time": 13, "distance": 533.0 }, { "time": 14, "distance": 602.0 }, { "time": 15, "distance": 675.0 }, { "time": 16, "distance": 752.0 }, { "time": 17, "distance": 833.0 }, { "time": 18, "distance": 918.0 }, { "time": 19, "distance": 1007.0 }, { "time": 20, "distance": 1100.0 }, { "time": 21, "distance": 1197.0 }, { "time": 22, "distance": 1298.0 }, { "time": 23, "distance": 1403.0 }, { "time": 24, "distance": 1512.0 }, { "time": 25, "distance": 1625.0 }, { "time": 26, "distance": 1742.0 }, { "time": 27, "distance": 1863.0 }, { "time": 28, "distance": 1988.0 }, { "time": 29, "distance": 2117.0 }, { "time": 30, "distance": 2250.0 } ] }โดยรูปแบบข้อมูลจะคงเดิม แต่ตัวข้อมูลจะเปลี่ยนแปลงไปขึ้นอยู่กับข้อมูลที่ป้อนเข้าไปให้ระบบในครั้งนั้นๆ
