Erlang binary pattern matching

ในโปรแกรมที่ผมกำลังทำอยู่ตอนนี้ จำเป็นต้องอ่านเท็กไฟล์ขนาดใหญ่เข้ามา แล้วเอามาแบ่งออกเป็นส่วนย่อยๆก็คือเอามา split นะแหละครับ แล้วทีนี้เวลาอ่านข้อมูลเอามาจากไฟล์ใน erlang จะใช้ฟังก์ชัน read_file จาก module file โดยผลลัพธ์ที่ได้จะอยู่ในรูปแบบประมาณนี้

{ok, <<"attaccggttaaccttgg">>}

คือได้ tuple ตัวแรกเป็น ok คืออ่านได้ปกติ ตัวหลังคือข้อมูลที่เป็นแบบ binary ใน erlang ข้อมูลแบบ binary จะอยู่ในสัญลักษณ์ <<>>

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

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

ข้อมูลแบบ binary จะอยู่ใน pattern แบบนี้

<<"abc">>

ตัวอย่างคือมีข้อมูลอยู่ 3 bytes (24 bits แต่ละตัวอักษรใช้ 1 byte ใน 1 byte มี 8 bits)

ถ้าเราต้องการ binding ค่าของ a ออกมาจะทำได้แบบนี้

<> = <<"abc">>.

คือตรงส่วน pattern เราก็ทำให้อยู่ในฟอร์มของ binary มี <<>> ครอบเหมือนกัน ผลที่ได้คือ A จะถูก bound ค่าของ 8 bits แรกใน binary <<"abc">> ถ้าเราสั่ง

A.
97

จะเห็นว่าจะได้ค่า 97 ก็คือค่ารหัส ASCII ของอักษร a นั่นเอง ส่วน Rest/binary เป็นการบอกว่า Rest คือส่วนที่เหลือทั้งหมด และส่วนที่เหลือทั้งหมดนี้เป็น binary ทั้งก้อน ผลที่ได้คือ Rest จะเท่ากับ <<"bc">> นั่นเอง

Rest.
<<"bc">>

ถ้าเราต้องการนำ A กลับไปเป็น binary อีกครับก็สามารถทำได้โดยใช้ <<>> ครอบ A
<>.
<<"a">>

นอกจากนี้ เราสามารถกำหนดได้ว่าเราจะทำการ matching ค่าจาก binary เป็นจำนวนกี่บิต จะเห็นว่าปกติเป็น 8 บิต ตัวอย่างเช่น เราต้องการดึงค่าจาก <"abc"> ออกมา 2 ตัวหน้า คือ "ab" จะเห็นว่าตัวอักษรมีทั้งหมด 2 ตัวแสดงว่าใช้ทั้งหมด 16 bits เราสามารถ match ได้ด้วยวิธีแบบนี้

<> = <<"abc">>.

ผลที่ได้คือ Rest จะเหลือ

<<"c">>

ส่วน A จะได้ค่าเป็น

24930

คือเป็นค่าที่เกิดจาก bit ของ $a และ $b มาต่อกัน
ถ้าเราต้องการเอา A ไปสร้างเป็น binary ที่มี "ab" ทำได้โดยเอา A ไปครอบด้วย <<>> เหมือนเดิม แต่เราต้องใส่รายละเอียดจำนวนบิตเหมือนเดิมกับตอนที่เอา binding ค่าออกมาด้วยเช่น

<>.
<<"ab">>

ตัวอย่างที่ผมเอาไปใช้ใน my_split ฟังก์ชันที่แบ่ง binary แต่ผมจะแบ่งแบบคาบเกี่ยวกัน เช่น แบ่ง 2000 แต่หักออก 1000 แล้วแบ่งอีก 2000

-module(my_binary).
-export([my_split/2]).

my_split(BinList,N) -> my_split(BinList,N,[]).

