Categories
BYOB

Snap 4.0

Snap หรือ BYOB ในเวอร์ชัน 4.0 อยู่ในรูปแบบของเว็บ ทำให้ไม่ต้องดาวน์โหลดโปรแกรมมาที่เครื่องก่อน ตอนนี้อยู่ในช่วงทดสอบ ใครสนใจสามารถเข้าไปทดลองใช้ได้ที่ http://snap.berkeley.edu/run และยังมีคู่มือฉบับร่าง ให้ลองอ่านก่อนด้วย

Categories
BYOB Programming

ฟังก์ชันที่เรียกต้วมันเอง

ฟังก์ชันที่เรียกต้วมันเอง เป็นฟังก์ชันชนิดหนึ่งเรียกว่า Recursive function ทำไมถึงต้องมีฟังก์ชันชนิดนี้ แล้วมันมีประโยชน์อย่างไร มาหาคำตอบกัน

แนวคิดของฟังก์ชันที่เรียกตัวมันเอง มีให้เห็นในปรากฏการณ์ทางธรรมชาติเหมือนกัน เช่น รูปร่างของเกล็ดหิมะ ต้นไม้ ใบเฟิร์น หรือ เปลือกหอย เป็นต้น รูปร่างของพวกมันจะมีหน้าตาเหมือนกัน แต่จะมีขนาดไม่เท่ากัน รูปแบบเหล่านี้เรียกว่า แฟร็กทัล (Fractal)

ในการคำนวณบางอย่าง เช่น การหาค่า factorial 5! = 5 x 4 x 3 x 2 x1 = 120 สามารถเขียนได้อีกรูปแบบหนึ่งคือ 5! = 5 x 4! ซึ่ง 4! = 4 x 3! , 3! = 3 x 2!, 2! = 2 x 1! เราจะเห็นรูปแบบการเรียกตัวมันเองเกิดขึ้นไปเรื่อย ๆ ด้วยตัวเลขที่ลดลงจนกระทั่ง 1! = 1 ซึ่งเป็นรูปแบบที่ไม่สามารถเรียกตัวมันเองได้อีกแล้ว

จากตัวอย่างข้างต้น จะเห็นได้ว่าการสร้างฟังก์ชันเรียกตัวมันเอง ต้องมีเงื่อนไขอยู่ 2 อย่างคือ

  1. ต้องมีรูปแบบพื้นฐานที่ไม่สามารถเรียกตัวมันเองได้ ซึ่งเป็นวิธีหยุดการทำงานของฟังก์ชันเรียกตัวมันเอง มิฉนั้น ฟังก์ชันจะทำงานไปเรื่อย ๆ ไม่มีวันจบ
  2. การเรียกตัวมันเองต้องมีแนวโน้มที่จะไปสู่รูปแบบพื้นฐาน ซึ่งอาจมีมากกว่า 1 แบบก็ได้

การเขียนโปรแกรมด้วยฟังก์ชันแบบนี้ จะทำให้ได้โปรแกรมที่สั้นและเข้าใจได้ง่าย (รึเปล่า) ซึ่งใน BYOB สามารถทำได้เช่นกัน มาลองดูกันคราวหน้านะครับ

Categories
BYOB Programming

หลักการเขียนโปรแกรมใน BYOB ตอนที่ 2

ฟังก์ชัน square สามารถวาดรูปสี่เหลี่ยม 100 x 100 ได้ขนาดเดียวทุกคร้้งที่เรียกใช้ฟังก์ชันนี้ ซึ่งไม่ค่อยยืดหยุ่น ถ้าเราต้องการสี่เหลี่ยมขนาดอื่นละ ทำได้ไหม ตามหลักการแล้ว คือการทำ Generalization ให้กับฟังก์ชัน โดยการส่งผ่านข้อมูลให้กับฟังก์ชัน เพื่อให้ฟังก์ชั่นทำงานได้ยืดหยุ่นขึ้น ไม่เฉพาะเจาะจงอยู่กับการทำงานเพียงแบบเดียว (วาดรูปสี่เหลี่ยม 100 x 100) เช่น ถ้าต้องการวาดสี่เหลี่ยมขนาดอื่นๆ ทำได้ด้วยการให้ข้อมูลขนาด (size) ให้กับฟังก์ชัน square เพื่อให้ได้สี่เหลี่ยมตามขนาดที่ใส่เข้าไปในฟังก์ชัน square (size)

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

