Sep 27, 2013

ไอคอนสกิลโปรแกรมเมอร์

ช่วงนี้อาจารย์สั่งงานเป็นโปรเจคเล็กๆ เพื่อความเข้าใจในฐานข้อมูล ครั้นจะเอาโปรเจคที่มีอยู่แล้วมายำๆ ส่งให้มันน่าเบื่อ ก็กลับไปค้นไอเดียเก่าที่ยังไม่ได้ implement มายำเล่นแทนดีกว่า

เรื่องสนุกของงานนี้คือ ไม่(ลืม)คิดมาก่อนเลยว่าโปรเจคนี้มันต้องมีรูปประกอบเยอะมาก (และสำคัญมากด้วย!) ก็ไม่เป็นไรเพราะได้จับโปรเจคที่อยากทำ ต่อให้ยากแค่ไหนไฟก็ลุกท่วม (ไฟพยายามนะไม่ใช่ไฟลนก้น) จริงมะ

และนี่คือร่างที่สองบนกระดาษ


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

ตอนแรกก็กะว่าจะสแกนรูปไปใช้เลย ติดที่ว่าตอนใช้งานจะตั้งใจให้มันมีทั้งโหมดขาวดำและภาพสี เลยลองลากๆ เมาส์ใน Gimp / Inkscape และพบว่าไม่เวิร์ก ไม้ตายสุดท้ายคือกลับสู่ปากกา โชคดีว่ายืม iPad มาได้เลยจิ้มวาดใน MyScript Memo ครับ



ถ้าเห็นว่าสวยก็เอาไปใช้กันได้เลยจ้า ให้เครดิตพร้อมหลังไมค์มาบอกแค่นี้ก็พอแล้ว ;)

Sep 19, 2013

ริจะฟังเพลงคลาสสิก อย่ายึดติดว่าต้องจินตนาการเห็นต้นไม้ใบหญ้า

ยาวไปไม่(ต้อง)อ่าน: จินตนาการระหว่างฟังเพลงคลาสสิกแล้วสนุกก็ทำไปเถอะ

แตกมาจากบทวิเคราะห์ Moonlight Sonata นะครับ เพื่อไม่ให้มีหลายเรื่องปนกัน

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

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

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

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

ดังนั้นคนที่ฟังแล้วไม่เห็นภาพอะไรก็ไม่ต้องกังวล ส่วนคนที่สั่งห้ามจินตนาการนั้นก็ดูท่าว่าจะกลัวจนเกินเหตุ

จินตนาการกันดีกว่า ใครจะมาเข้าใจผิดก็ช่างเขาเถอะ

Sep 10, 2013

CoffeeScript มหัศจรรย์: ลูกศรเปลี่ยน Scope

JavaScript เป็นภาษา functional ที่คนมักเข้าใจผิดว่ามันเป็น OOP (ด้วยตัว syntax ที่หน้าตาคล้าย C/Java เสียเหลือเกิน) ด้วยความเข้าใจผิดและไม่มี syntax ประกาศ class โดยตรง ทำให้ framework หลายๆ เจ้าพยายาม define syntax นี้กันเอง ตัวอย่างเช่นใน CoffeeScript

class Dog
    constructor: (@name, @owner) ->
        me = $('<button>').addClass('dog').append(@name).click(@bark)
        $('#animals').append(me)
    
    bark: ->
        alert(@name + ': Bark bark. I love you, ' + @owner + '. Bark!')

bone = new Dog('Bonnie', 'Alice')

ดูดีและเหมือนภาษา OOP ทั่วไปเลยทีเดียว นอกจากนี้เมื่อทดสอบบน console จะเห็นว่า bone.bark() แสดงผลลัพท์ที่ถูกต้อง ไม่น่ามีปัญหาอะไร

อย่างไรก็ตาม ด้วยความเป็น dynamic scope ทำให้ฟังก์ชัน bark ไปใช้ scope จาก jQuery แทน ถ้ากดปุ่มจะเห็นว่าคราวนี้มี undefined ในข้อความ (เพราะ me ที่เป็น jQuery object ไม่มี attribute owner)

วิธีแก้แบบ JavaScript จะคล้ายๆ Python คือสร้าง self ที่ชี้กลับมาหาตัวเราจริงๆ แล้วให้ this เป็นแบบ dynamic ตามปรกติ

class Dog
    constructor: (@name, @owner) ->
        self = this
        me = $('<button>').addClass('dog').append(@name).click -> self.bark()
        $('#animals').append(me)

    bark: ->
        alert(@name + ': Bark bark. I love you, ' + @owner + '. Bark!')

ส่วน CoffeeScript มีท่าง่ายกว่านั้น แค่ใช้ fat arrow ก็พอ

class Dog
    constructor: (@name, @owner) ->
        me = $('<button>').addClass('dog').append(@name).click(@bark)
        $('#animals').append(me)

    bark: =>
        alert(@name + ': Bark bark. I love you, ' + @owner + '. Bark!')

ว่าแล้วก็แอบเห็นด้วยกับทวีตนี้ :P