my_split(<<>>,_,R) -> R;
my_split(BinList,N,R) -> Length = N*8,
                         BinListLength = bit_size(BinList),
                         CheckLength = Length =< BinListLength,

                         if CheckLength == true ->
                                        <> = BinList,
                                        DropLength = Length div 2,
                                        <<_:DropLength,DropRest/binary>> = BinList,
                                        my_split(DropRest,N,[<>|R]);
                                   true ->
                                        <> = BinList,
                                        my_split(Rest,N,[<>|R])
                         end.

กำหนดพาธของ ssl certificates ให้ curl

กำลังหัดเขียน facebook application เล่นๆ ก็ลองเอาโค้ดตัวอย่างที่มีให้มาลองแต่แล้วพอทดสอบแล้วเจอกับ error แบบนี้

Fatal error: Uncaught CurlException: 60: error setting certificate verify locations: CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath:
none thrown in /var/www/vhosts/iporsut.com/httpdocs/tkliwapp/facebook-php-sdk/src/facebook.php on line 511

นั่นคือไม่สามารถเข้าถึงไฟล์ /etc/pki/tls/certs/ca-bundle.crt ได้ พอลองเช็คดูแล้วไม่มีไฟล์ ca-bundle.crt อยู่ตามพาธนี้ ก็เลยลองหาด้วย google ดูก็เห็นว่ามันอยู่ในอีกพาธนึงคือ /usr/share/ssl/certs/ca-bundle.crt

ก็ลองหาวิธีกำหนดว่าจะทำยังไงให้ curl มันไปอ่านไฟล์ ca-bundle.crt ตามพาธที่เราต้องการ ก็ไปเจอว่าต้องกำหนดค่าให้กับ option ตัวนี้

CURLOPT_CAINFO => '/usr/share/ssl/certs/ca-bundle.crt'

แต่ว่าพาธนี้ก็ยังติดเรื่อง permission อีกก็เลยต้อง copy ไปไว้ใน path ของ vhosts/iporsut.com/ แล้วก็กำหนดใหม่เป็น

CURLOPT_CAINFO => '/var/www/vhosts/iporsut.com/httpdocs/tkliwapp/ca-bundle.crt'

ส่วนโค้ดตรงนี้ก็เอาไปเพิ่มใน facebook.php จะมีส่วนที่เป็นการกำหนด default options ให้กับ curl อยู่ ก็เพิ่มเข้าไป เท่านี้ก็ทำงานได้ปกติแล้ว

Openframeworks เบื้องต้น

วิธีการสร้างโปรแกรมจาก Openframeworks คือ อาศัยการ extends คลาส ofBaseApp ซึ่งเป็น base class สำหรับทุกๆ app ที่สร้างจาก openframeworks โดยในตัวคลาส ofBaseApp จะมี function หลักๆที่ควบคุม event การทำงานของโปรแกรมอยู่ 10 function คือ

ลองเล่น Openframeworks

openframeworks คือ ชุดคำสั่งภาษา c++ ที่ออกแบบมาสำหรับช่วยในงานสร้างสรรค์ โดยเตรียมโครงสร้างโค้ดไว้อย่างเรียบง่ายให้ทดลองใช้งาน

ชุดคำสั่งถูกออกแบบมาให้ใช้ในงานทั่วๆไป โดยเชื่อมต่อและครอบหลายๆ ชุดคำสั่งให้ใช้งานด้วยกันได้ เช่น : OpenGL สำหรับกราฟฟิค, rtAudio สำหรับ งานด้านเสียง, freeType สำหรับ fonts, freeImage สำหรับการ รับและแสดงผลภาพ, quicktime สำหรับการเล่น video และการเก็บลำดับ video