โดยสรุป ระดับของการทำ Generalization ให้กับฟังก์ชันต้องดูความเหมาะสม ฟังก์ชันที่ทำงานได้สารพัดอย่างย่อมมีความซับซ้อนตามไปด้วย

การใส่ข้อมูลให้กับฟังก์ชัน ทำให้หน้าตาของมัน (function interface) เปลี่ยนไป ฟังก์ชันด้านซ้ายคือ ฟังก์ชันวาดรูปสี่เหลี่ยมจัตุรัสได้หลายขนาด “square (size) steps” กับฟังก์ชันวาดรูปสี่เหลี่ยมผืนผ้าตามขนาดกว้าง x ยาว  “square (width) steps (height) steps” (ข้อมูลเข้าจะอยู่ในวงเล็บ) 2 ฟังก์ชันนี้มีหน้าตาไม่เหมือนกัน จำนวนข้อมูลเข้าไม่เท่ากัน การทำงานภายในฟังก์ชันก็ไม่เหมือนกัน แต่ยังมีหลักการทำงานคล้ายกันคือ วาดรูปสี่เหลี่ยม

โดยทั่วไป หน้าตาฟังก์ชันทำให้เรารู้คราวๆ ว่ามันสามารถทำอะไรได้บ้าง เริ่มจาก ชื่อของฟังก์ชัน square บ่งบอกว่าเกี่ยวกับสี่เหลี่ยมจัตุรัส เมื่อมีข้อมูล size พอเดาได้ว่าเกี่ยวกับขนาดหรือด้านของสี่เหลี่ยม ส่วน steps ไม่ใช่ข้อมูลเข้า เป็นเพียงข้อมูลเพิ่มเติม (ไม่มีก็ได้) บอกหน่วยของขนาด (ใช้ steps เพราะสี่เหลี่ยมเกิดจากการเดินของตัวละคร Alonzo) ส่วนอีกฟังก์ชันหนึ่ง ใช้ชื่อ square เหมือนกันแต่มีข้อมูลเข้าสองตัว width กับ height บอกขนาดกว้างกับยาวของสี่เหลี่ยมผืนผ้า (จริงๆ ควรใช้ชื่อ rectangle มากกว่า)

ข้อมูลเข้า เช่น size เรียกว่าพารามิเตอร์ (parameter) เมื่ออยู่ในฟังก์ชัน จะเป็นตัวแปรชนิดหนึ่ง ที่รู้จักเพียงภายในของฟังก์ชันนั้นๆ (local variable) ถึงแม้จะมีตัวแปรชื่อเหมือนกันภายนอกฟังก์ชัน ก็จะถือว่าเป็นตัวแปรคนละตัวกัน

เมื่อฟังก์ชันถูกเรียกใช้พร้อมกับข้อมูลเข้า เช่น ต้องการวาดสี่เหลี่ยมจัตุรัสขนาด 50 x 50 ก็ต้องเรียกใช้ฟังก์ชัน “square (50) steps” ตัวเลข 50 เรียกว่าอาร์กิวเมนต์ (argument) เป็นข้อมูลที่จะถูกส่งผ่านฟังก์ชัน เชื่อมเข้ากับตัวแปรพารามิเตอร์ size ภายในฟังก์ชัน square ซึ่งข้อมูลนี้ (50) สามารถนำไปใช้ต่อได้ภายในฟังก์ชัน square

หน้าตาของบล็อกหรือฟังก์ชัน อาจไม่เพียงพอต่อการนำมันไปใช้งาน บางคร้้งต้องอ่านข้อมูลเพิ่มเติม เช่น อ่านข้อมูลความช่วยเหลือ (help) หรืออ่านคู่มือการใช้งานฟังก์ชัน (API: application program interface) ซึ่งจะมีข้อมูลรายละเอียดการใช้งานในแต่ละฟังก์ชัน

Categories
BYOB

หลักการเขียนโปรแกรมใน BYOB ตอนที่ 1

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

การสร้างฟังก์ชันเป็นการลดความซับซ้อน และซ่อนรายละเอียดของการทำงาน ให้อยู่ในรูปของชื่อฟังก์ชันแทน ในทางทฤษฎีเรียกกระบวนการนี้ว่า แอ็บสแทรกชัน (Abstraction)

