Tag Archives: python

วิทย์ม.ต้น: เริ่มรู้จักภาษา Python

วันนี้เด็กๆม.ต้นได้เริ่มรู้จักภาษาคอมพิวเตอร์อีกหนึ่งภาษาครับ ชื่อว่าภาษาไพธอน (Python) เป็นภาษาที่เรียนรู้ได้ค่อนข้างง่ายและใช้ได้ทั่วไปครับ วันนี้เราหัดใช้แบบออนไลน์กันที่ repl.it  ซื่งเป็นเว็บไซต์ใช้ทดลอง เรียนรู้ และสร้างผลงานด้วยภาษาคอมพิวเตอร์หลายๆภาษาครับ เข้าไปแล้วก็กดสมัคร (Sign up) แล้วเลือกภาษา Python ครับ

เว็บ repl.it ครับ
เว็บ repl.it ครับ

ชื่อเว็บ repl.it มาจากตัวย่อของ Read-Evaluate-Print-Loop ครับ คือจะให้เราพิมพ์คำสั่งเข้าไปแล้วมันก็จะอ่าน (Read) แล้วมันก็จะคำนวณผลจากคำสั่งที่เราใส่เข้าไป (Evaluate) และพิมพ์ผลลัพธ์ให้เราดู (Print) และก็กลับไปรอรับคำสั่งเราอีก (Loop) 

 พอสมัครสมาชิกและเลือกภาษา Python แล้ว หน้าจอจะมีหน้าตาประมาณนี้ครับ:

ช่องดำๆด้านขวาคือส่วนที่เราป้อนคำสั่งต่างๆให้คอมพิวเตอร์คำนวณให้เราครับ ช่องขาวๆตรงกลางเป็นที่เก็บคำสั่งเยอะๆไว้ด้วยกันเป็นโปรแกรมเพื่อว่าเวลาเรากลับเข้ามาใหม่เราจะได้เรียกใช้ได้ เราสามารถพิมพ์โปรแกรมของเราในช่องกลางแล้วกดปุ่ม run ด้านบนแล้วดูผลลัพธ์ในช่องสีดำด้านขวาครับ

จากนั้นเด็กๆลองพิมพ์คำสั่งให้ Python คิดเลขให้ เอาตัวอย่างมาจากเว็บ Learn X in Y minutes ส่วนภาษา Python:

จาก https://learnxinyminutes.com/docs/python3/  ครับ
จาก https://learnxinyminutes.com/docs/python3/ ครับ