โค้ดที่เขียนสามารถทำงานได้ข้ามแพลตฟอร์ม(PC, Mac, Linux, iPhone) และข้ามตัวแปรภาษา API ถูกออกแบบมาให้มีขนาดเล็กๆง่ายต่อการทำความเข้าใจ โดยมีคลาสเพียงเล็กน้อย และในแต่ละคลาสก็มีฟังก์ชันไม่มากไป โค้ดที่เขียนอยู่ภายในคลาส มีการอ้างอิงข้ามกันน้อย ทำให้ง่ายในการนำกลับมาใช้ใหม่ ถ้าต้องการ หรือจะทำการ extends คลาสก็ได้

ตัวอย่างงานสร้างสรรค์โดย openframeworks

Functor Type Class

Functor Type Class

นิยามไว้ว่า

class Functor f where
fmap :: (a -> b) -> f a -> f b

นั่นคือ Type ที่เป็น instance ของ type class นี้จะต้องสร้างฟังก์ชัน fmap โดยฟังก์ชันนี้รับค่าฟังก์ชัน (a->b) และ f a แล้วจะได้ f b
จะเห็นว่า เราเอา type f มาทำเป็นข้อมูลแบบ f a แสดงว่า instance ของ Functor ต้องเป็น type ที่มี constructor ที่รับ parameter อีก 1 ตัวเพื่อทำให้สามารถเขียนเป็น f a , f b ได้ จาก type ของฟังก์ชัน fmap จะเห็นว่ามีลักษณะเดียวกันกับฟังก์ชัน map

map :: (a -> b) -> [a] -> [b].

จะเห็นว่า map คือรับฟังก์ชันที่รับค่าเป็น type a แล้วได้ผลลัพธ์เป็น type b แล้วรับลิสต์ของ type a และจะได้ผลลัพธ์เป็นลิสต์ของ type b
นั่นคือ ลิสต์เป็น instance ของ Functor เขียน instance ได้ดังนี้

instance Functor [] where
fmap = map

โดยที่ [] เป็น constructor ของข้อมูลแบบลิสต์

อีกตัวอย่าง type ที่สามารถเป็น instance ของ Functor ได้อีกคือ Maybe

instance Functor Maybe where
fmap f (Just x) = Just (f x)
fmap f Nothing = Nothing

นั่นคือ การ map function f ไปที่ข้อมูลแบบ Maybe ถ้าเป็น Just x จะได้ค่า Just (f x)
ถ้า map ไปที่ Nothing จะได้ Nothing

ส่วน Either a b = Left a | Right ก็สามารถสร้างเป็น instance ของ Functor ได้เช่นกัน

instance Functor (Either a) where
fmap f (Right x) = Right (f x)
fmap f (Left x) = Left x

จะเห็นว่าเราทำให้ Either เป็น type ที่รับ type parameter แค่ตัวเดียวได้โดยทำหนดให้ type ที่ส่งไปทำเป็น instance มี type a ติดเข้าไปด้วย ทำให้มันเหลือแค่ต้องรับค่า type b เพิ่มเข้าไป ทำให้เวลา map function f เข้าไปกับ (Left x) ได้ Left x เหมือนเดิม และเมื่อรับ Right x จะได้ Right (f x)

Functor Law

Functor จะมีกฎอยู่ 2 ข้อคือ
1) The first functor law states that if we map the id function over a functor, the functor that we get back should be the same as the original functor.
ถ้าเรา map function id เข้าไปที่ functor จะได้ functor เดิมกลับมา

fmap id = id

2) The second law says that composing two functions and then mapping the resulting function over a functor should be the same as first mapping one function over the functor and then mapping the other one.
ถ้าเรา map composing function เข้าไปจะมีผลเท่ากับการ เอาฟังก์ชันแรกไป map functor แรก composing กับ อีกฟังก์ชัน map กับ functor ที่ 2

fmap (f . g) = fmap f . fmap g. Or to write it in another way, for any functor F, the following should hold: fmap (f . g) F = fmap f (fmap g F).

เรียน ป.โท วันแรก