การสร้างฟังก์ชัน หรือ การนิยามฟังก์ชัน เช่นฟังก์ชัน square เป็นการผูกชื่อของฟังก์ชัน (square) กับ ส่วนคำสั่งการทำงานของฟังก์ชัน (วาดรูปสี่เหลี่ยมขนาด 100 x 100)

เมื่อนิยามฟังก์ชัน square ขึ้นมาแล้ว ชื่อฟังก์ชันจะแทนแนวคิดที่อยู่เบื้องหลัง (การวาดรูปสี่เหลี่ยม) เมื่อใดที่ต้องการวาดรูปสี่เหลี่ยม ก็สามารถเรียกใช้งานฟังก์ชันผ่านการเรียกชื่อฟังก์ชัน square (function call) ส่วนการทำงานจริงจะอยู่ที่ตัวฟังก์ชัน (function body) ซึ่งมีคำสั่งต่างๆ ตั้งแต่จรดปากกา เดินเป็นรูปสี่เหลี่ยมพร้อมกับลากเส้นไปด้วย

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

Categories
BYOB

ใส่ข้อมูลให้บล็อก square

ณ ขณะนี้บล็อก square สามารถวาดสี่เหลี่ยมได้เพียงขนาดเดียว (100 x 100) ทำอย่างไรถึงจะกำหนดขนาดสี่เหลี่ยมได้เอง เราทำได้โดยการใส่ข้อมูลกำหนดความยาวของด้านสี่เหลี่ยมให้กับบล็อก square ซึ่งจะทำให้ Alonzo เดินตามค่าที่กำหนดให้ แทนที่จะเป็น 100 เพียงอย่างเดียว

ก่อนอื่นนำเอา Block editor ออกมาก่อน ด้วยการคลิกขวาที่บล็อก square จากนั้นคลิกเลือก edit

เมื่อนำเมาส์มาวางเหนือบล็อกที่กำลังสร้างอยู่ ณ ขณะนี้มีข้อมูล square อันเดียวเป็นชื่อของบล็อกนี้ เมื่อเอาเมาส์ชี้ที่ square จะมีเครื่องหมายบวก (+) ปรากฏทั้งสองด้าน สามารถคลิกเพื่อสร้างข้อมูลเพิ่มได้อีกเหมือนกัน แต่ตำแหน่งของมันจะขึ้นกับข้อมูลที่เมาส์ชี้อยู่ (square ) ถ้าคลิกที่ตัว square เอง จะปรากฏหน้าต่างบอกรายละเอียดของข้อมูล square และถ้าไม่ต้องการข้อมูลนี้แล้ว สามารถลบทิ้งได้ ด้วยการคลิกปุ่ม Delete

เมื่อคลิกเครื่องหมายบวกอันใดอันหนึ่งจะปรากฏหน้าต่างให้สร้างชื่อข้อมูลเข้า และสามารถเลือกชนิดของข้อมูลได้ 2 แบบ คือ จะเป็นเพียงชื่อ (Title text) ใช้สื่อสารเท่านั้น หรือ จะเป็นชื่อของตัวแปร (Input name) ที่สามารถนำมาใช้ในสคริปต์ของบล็อกนี้ได้

 

เพื่อสร้างบล็อก square ให้สามารถกำหนดขนาดของด้านสี่เหลี่ยมได้ และให้บล็อกนี้สื่อกับผู้ใช้ว่าข้อมูลที่จะใส่เข้าไป เป็นข้อมูลอะไร เราต้องการข้อมูล 2 ตัว ทั้งสองแบบ คือ เลือก Input name สำหรับตัวแปร size ใช้กำหนดขนาดด้านของสี่เหลี่ยม และ เลือก Title text สำหรับข้อมูล steps ใช้บอกหน่วยของตัวแปร size

ขนาดของด้านสี่เหลี่ยม เกิดจากการเคลื่อนที่ของ Alonzo ดังนั้นเราต้องนำตัวแปร size มาใส่ในบล็อก move ด้วยการลากตัวแปร size ที่สร้างขึ้นมาใหม่ในบล็อก square มาใส่ได้เลย (เหมือนกับการลากบล็อกจากบล็อกหมวดต่างๆ ใน Scratch)

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