ต่อไปเด็กๆก็เข้าไปทำแบบฝึกหัดและเรียนรู้เองด้วย Auto-Graded Course with Solutions ภาษา Python โดย Vitaly Pavlenko ครับ (มีคอร์สอื่นๆที่ https://repl.it/community ด้วยนะครับ)

เวลาเด็กๆไม่เข้าใจแบบฝึกหัด เขาจะไปอ่านความรู้เพิ่มเติมที่ https://snakify.org/en/  โดยที่ในแต่ละแบบฝึกหัดจะมีลิงก์ไปส่วนต่างๆที่ควรไปอ่านครับ เช่นแบบฝึกหัดอันแรกๆก็จะให้ไปอ่านที่ https://snakify.org/lessons/print_input_numbers/ เป็นต้นครับ หน้าตาเป็นประมาณนี้ครับ:

ตัวอย่างหน้าความรู้เพิ่มเติมครับ: https://snakify.org/en/lessons/print_input_numbers/
ตัวอย่างหน้าความรู้เพิ่มเติมครับ: https://snakify.org/en/lessons/print_input_numbers/

ผมให้เด็กๆไปทยอยทำแบบฝึกหัดทั้งหลายให้หมดภายในสองสัปดาห์นี้ครับ เป็นการทำความคุ้นเคยกับภาษา Python และหัดอ่านและค้นคว้าด้วยภาษาอังกฤษไปด้วย

คำนวณเลข Fibonacci ด้วย Python แบบไม่ช้านัก

ผมเห็นหัวข้อ blog post ว่า “Holy Shmoly, Ruby 1.9 smokes Python away!” ก็เลยกดเข้าไปดู ปรากฎว่าผู้เขียนได้จับเวลาการคำนวณเลข Fibonacci (0, 1, 1, 2, 3, 5, 8, 13, 21, … ) หรือเลขตัวที่ n เท่ากับผลรวมของตัวที่ n-1 กับ n-2 และ Python ใช้เวลาประมาณ 30 วินาที ขณะที่ Ruby 1.9.0 ใช้ประมาณ 12 วินาที ในการคำนวณตัวเลข 35 ตัวแรก

โปรแกรมที่ใช้คำนวณหน้าตาแบบนี้:

def fib(n):
if n == 0 or n == 1:
return n
else:
return fib(n-1) + fib(n-2)

for i in range(36):
print "n=%d => %d" % (i, fib(i))

ผมลองรันโปรแกรมบนเครื่องผมก็ใช้เวลา 36 วินาที ผมรู้สึกประหลาดใจเนื่องจากไม่คิดว่าจะใช้เวลานานอย่างนี้เลยคิดถึงสาเหตุที่ทำให้ใช้เวลานาน สาเหตุที่ผมพบมีดังนี้:

1. ตัวแปรในภาษา Python เป็นตัวแปรที่มี run-time type information ที่ CPU ไม่สามารถทำการคำนวณโดยตรงได้เหมือนตัวแปรพวก int หรือ double ในภาษา C

เวลา Python interpreter ทำการคำนวณ จะต้องหาว่าตัวแปรเป็นประเภทอะไรก่อน จึงจะเลือกคำสั่ง CPU ที่ถูกมาใช้

2. จะเห็นได้ว่าฟังค์ชัน fib(n) เป็นฟังค์ชันที่เรียกตัวเอง (หรือ recursive function) คือการคำนวณ fib(n) จะเรียกใช้ fib(n-1) และ fib(n-2) และค่า fib(0), fib(1), …, fib(k) ก็ถูกคำนวณซ้ำซากอยู่บ่อยๆ

ผมก็เลยคิดถึงวิธีที่จะแก้ปัญหาสองข้อนี้ สำหรับสาเหตุข้อแรกเราสามารถใช้เครื่องมือที่เรียกว่า Psyco ซึ่งทำหน้าที่เหมือน JIT (Just-in-Time) compiler ที่แปลงโปรแกรม Python เป็นคำสั่งที่มีประสิทธิภาพสูงของ CPU โดยตรง พอผมเพิ่มสองบันทัด (สีแดง) เข้าไป:

import psyco
psyco.full()


def fib(n):
if n == 0 or n == 1:
return n
else:
return fib(n-1) + fib(n-2)

for i in range(36):
print "n=%d => %d" % (i, fib(i))

เวลาในการคำนวณก็ลดจาก 36 วินาทีเหลือ 2 วินาที

สำหรับสาเหตุที่สองเราแก้ได้โดยไม่คำนวณอะไรซ้ำๆ โดยเก็บค่าที่เคยคำนวณไว้ไม่ต้องทำใหม่ทุกๆครั้ง (เทคนิคประเภทนี้เรียกว่า Caching หรือ Memoization):

class cachedFib:
def __init__(self):
self.f = {}
self.f[0] = 0
self.f[1] = 1

def fib(self,n):
if n in self.f:
return self.f[n]
else:
self.f[n] = self.f[n-1]+self.f[n-2]
return self.f[n]

cf = cachedFib()
for i in range(36):
print "n=%d => %d" % (i, cf.fib(i))

เวลาในการคำนวณก็ลดจาก 36 วินาทีเหลือ 0.08 วินาที

— – —- – —– ———
P.S.
1. โปรแกรมสำหรับการคำนวณแบบอื่น (โดยไม่ใช้ recursion และในภาษาอื่นๆ) ดูได้ที่นี่
2. ตาราง Fibonacci 300 ตัวแรก (แถมแยกตัวประกอบ)
3. Fibonacci ตัวที่ 10,000,000
4. สูตรน่าสนใจในการคำนวณเลข Fibonacci