วันนี้เปิดเทอมวันแรกและก็เป็นวันที่เริ่มเรียน ป.โท วันแรกที่ มทส. ที่เดิมกับที่เรียน ป.ตรี เรียนก็เรียนสาขาเดิม วิศวกรรมคอมพิวเตอร์ วันนี้มีเรียนวิชาเดียวคือ SELECTED TOPICS IN COMPUTER ENGINEERING I เรียนกับ รองศาสตราจารย์ ดร.กิตติศักดิ์ เกิดประสพ ตอน 10.00 - 12.00 น. แต่ว่าก็ไปแต่เช้านะแหละกะไว้ว่าจะไปถ่ายรูปทำบัตรนักศึกษาแล้วก็เปิดบัญชีไทยพานิชย์ด้วยเพราะบัตรนักศึกษาจะต้องไปผูกเป็นบัตร ATM ด้วย เขาบังคับเลยว่าต้องเป็นไทยพานิชย์สาขาย่อย มทส. งานนี้ต้องถ่ายเอกสารบัตรประชาชนไปด้วย แต่ว่าลืมไปว่า เอาบัตรประชาชนไปเช่าการ์ตูนทิ้งไว้ เลยต้องไปร้านแต่เช้า แต่ร้านไม่เปิดซวยแล้ว เลยโทรกลับมาที่บ้านหน้า ม. ให้เพื่อนช่วยดูที่ซองเอกสารให้ว่าเหลืออันที่เคยถ่ายไว้แล้วหรือเปล่า ปรากฎกว่าเหลืออยู่ 2 แผ่น รอดไป กว่าจะไปเรียนรวมอีกรอบก็จะ 10.00 น. แล้วเลยเข้าไปเรียนก่อนค่อยออกมาทำบัตร

Selected Topics วิชานี้ได้เรียน AI เพราะว่าอาจารย์ กิตติศักดิ์ ท่านทำวิจัยด้านนี้เลยเลือกเรื่องนี้มาสอน วันนี้ก็ไม่มีอะไรมากช่วงแรกก็พูดคุยทั่วไปว่า ป.โท เขาเรียนกันยังไง เล่าคร่าวๆว่าแต่ละอาทิตย์วิชานี้จะต้องเรียนอะไรกันบ้าง ต้องมีงานอะไรต้องทำส่งบ้าง หลักๆก็คือให้ไปหาหัวข้องานวิจัยมาทำเป็น miniThesis เพื่อเป็นการฝึกทำ Thesis อาจารย์ก็แนะนำตัวอย่าง Thesis ให้ดูแล้วก็แนะนำวิธีการเข้าไปหาอ่านเปเปอร์จาก IEEE และ ACM หลังจากนั้นก็ lecture นิดหน่อยแค่ Introduction Artificial Intelligence ก็บอกว่าเนื้อหาที่จะเรียนมีไรบ้าง หลักๆก็เรื่อง Knowledge Base, Machine Learning, Fuzzy Logic อะไรประมาณนี้

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

ตอนบ่ายไปประชุมกับพี่ใหม่เรื่องช่วยสอนแล็บวิชา OOT ก็สรุปว่าได้คุมวันอังคาร พี่ใหม่ก็ให้โจทย์ตัวอย่างมาลองหัดๆทำไว้ จะได้ช่วยแนะนำน้องๆได้ โจทย์ไม่ยากมากก็เคยๆทำมาแล้วทั้งนั้นตอนสมัยเรียน จะมีก็แค่บางข้อต้องคิดซับซ้อนนิดหน่อย ตอนนี้นั่งทำไปได้ 2 lab ล่ะเดี๋ยวค่อยทำต่อให้หมด

Moonlight Mile Lostman's Journey Enjoy the Ride

เพลงประกอบเอนิเมชันเรื่อง Moonlight Mile เพราะดี เพิ่งเช่ามาอ่านได้เล่มเดียว เป็นเรื่องราวของนักปีนเขาสองคน ที่ปีนเขาจนหมดแล้ว เลยคิดจะปีนต่อไปดวงจันทร์

