Tag Archives: python

วิทย์ม.ต้น: ม.1 หัดเขียนฟังก์ชั่นในไพธอน, ค่าพายมาจากการบวกซ้ำๆได้ด้วย!

สัปดาห์นี้เด็กๆม.1 รู้จักเขียนฟังก์ชั่นเพื่อทำงานซ้ำๆหรืองานคล้ายๆกันครับ เริ่มจากการสั่งให้คอมพิวเตอร์บวกเลขให้เรา 1+2+3+…+1,000,000:

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

แบบฝึกหัดในห้องคือให้เด็กๆหัดเขียนฟังชั่นที่รวมกำลังสอง และกำลังสามของตัวเลขต่างๆกันดู

สักพักเด็กๆก็เขียนเป็นฟังก์ชั่นหน้าตาประมาณนี้ (ผมกำหนดชื่อฟังก์ชั่นไว้เป็น sumsqr และ sum3rd ย่อมาจาก sum of square คือบวกเลขยกกำลังสอง และ sum of 3rd power คือบวกเลขยกกำลังสาม):

เราทดลองพิมพ์ค่า n, ผลรวมจาก 1 ถึง n, ผลรวมกำลังสองของ 1 ถึง n, และ ผลรวมกำลังสามของ 1 ถึง n กันดู:

เมื่อผมทำให้เด็กประหลาดใจที่ผมสามารถหาผลรวมของกำลังสามในใจได้เร็วกว่าที่เด็กๆคิด ผมก็บอกเด็กๆว่ามันมีความสัมพันธ์กันอยู่ที่ว่า (1 + 2 + 3 + … + n)2 = 13 + 23 + 33 + … + n3 และ เราหา (1 + 2 + 3 + … + n) ได้ง่ายเพราะเหมือนการจับคู่หัวท้ายแล้วคูณด้วยจำนวนคู่ = 1/2 n (n+1)

ผมถามเด็กๆว่าถ้าเราต้องการคำนวณยกกำลังอื่นๆอีกจะทำอย่างไร ต้องเข้าไปสร้างฟังก์ชั่นใหม่ๆเรื่อยๆไหม ปรากฎว่าเราสามารถสร้างฟังก์ชั่นที่รับค่ายกกำลัง และค่าที่ว่าจะให้รวมถึงแค่ไหนก็สามารถใช้คำนวณยกกำลังอื่นๆได้เลย ไม่ต้องสร้างฟังก์ชั่นใหม่ๆสำหรับกำลังใหม่ๆ หน้าตาก็จะเป็นประมาณนี้:

ผมลองรวมยกกำลัง -2 ดู ให้คำนวณ 1/12 + 1/22 + 1/32 + … + 1/1,000,0002 ดูปรากฎว่าใกล้เคียงกับค่า π2/6 มาก:

เด็กๆก็ตื่นเต้นว่าค่า π มาเกี่ยวข้องกับผลรวมอย่างนี้ได้อย่างไร จริงๆแล้วเมื่อกำลังเป็นเลขคู่ที่เป็นลบจะมีความเกี่ยวข้องกับ Riemann zeta function ที่มีคนค้นพบว่ามีค่า π ติดอยู่ดังนี้ครับ:

จาก https://en.wikipedia.org/wiki/Particular_values_of_the_Riemann_zeta_function

เนื่องจากเราไม่สามารถบวกเลขเป็นอนันต์เทอมได้ เราก็บวกไปสิบล้านเทอมเป็นการประมาณเทียบดูกับค่าข้างบนก็ใกล้เคียงกันครับ:

วิทย์ม.ต้น: ให้คอมพิวเตอร์คำนวณความน่าจะเป็น และใช้วิธีสุ่ม (sampling) เมื่อปัญหาใหญ่เกิน

(ลิงก์ดาวโหลดอยู่ด้านล่าง)

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

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

เราก็สามารถให้คอมพิวเตอร์สร้างรูปแบบขนม 8 กล่องที่เป็นได้ทั้งหมด และนับว่ารูปแบบไหนมีตุ๊กตาครบ 4 แบบดังนี้:

ผมให้เด็กๆหัดใช้ all() และ any() และ list comprehension ด้วย หน้าตาโปรแกรมก็อออกมาประมาณนี้:

ถ้าเราอยากรู้ว่าโอกาสได้รางวัลเป็นเท่าไรเมื่อซื้อมา 4 กล่อง เราก็สามารถแก้ไขโปรแกรมเราได้ประมาณนี้:

ถ้าเราอยากคำนวณความน่าจะเป็นเมื่อซื้อจำนวนกล่องอื่นๆโดยไม่ต้องเข้าไปแก้ไขโปรแกรมตลอด เราสามารถใช้ itertools.product() ได้:

ถ้าเราพยายามคำนวณสำหรับจำนวนกล่องมากๆ วิธีแจกแจงจำนวนกล่องที่เป็นไปได้ทั้งหมดจะทำได้ยาก เพราะจำนวนแบบที่เป็นไปได้เพิ่มขึ้นรวดเร็วมากเมื่อจำนวนกล่องเพิ่ม (เท่ากับ 4N เมื่อ N คือจำนวนกล่อง) ถ้าเราซื้อ 20 กล่อง จำนวนที่เป็นไปได้จะเป็นล้านล้านแบบ (เลข 12 หลัก) ถ้าซื้อ 30 กล่อง จำนวนที่เป็นไปได้จะเป็นล้านล้านล้านแบบ (เลข 18 หลัก) เราต้องใช้วิธีอื่นประมาณความน่าจะเป็น

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

เมื่อวาดกราฟความน่าจะเป็น vs. จำนวนกล่องก็จะได้ภาพแบบนี้:

ผมบันทึกตัวอย่างเหล่านี้ไว้ให้เด็กๆและผู้สนใจเข้ามาดูทบทวนโดยสามารถโหลด Jupyter Notebook ได้ที่นี่ หรือดูออนไลน์ได้ที่นี่นะครับ

วิทย์ม.ต้น: ให้คอมพิวเตอร์แก้ปัญหาสมการเชิงเส้นให้เรา

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

คราวนี้ผมให้แบบฝึกหัดเด็กๆไปหัดเขียนฟังก์ชันว่าเส้นตรงสองเส้นตัดกันตรงไหน หน้าตาจะออกมาประมาณนี้ครับ:

การหาว่าเส้นตรงสองเส้นตัดกันตรงไหนเป็นวิธีแก้ปัญหาสมการเชิงเส้นในสองตัวแปรครับ ถ้ามีตัวแปรมากกว่าสองตัว รูปแบบคำตอบจะดูยุ่งยาก ผมให้เด็กๆรู้จักเข้าไปใช้ Wolfram Alpha หาคำตอบพวกนั้น (ยกตัวอย่างเช่นสามตัวแปรเป็นอย่างนี้)

ปัญหาที่น่าสนใจจะมีตัวแปรเยอะกว่าที่ทำด้วยมือในโรงเรียนมากครับ ตัวแปรจะเป็นร้อยเป็นพันถึงเป็นล้านตัว ต้องให้คอมพิวเตอร์ช่วยทำ ผมให้เด็กๆเห็นวิธีตรงไปตรงมาเหมาะกับให้คอมพิวเตอร์ทำชื่อ Gaussian Elimination (หรืออีกชื่อว่า Gauss -Jordan Elimination) หาคำตอบแทนสูตรสำเร็จรูป ดูตัวอย่างได้ที่คลิปนี้ หรือ คลิปนี้

ถ้าเด็กๆสนใจ ก็สามารถใช้ไพธอนช่วยแก้ปัญหาพวกนี้ได้ด้วย numpy.linalg.solve() ครับ หน้าตาอาจเป็นแบบนี้ครับ:

ผมบันทึกตัวอย่างเหล่านี้ไว้ให้เด็กๆและผู้สนใจเข้ามาดูทบทวนโดยสามารถโหลด Jupyter Notebook ได้ที่นี่ หรือดูออนไลน์ได้ที่นี่นะครับ