เพิ่ม fields ให้ node ของ drupal ด้วย cck module

โครงสร้าง content ของ drupal คือ node โดยที่ field หลักๆที่เป็นส่วนของ content ของ node คือ title กับ body โดยปกติเวลาเราสร้าง content type ใหม่ก็จะมีแค่ให้ปรับ label ของ title กับ body ไม่มีส่วนที่ให้เราเพิ่ม field อื่นๆลงไปเอง (โดยไม่ต้องไปเขียนโค้ดสร้าง module เอง)

โมดูล cck จะมาช่วยตรงนี้คือช่วยให้เราเพิ่ง fields ลงไปให้กับ content type ได้ ปรับตำแหน่งต่างๆของ form ได้ เช่นเราจะสร้าง content type ไว้เก็บข้อมูลพนักงาน ก็ทำให้เราเพิ่ง fields firstname, lastname, address ปรับชื่อ label ของฟอร์มได้เอง

วิธีแก้ให้ ssh บน ubuntu ไม่ให้รอนานๆก่อนที่จะขึ้นให้ใส่ password

มีปัญหากับ ssh บน ubuntu มาตั้งแต่ 9.10 แล้วคือเวลาใช้แต่ละที มันจะรอนานมากๆกว่าจะขึ้นให้ใส่ password แต่เวลาใช้ ssh บน terminal ของ osx กลับเร็วปกติ ไม่มี delay อะไรเลย ก็ทนๆใช้ไปไม่ได้หาทางออกอะไร เมื่อวานก่อนก็เลยบ่นๆไปใน twitter ก็มี @sugree ตอบให้ว่า @iporsut อันนี้ก็ได้ https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/84899 ก็เลยเข้าไปดูที่ https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/84899 ก่อนไล่ๆดูไปนะ ไม่ค่อยเข้าใจหรอกว่ามันเป็นปัญหาอะไร แต่ก็ไปเจอวิธีแก้อันนึง บอกให้เวลาเรียก ssh ให้ใส่ option แบบนี้ไปด้วย

 ssh -o GSSAPIAuthentication=no 

แล้วค่อยตามด้วย accout@domain ก็ลองทำตามดู เออ โอเคเร็วเลยทีนี้ ทีนี้จะมานั่งใส่แบบนี้มันทุกครั้งก็ขี้เกียจก็เลยใช้คำสั่งของ bash คือ alias เพื่อย่อคำสั่ง ssh แบบที่มีติด option นี้ไปด้วยให้เหลือแค่ ssh แบบนี้

 alias ssh="ssh -o GSSAPIAuthentication=no" 

ทีนี้เวลาไปเรียก ssh มันก็ใส่ option ไอ้แบบนี้ให้เราตลอดเองเลย ต่อไปก็คือ ขี้เกียจมานั่ง alias ตลอด เราก็เอาคำสั่ง alias เมื่อกี้ไปใส่ไว้ใน ~/.bashrc ซะมันจะได้เรียกให้ทำงานตลอดเมื่อเราเปิด terminal ขึ้นมา เพียงเท่านี้ก็ไม่ต้องทนรอเวลาใช้ ssh อีกต่อไปแล้ว
ขอบคุณ @sugree ขอบคุณ twitter ได้คำตอบแบบไม่ได้ตั้งใจ ตรงประเด็นกว่านั่น search กูเกิ้ลเองอีก

HTML5 presentation

HTML5 presentationสไลด์อธิบายเรื่อง HTML5 ตัวสไลด์เองก็ทำเป็น web โดยใช้ html5 ในการสร้างเหมือนกัน

Trend ในการพัฒนาเว็บในอีกไม่กี่ปีข้างหน้าที่เห็นๆก็มี

  • HTML5, CSS3, Javascript (ECMAScript, 5th Edition)
  • Adobe Flash Platform รวมทั้ง AIR
  • แล้วก็ฝั่ง Silverlight ของ Microsoft