Mar 5 2010

ตัดคำไทยด้วย C#

Category: OOAD | .NET | Java | Nativem3rLinEz @ 02:15

WARNING: Highly technical blog ahead

กาลครั้งหนึ่งนานมาแล้ว … อาจารย์สมชายแห่ง CP เคยเอารัฐธรรมนูญฉบับเก่ากับฉบับใหม่มาเทียบความถี่ในการปรากฎของคำ ตอนนั้นผมอึ้งมากที่รู้ว่า Java มันตัดคำไทยได้ด้วย แบบ built-in มาไม่ต้องหา library อะไรมาเพิ่มเลย >_<  ถ้าผมเข้าใจไม่ผิด Java ใช้ ICU ของ IBM ที่เป็น open source แต่ตัวที่อยู่ใน class library ของ Java จะเป็นเวอร์ชันเก่ากว่าหน่อย

เจ้า ICU ที่ว่านี่นอกจากตัดคำได้ (Boundary Analysis) แล้วมันยังทำอย่างอื่นที่เกี่ยวกับกับ localization & internationalization ได้อีกมากมายก่ายกองครับ ลองเข้าไปดูกันเอง IBM ทำไว้สองชุดคือ ICU4C และ ICU4J สำหรับ C, C++ และ Java (ไม่มี .NET แป่วว) ถ้าใครทันสมัยใช้ Firefox ที่ยังตัดคำไทยไม่ค่อยจะคล่องอาจจะได้ยินชื่อนี้บ่อย เพราะมีคนไทยฮาร์ดคอร์มากมายเอาโค้ด Firefox มาแก้ใส่ ICU ให้ตัดคำแล้ว build ใหม่ … แค่ฟังก็อยากจะอ้วกออกมาเป็น pointer กับไฟล์ .h แล้วว =__=’

ด้วยความที่ 3 วันนี้ผมเมาจัดหรือยังไงไม่ทราบ เลยใช้เวลาว่างอันมีอยู่น้อยนิดไปพยายามทำ binding ให้เรียกใช้ ICU จาก C# (และ .NET) ได้ครับ! ก่อนทำก็หา best practice โดยการไปถามที่แหล่งประจำเล็กน้อย ได้คำตอบมาแค่อันเดียวน่าเศร้าใจ TvT

ผมเข้าใจว่าการทำ binding มันจะต่างจาก wrapper ตรงที่ เราต้องนำเสนอ interface เดียว (หรือคล้ายๆ) กับที่ underlying C++ classes มันใช้อยู่ให้กับผู้ใช้ ส่วนการทำ wrapper มันเหมือนกับว่าเราไปสร้างอะไรซักอย่างหุ้ม C++ classes เหล่านั้นไว้ และให้ผู้ใช้เรียกใช้งานผ่าน interface ของเรา (โดยไม่รู้ว่าข้างในมีอะไรอยู่บ้าง – Facade Pattern อ่านว่า “ฟา-ซ้าด”) ซึ่งการทำ wrapper นี่มันง่ายกว่าโขเลยน่ะ

หลังจากลองถูๆไถๆ ใช้พลังกับ C++/CLI เหมือนที่เคยใช้ในซีเนียร์โปรเจค ก็ออกมาเป็นรูปเป็นร่าง อยู่ที่ ICU4NET สามารถลองดาวน์โหลดไปใช้ได้ ถึงชื่อจะบอกว่า ICU4NET แต่จริงๆแล้วตอนนี้มันมี class ที่ใช้งานได้อยู่ class เดียวคือ BreakIterator =_=” ตั้งใจไว้ว่าจะจัดการกับ class ในกลุ่ม boundary analysis ให้หมด

เอาโค้ดตัวอย่างให้ดูเล็กน้อย อันแรกเป็นแบบดั้งเดิม ลักษณะเดียวกับที่เขียนใน ICU4J และ ICU4C

private List<string> WordBreak(string text)
{
var sb = new StringBuilder();
var col = new List<string>();

using (BreakIterator bi = BreakIterator.CreateWordInstance(Locale.GetUS()))
{
bi.SetText(text);
int start = bi.First(), end = bi.Next();
while (end != BreakIterator.DONE)
{
col.Add(text.Substring(start, end - start));
start = end; end = bi.Next();
}
}

return col;
}

ส่วนอันนี้ผมเขียน Extension Method เพิ่มให้มัน return เป็น IEnumerable ได้ พวกขา 3.5 จะได้เล่นซนแบบนี้ได้ :’)

using (BreakIterator bi = BreakIterator.CreateWordInstance(Locale.GetUS()))
{
bi.SetText(uxText.Text);

// requires ICU4NETExtension to use Enumerate extension method
MessageBox.Show(string.Join(Environment.NewLine, bi.Enumerate()
.GroupBy(w => w)
.OrderBy(x => x.Count())
.Reverse()
.Select(x => x.Key + " : " + x.Count())
.Take(10)
.ToArray()));
}

ตอนแรกตั้งใจว่า ส่วนที่น่าจะเอาไปเล่นได้หลักๆคงเป็นพวก ASP.NET Web App แหละ แต่นั่งคิดๆดูแล้วมันมีส่วนประกอบที่เป็น library native ของ ICU หลายอันอยู่ ถ้าเข้าใจไม่ผิดคงมีปัญหากับเรื่อง trust level ของ IIS พอสมควร …

ผลพลอยได้จากการผลาญเวลา (แบบไร้เหตุผล เอามันส์ล้วนๆ) ครั้งนี้คือ ได้ศึกษา C# เพิ่มอีกนิดหน่อย แล้วก็ลองใช้ C++/CLI อีกนิสสสนึง หลังๆมานี่อยู่ที่ทำงานได้ใช้แต่ C++ จนรู้สึกตัวเองตามโลก C# ไม่ทัน มาอ่านโค้ดของ @chakrit (ขา 3.5 ตัวพ่อ) ทีนี่นั่งงงอยู่หลายนาที –..-‘ เออออ … น้ำหลักลดด้วยนะ ^ ^

จากประสบการณ์ ด้วยหัวข้อยบลอกประมาณนี้ ผมเชื่อว่าคงมี นิสิต/นักศึกษา ที่กำลังปั่นงานของอาจารย์แล้ว search มาเจอ และอยากนำไปใช้ได้โดยเร็ว … ผมขอร้องว่าก่อนจะทิ้งคอมเม็นต์ไว้หรือเมล์มาถาม technical issue กับผม ช่วยศึกษาเรื่องพื้นฐาน C# กับเรื่องพวกวิธี reference รวมถึงอ่าน Readme ก่อน แล้วค่อยถามมานะครับ …

ผมตั้งเป้าไว้ว่าจะมีคนเอาไปใช้ประโยชน์ได้ 2 คนขึ้นไป ใครเอาไปใช้ทำอะไรบอกด้วยๆ :’)

ICU4NET – ICU Binding for .NET

WordBreak

Tags: , , , , , ,

Mar 1 2010

New Big Toy

Category: Lifem3rLinEz @ 12:08

พักหลังๆนี่เวลาแก๊นจะตัดสินใจซื้ออะไรซักอย่างที่มันมีราคา จะคิดแล้วคิดอีก อย่างน้อยก็ทิ้งเวลาไว้ตั้งแต่ 2 อาทิตย์ - หลายเดือน เพื่อจะดูว่าเราต้องการมันจริงๆรึเปล่า (ถ้าผ่านมานานแล้วก็ยังต้องการอยู่ก็แปลว่าโอเค ไม่ใช่ความรู้สึกชั่ววูบหลังดูโฆษณา)

ของเล่นชิ้นล่าสุดที่เอาเข้าบ้านคือ LCD TV ของ LG รุ่น LH70 ขนาด 32 นิ้ว กระเป๋าแห้งไปอีกหลายเดือน อยากถ่ายรูปที่ห้องเก็บไว้เหมือนกัน แต่ห้องรกจัด แหะๆ ผมแนะนำว่าซื้อกับร้านข้างนอกถูกกว่าในห้างมากจนน่าตกใจเลยนะครับ สุดท้ายมันก็ประกันศูนย์ LG เหมือนกัน

LH70_LR (1)

ประโยชน์ใช้สอยหลักๆก็เอามาดูหนังนั่นแหละครับ คนแรกที่ทำให้อยากซื้อคือพี่ธี CP31 เนื่องจากผมเห็นเค้าตั้งชื่อใน WLM ในทำนองแฮปปี้กับ TV ใหม่มาก หลังจากนั้นผมจึงเกิดความอยากได้แล้วก็เริ่มมีความรู้เรื่องพวก High Definition (Hi-Def) ขึ้นมาเล็กน้อย สรุปให้ฟังคร่าวๆดังนี้

  • TV ที่มันเขียนว่า FullHD แปลว่ามันแสดงผลได้ที่ 1920 x 1080 pixel
  • ไฟล์วีดิโอที่ขนาดดังกล่าว เรียกสั้นๆว่า 1080p แต่จริงๆแล้วมันยังมีขนาดเล็กกว่านั้นคือ 720p อีก เรียกรวมๆกันว่า Hi-Def video ทั้งคู่
  • หนัง Hi-Def พวกนี้ไฟล์ใหญ่เอาเรื่อง เรื่องนึงมีขนาดได้ตั้งแต่ 8 – 12 GB สำหรับหนัง 2 ชม.ครึ่ง
  • พอร์ตที่ใช้ส่งข้อมูลจะกลายเป็น HDMI แทน ซึ่งขนส่งข้อมูลแบบ digitial ไม่ใช่ analog ดังนั้นสายจีนแดงอันละ 350 กับสายแพงๆอันละ 2000 – 3000 จะมีความสามารถในการส่งเท่ากัน ต่างกันแค่ที่ความคงทน แล้วก็เรื่องคุณภาพของหัวต่อนิดหน่อย (แต่ไม่ทำให้สีอิ่มขึ้น สวยขึ้น ชัดขึ้น แน่นอน) เคยมีดราม่าเรื่องนี้ด้วยนะเทอว์
  • พอร์ต HDMI จริงๆแล้วมันขนส่งข้อมูลที่เป็นสัญญาณภาพแบบเดียวกับ DVI (ที่เห็นใน Graphics card และจอ LCD ของคอมพิวเตอร์ทุกวันนี้) แต่จะมี digital audio เพิ่มมาด้วย สรุปคือ HDMI = DVI + digital audio
  • ดังนั้นมันจึงมีหัวแปลงจาก HDMI –> DVI (โดยที่เสียงจะหายไป) และ DVI –> HDMI ได้โดยไม่เสียคุณภาพของภาพแม้แต่น้อย
  • ดังนั้น ตามทฤษฎี การเอาหัวแปลง DVI –> HDMI มาต่อที่ Graphics card แล้วเอาสาย HDMI ต่อเข้า TV จะทำให้เสียงไปโผล่ที่ TV ไม่ได้ อีกทั้ง Graphics card มันก็ไม่ได้ออกแบบมาให้มีเสียงออกมาด้วยอยู่แล้ว
  • แต่ ในทางปฎิบัติ ทั้ง ATi และ Nvidia ก็ต่างมีวิธีของตัวเองทำให้เสียงมันออกมาด้วยได้ !! (ตึ๊ง) โดยที่ ATi ต้องใช้หัวแปลงที่แถมมากับกับการ์ดเท่านั้น ส่วน Nvidia ลองไปดูกันเอง ฮ่าๆ (ผมใช้ ATi รุ่นที่มันยังไม่แถมหัวแปลงมาให้ ปัจจุบันยังหาไม่ได้เลย ยังใช้ลำโพงของคอมพิวเตอร์อยู่ T_T)

หลายวันนี้จะมีช่วงนึงที่เงียบๆไป เพราะเห่อของเล่นใหม่อยู่ครับ ฮาาาา โดยรวมๆแล้วจุดที่ชอบก็มีตรงที่ดู XVid จาก USB Flash Drive + USB HDD ได้ (มีพอร์ต USB หลังเครื่อง) แล้วก็ TruMotion ที่เป็นเทคโนโลยีการแทรก frames เข้าไประหว่าง frames ทำให้ภาพมันลื่นไหลมากขึ้น และส่วนของ UI ทำออกมาดูสวยใช้งานง่ายดี

ส่วนจุดที่ผิดคาดนิดหน่อยคือเวลาเอาหนัง 1080p กับ 720p ไปเปิดแล้วดูที่ระยะประมาณ 3 เมตร ผมแทบจะสังเกตความแตกต่างไม่ออกเลย T_T แต่หลายคนก็บอกอ่ะนะ ว่าถ้าเป็น LCD TV ขนาด 32” ไม่ต้องจ่ายเพิ่มเพื่อให้เป็น FullHD ก็ได้ เพราะมันสังเกตความต่างยาก

เอารูปตัวอย่างที่ printScrn มาให้ดูนิดหน่อย (ภาพเต็มขนาดที่ http://www.solidskill.net/FCKUploaded/Image/FullDistrict.png )เผื่อจะสามารถกระตุ้นต่อมอยากคนแถวนี้ได้ ฮ่าๆ

FullDistrict

ปล. มีแววอยากได้เครื่องเล่นเกมอีกแหงมๆ แต่เชื่อว่าคงไม่มีเวลาเล่นว่ะ T_T เส้าใจ (แล้วมีเวลาดูหนังได้ไงวะ !?)

Tags: , , ,

Feb 21 2010

ทำไมคนเราถึงเกลียดภาษาอื่นๆ

Category: Generalm3rLinEz @ 09:02

แน่นอน ภาษา Programming นะครับ ไม่ใช่ จีน ญี่ปุ่น อังกฤษ :P

ไปเจอคำถามนี้และคำตอบที่น่าสนใจมาก ว่าการเกลียดภาษาอื่นๆมักจะแบ่งเป็น 3 แบบ

เกลียด เพราะได้ยินข่าวลือแย่ๆมา เช่น

  • “Ruby ช้า เขียนแล้วโค้ดสวยก็จริงแต่ทำงานช้าโคดๆ”
  • “เขียน VB, C#, .NET แล้วโง่ เอะอะอะไรก็ลากแปะ”
  • “Java ช้า”
  • “C++ มีแต่ไดโนเสาร์เขียน”

พวกนี้ส่วนใหญ่พอได้ยินข่าวลือพวกนี้มาจาก forums หรือเว็บข่าว ก็มักจะฝังใจแล้วบอกต่อๆกัน แต่ก็ไม่เคยลองเอง และก็ไม่รู้ว่ามันไม่ดีตามที่บอกรึเปล่า

เกลียด เพราะใช้แล้วไม่พอใจ

พวกนี้เคยใช้จริง แล้วไม่พอใจจริง ซึ่งอาจเกิดจากสาเหตุ เช่น

  • โดนหัวหน้า อาจารย์ เจ้านาย บังคับให้ทำ ซึ่งทำแล้วปรากฎว่าใช้แล้วได้ผลไม่ดี (อาจจะแบบว่าใช้อย่างอื่นแล้วเหมาะกว่า เช่น เคยเอา C++ ไปเขียน Web App) ก็เลยไม่ชอบ
  • ใช้แล้วมัน “ไม่ใช่ว่ะ”
  • ไม่ค่อยมีข้อมูลในการใช้เรียนรู้ หรือ learning curve ชันไป

เกลียด โดยหลักการ

ไม่ชอบลักษณะ / คุณสมบัติ บางอย่างของภาษา โดยอาจจะรู้สึกว่าภาษาหนึ่งดีกว่าอีกภาษา ตรงที่ … เช่น

  • “ไม่ชอบ Java เพราะต้องทำงานบน JVM  … มันไม่ถูกต้องนะ! เขียน C++ แล้วให้ compile เป็น native สิ!” -- คลั่ง C++
  • “ไม่ชอบ C++ เพราะต้องมารับผิดชอบการเขียนให้มัน cross platform เอง ต้องมาเช็ค #ifdef เบื้อกอะไรตั้งมากมาย แล้วต้องมาเรียนรู้ platform-specific system calls เอง เฮ้อ” -- ผมเขียน Java
  • “ไม่ชอบ Java เพราะ syntax มันช่างบุโรคั่งและยืดเยื้อ รวมถึงแคร์เรื่อง backward compatibility เหลือเกิน ไม่ Elegant เหมือนภาษาผมเอาซะเลย” -- ผมเขียน C#

ส่วนตัวผมมีประสบการณ์กับการไม่ชอบทั้ง 3 แบบ

แบบ 1 สมัยเด็กๆผมรู้สึกว่า VB 6 ดูดีมีอนาคตกว่า VC++ มากๆ เพราะแค่ new project ใหม่ก็ได้ Window เปล่าๆมาอันนึงแล้ว ส่วน VC++ ต้องเขียนโค้ดเองกว่า 80 บรรทัดกว่าจะได้หน้าต่างว่างๆมา ผมก็เลยไม่เข้าใจอย่างยิ่งว่าทำไมคนถึงยังชอบไปเขียน C++ กัน ประกอบกับเจอพวก C++ หัวแข็งมากมายใน forum ดังสมัยนั้น (thaidev.com) ซึ่งบางที task VC++ บางอย่างที่มาถามๆกันในเว็บบอร์ด ผม “Thinking in VB 6” พรืดเดียวก็ออกแล้ว ผมจึงไม่ชอบ C++ และเป็นผู้ ไม่สนับสนุน อย่างเป็นทางการ ตั้งแต่นั้น

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

แบบ 2 ผมเกลียด C บน Microcontroller มากๆครับ! เนื่องจากว่ามันเป็นภาษาที่ค่อนข้างพิกา… เอ้ย จำกัด ไม่สามารถใช้ประโยชน์ของ C ได้อย่างเต็มที่, call stack ก็มีขนาดจำกัด แล้วยังมี bahavior ที่คาดเดาไม่ได้อีกหลายอย่าง (ขนาดผมเขียน C แบบพื้นฐานมากๆแล้วนะ) ประกอบกับผมขาด resource (เวลา + ฮาร์ดแวร์ที่ใช้เบิร์นโปรแกรมลงบอร์ด) ทำให้สุดท้ายผลมันออกมาไม่ดี แล้วก็มีเรื่องไม่ดีมากตามมาอีกหลายอย่าง (เพื่อนสนิทรู้กัน - -‘’) ผมเลย “พาล” เกลียด C บน Micro แบบฝังใจไปเลยจนทุกวันนี้

เปรียบเทียบกับประสบการณ์เดียวกันบน Verilog (มันใช้งานละแบบกันน่ะ แค่เป็น hardware เหมือนกันเลยเอามาเทียบ) ผมประทับใจมากกก

แบบ 3 ถ้าจะมีคงเป็น PHP ซึ่งตอนนั้นผมขยับจาก ASP ไปเป็น ASP.NET พอดี สมัยนั้น ผมดูภาษามันแล้วรู้สึกว่าวิธีการ extends ภาษาด้วยการลง mod เพิ่มมันดูพิลึกๆ (มาก) แล้วก็ยังมีเรื่องต้อง compile คู่กับ MySQL lib ให้ตรงเวอร์ชันอีกไม่งั้นจะใช้ด้วยกันไม่ได้ ก็เลยไม่คิดจะศึกษาเพิ่มเติมนอกจากเขียนอะไรง่ายๆที่สมัยนั้นคนชอบเขียนกัน (Counter, Webboard, GuestBook) ซึ่งการไม่ศึกษา PHP ทำผมเสียโอกาสไปเยอะพอควร

เอาจริงๆผมไม่ค่อยเกลียดอะไรในระดับนี้เท่าไหร่นะ ด้วยเหตุผลที่ว่า ภาษาไหนที่มันไม่ดังผมก็จะไม่ค่อยสนใจ แล้วภาษาที่ดังขึ้นมาได้ก็แปลว่ามันผ่านกระบวนการ natural selection และมันโดนทดสอบด้วย “เวลา” มาระดับนึงแล้ว มันก็คงมีข้อดีของมันแหละ

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

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

Tags:

Dec 13 2009

ดึงราคาหุ้นใน SET

Category: Generalm3rLinEz @ 18:14

ไปอ่านเอกสารพวก Chart Patterns มา ซึ่งมันคือ Pattern ของกราฟราคาหุ้นที่คนเขียนเอกสารพวกนี้เค้าสังเกตมาว่า เป็นสัญญาณอะไรบางอย่างที่ทำให้หุ้นจะเปลี่ยนราคา (ขึ้น หรือ ลง) ไปอย่างรวดเร็วทำให้สามารถใช้ trade ทำกำไร (หรือขาดทุนยับ) ได้ ส่วนใหญ่คนเขียนเอกสารเค้าก็จะออกตัวไว้ก่อนเลยว่า มันไม่ถูก 100% นะ แต่ก็ไม่เคยมีใครบอกว่ามันถูกกี่ % ดังนั้นก่อนอื่นต้องหาวิธีดึงราคามาเอาไว้ทำการทดลองก่อน

จริงๆแล้ว API ที่ บ.เหมาะกับงานนี้มากเลย แต่ถ้าเอา Data ตรงนั้นมาใช้กลัวว่าอาจจะได้เตะฝุ่นก่อนทำงานครบปี :[ เหอะๆ

class DayData:
    date = None
    open = None
    close = None
    max = None
    min = None
    volume = None
    value = None
    set_index = None

    def __init__(self):
        pass

    @staticmethod
    def to_datetime(str):
        from datetime import datetime
        ds = [int(x) for x in str.split('/')]
        ds[2] = ds[2] + 2000
        return datetime(ds[2], ds[1], ds[0])
                
    @staticmethod
    def to_decimal(str):
        from decimal import Decimal
        return Decimal(str.replace(',',''))

class SETFetch:
    @staticmethod
    def fetch(symbol):
        import urllib2
        from decimal import Decimal
        from BeautifulSoup import BeautifulSoup
        
        set_url_format = "http://www.settrade.com/C04_02_stock_historical_p1.jsp?txtSymbol=%s&from=%d";
        cur_pos = 1
        all_data = []

        while True:
            page = urllib2.urlopen(set_url_format % (symbol, cur_pos))
            soup = BeautifulSoup(page)
            read_data = soup.findAll('tr','tdbg_gray20') + soup.findAll('tr','tdbg_white20')
            if len(read_data) == 0:
                # no more data to read
                break
            cur_pos = cur_pos + len(read_data)
            all_data = all_data + read_data

        daily = []
        for day in all_data:
            flds = day.findAll('td')
            current = DayData()
            current.date =  DayData.to_datetime(flds[0].text)
            current.open = DayData.to_decimal(flds[1].text)
            current.max = DayData.to_decimal(flds[2].text)
            current.min = DayData.to_decimal(flds[3].text)
            current.close = DayData.to_decimal(flds[5].text)
            current.volume = DayData.to_decimal(flds[8].text) * 1000
            current.value = DayData.to_decimal(flds[9].text)
            current.set_index = DayData.to_decimal(flds[10].text)
            daily.append(current)    
        daily.sort(key=lambda x: x.date, reverse=True)
        return daily

if __name__ == '__main__':
    daily = SETFetch.fetch('PTT')
    for day in daily:
        print day.date
    #pdb.set_trace()
ตัวอย่างการใช้งาน
Python 2.6.3 (r263rc1:75186, Oct  2 2009, 20:40:30) [MSC v.1500 32 bit (Intel)]
on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from setfetch import SETFetch
>>> data = SETFetch.fetch('CPF')
>>> dir(data[0])
['__doc__', '__init__', '__module__', 'close', 'date', 'max', 'min', 'open', 's
t_index', 'to_datetime', 'to_decimal', 'value', 'volume']
>>> for sample in data[0:10]:
...     print sample.date, sample.close
...
2009-12-11 00:00:00 10.90
2009-12-09 00:00:00 10.70
2009-12-08 00:00:00 10.80
2009-12-04 00:00:00 11.00
2009-12-03 00:00:00 10.70
2009-12-02 00:00:00 10.60
2009-12-01 00:00:00 10.90
2009-11-30 00:00:00 10.70
2009-11-27 00:00:00 10.20
2009-11-26 00:00:00 10.40
>>>

เท่าที่รู้ SET จะไม่ยอมให้ใครมาเผยแพร่ Historical Prices พวกนี้ ยกเว้นคนที่จ่ายตังค์ให้ SET และถ้าจะเผยแพร่ก็ต้องเผยแพร่แบบเก็บเงินเท่านั้นด้วย! (แจกฟรีไม่ได้) แต่ทุกวันนี้ก็จะเห็นมีการแอบแจกกันบ่อยๆ :} เป็นเหตุผลว่าทำไมถึงดูราคาหุ้นไทยในเว็บดีๆอย่าง Google Finance ไม่ได้ (แต่ทำไม Bloomberg ดูได้ไม่รู้ ขี้โกงๆ)

ช่วงนี้นอกจากจะเขียนโค้ดช้าลงแล้ว เวลาว่างยาวๆติดๆกันก็ไม่ค่อยจะมี ความสนใจก็เยอะเหลือเกิน >_< เลยต้องพยายามทำให้เสร็จไปเป็นชิ้นเล็กๆ ครั้งหน้าค่อยมาต่อกันเรื่อง Bar Pattern ที่ไปดูมา ว่าพอมาทดสอบกับข้อมูล 6 เดือนที่ดึงมาแล้วมันจะเวิร์คแค่ไหน

Tags: , , ,

Nov 10 2009

Data Visualization

Category: Toolsm3rLinEz @ 00:17

gant_so 

ทุกวันนี้พวกเราทำงานกับข้อมูลจำนวนมาก มันเป็นศาสตร์ใหญ่ๆอย่างนึงเลยทีเดียวในเรื่องของวิธีการเอาข้อมูลมาแสดง ว่าการแสดงในรูปแบบไหนถึงจะทำให้ผู้ชมเข้าใจข้อมูลได้ง่ายที่สุด และสามารถ reveal feature บางอย่างที่ถ้าสังเกตจาก representation อย่างอื่นแล้วอาจจะมองไม่เห็น!

รูปด้านบนเกิดจากการเอาโพสต์จากบลอกภาษาอังกฤษของผมมาตัดคำแล้วเอามาทำเป็นต้นไม้ จะเห็นได้ขึ้นมาชัดระดับนึงว่า เวลาเราเขียนคำๆนึงแล้ว เรามักจะเอาคำอะไรมาต่อ (อื้มมมม น่าจับพวกเนื้อเพลงมาทำ คงฮาระดับนึง :P) อันนี้มีคนใจดีทำไว้ให้เล่น ที่ Many Eyes

อันนี้เป็นอีกรูปนึงที่ความถี่ของคำเยอะกว่ารูปแรกมาก (ใช้คำว่า I)

gant_i

จริงๆแล้วตัวเว็บมันยังมีรูปแบบในการ Visualize ให้เล่นอีกหลายแบบมาก รวมถึงรูปแบบข้อมูลที่เอา input ให้ระบบไปก็ยังมี 2 รูปแบบ ตัวอย่างข้อมูลที่เป็นโพสต์จากบลอกของผมเรียกว่า Free Text แต่ยังมีอีกแบบนึงที่เป็น Table ซึ่งทำให้สามารถนำเสนอข้อมูลที่มันสัมพันธ์กันซับซ้อนมากกว่า 1 มิติได้

ส่วนอันนี้เป็นอีกรูปแบบนึงที่เรียกว่า Phrase Net อันนี้จะเน้นการแสดงความสัมพันธ์ในระดับคำแทน เราสามารถเลือกได้ว่าให้ระบบแสดงความสัมพันธ์แบบไหน ตัวอย่างเช่น สัมพันธ์แบบเป็นวลีในรูปแบบ “A and B” หรือ “A’s B” หรือ “A of B” หรือ “A[space]B” อันที่เอามาให้ดูนี่เป็นแบบ “A[space]B” รู้สึกว่ารูปสวยดี (อันนี้เหมาะจะเอามาทำกับเนื้อเพลงมากกว่าอันข้างบนอีก ฮ่าๆ)

gant_pn

ส่วนอันนี้ชอบมาก! สวยกว่านั่งทำ Typography เองอีก โอ้ว!!! ใครโดนสั่งทำปกสมุดแล้วคิดอะไรไม่ออก เอาไอนี่ไปวางแก้ขัดได้เลย ~

gant_typo

สาขา ป.โท ที่ใกล้เคียงเรื่องพวกนี้ที่สุดน่าจะเป็นเรื่อง Human Computer Interaction (HCI) เคยอยากเรียนเหมือนกัน แต่จน .. เอ้ย! แต่โง่ …. เย้ยย! รู้สึกว่าถ้าไปเรียนก็คงสนุกดี (เข้าทาง) ชอบเรื่องพวกนี้มากๆเลย ถ้าไปเรียนก็อยากไปเรียน ”เพื่อความบันเทิง” อ่ะ (แต่คงยากจะเกิดเหตุการณ์แบบนั้นขึ้น –_-‘ ถ้ายังคงมีภาระชีวิตที่ต้องรับผิดชอบอยู่)

ใครสนใจก็ลองไปเล่นกันดู :)

Tags: , , ,

Nov 7 2009

2 เดือนในตลาด

Category: Generalm3rLinEz @ 13:06

เผลอๆผ่านมาจะครบสองเดือนแล้วตั้งแต่เริ่มเข้าไปซื้อขายหุ้นใน SET ~

ผมสารภาพว่าก่อนหน้านี้ เวลาดูข่าวทีวี (เอ๊ะ .. ดูทีวีด้วยเหรอ) ช่วงที่เค้าบอกว่าวันนี้ดัชนีตกไปกี่จุดๆ จะเป็นช่วงเวลาที่น่าเบื่อสำหรับผมมากก (พูดเรื่องอะไรกันวะ) แต่หลังจากเริ่มทำงานที่บริษัทก็เลยรู้ว่า product ของ Thomson Reuters มันเกี่ยวกับ Financial Market ล้วนๆเลยนี่หว่า (ก่อนสัมภาษณ์เข้าทีไม่กี่วันยังคิดอยู่เลย ว่านี่จะเข้ามาเป็นลูกจ้างนักข่าว เขียนโปรแกรมตามสั่งให้รึเปล่าวะ 555+) ก็เลยเริ่มสนใจขึ้นมามาก ประกอบกับวัยเพิ่งเริ่มทำงาน ภาระอะไรก็ไม่มี ยังรับความเสี่ยงสูงๆได้อยู่ น่าจะใช้โอกาสนี้ให้คุ้มค่าหน่อย

เคยคุยกับพี่ที่ทีม เค้าบอกว่าเค้าเริ่มซื้อๆขายๆตั้งแต่ ปี 2 … จะไม่น่าแปลกใจเท่าไหร่ถ้าพี่เค้าไม่ได้อายุมากกว่าผมประมาณ 6 ปี = =’ ผมก็แอบรู้สึกว่าตัวเองเริ่มช้าไปนิดนึง จริงๆเรื่องนี้อาจจะแล้วแต่คน แต่ผมคิดว่าวันนึงเราคงหลีกเลี่ยงการรู้จัก “ตลาด” ไม่ได้ เริ่มรู้จักตลาดเร็วๆก็น่าจะดีกว่า ถ้าย้อนเวลากลับไปได้อยากเริ่มซะตั้งแต่เรียนมหาลัยนี่หละ เหมาะที่สุดแล้ว

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

  1. อย่างแรก ซื้อหุ้นน้ำผลไม้ของ TIPCO แล้ว (มารู้ตอนหลังว่ามันบังเอิญมากก) ราคามันขึ้นสูงอย่างมีนัยสำคัญ ก็ขายทิ้ง ถือเป็น impression ที่สุดยอดมากสำหรับมือใหม่ ทำให้ view ผมตอนนั้นโคด optimistic เลย (ถ้าเงินมันหาง่ายขนาดนั้น คงมีคนนอนจิ้มๆคีย์บอร์ดอยู่บ้านมากมาย =_=’)
  2. อย่างที่สอง ตอนมีข่าวทุบตลาด แล้วดัชนีร่วงติดกัน 2-3 วัน ช่วงนั้นหุ้นที่ซื้อมาแทบทุกตัวราคาตกระนาว ก็ได้เรียนรู้กันไปหลายอย่าง ทำลายความ optimistic ลงไปอย่างสิ้นเชิง และทำให้รู้สึกว่าต้องระมัดระวังขึ้นมาก

 

Technical Analysis และ Value Investing

วิธีการทำเงินในตลาดมันเข้าใจง่ายมากครับ ก็คือซื้อมาแล้วก็ขายออกไปให้แพงกว่า! แต่ปัญหาคือ แล้วจะซื้อตอนไหนและขายตอนไหนน่ะสิ ???

มี “แนวคิด” สองอย่างที่ใครๆในตลาดก็รู้จัก คือเรื่องของ Technical Analysis และ Value Investing (VI)

อย่างแรกมีความหมายตามชื่อ คือ Technical Analysis นั้น จะสนใจข้อมูลที่อยู่ตรงหน้าเป็นหลัก คือ ราคา ปริมาณการซื้อขาย แล้วพยายามทำนายอนาคต มีเครื่องมือที่สำคัญคือ indicator ซึ่งจริงๆแล้วมันคือการเอาข้อมูลที่เห็นตรงหน้า (ราคา เปิด ปิด สูงสุด ต่ำสุด ซื้อขายล่าสุด ปริมาณ) ไปผ่านการคำนวณอะไรบางอย่าง แล้วเอามาแสดงอีกรอบ เท่านั้นเอง หลังจากเราเห็นข้อมูลพวกนี้ก็สามารถมองหา Signal (สัญญาณ) ได้ สัญญาณที่บอกว่าราคากำลังจะขึ้นเรียกว่า Bullish Signal (กระทิง) ในขณะที่สัญญาณที่บอกว่าราคาจะตกเรียกว่า Bearish Signal (หมี)

Indicator ก็แบ่งเป็นประเภทต่างๆ ที่เห็นพูดถึงกันบ่อยก็คือ MACD ที่เป็น indicator ประเภท trend following นั่นคือมันจะทำงานได้ดีเวลา “แนวโน้ม” ราคามัน “ขึ้น” หรือว่า “ลง” อย่างชัดเจน และจะทำงานได้แย่มากถ้าราคามันแกว่งไปมาแบบไม่มี trend หรือรูปแบบ Whipsaw ส่วนอีกตัวที่พูดถึงบ่อยเช่นกันคือ Relative Strength Index (RSI) เป็น Indicator ประเภท momentum คือบอกว่าตอนนี้มีการซื้อหรือขายมากเกินไปรึยัง (over-bought, over-sold) ถ้ามากเกินไปแล้วก็อาจจะถึงเวลาที่ราคาจะกลับตัว

อย่างที่สอง คือ Value Investing เป็นแนวคิดที่ริเริ่มสอนโดย Benjamin Graham ซึ่งปรากฎว่า ศิษย์เอกของอาจารย์คนนี้ “รวยแหลก” แทบทุกคน หนึ่งในนั้นรวมถึงนักลงทุนที่ขึ้นชื่อว่าประสบความสำเร็จที่สุดในโลก คือ Warren Buffett ด้วย เนื่องจากว่ามือใหม่อย่างผมเป็นพวกที่ incline ไปทาง TA มากกว่า เลยรู้แนวคิดของ VI แค่นิดหน่อย คือการเลือกหุ้นเพื่อลงทุนของ VI นั้นมักจะใช้ข้อมูลที่เป็น Reference Data คือเป็นประวัติการจ่ายปันผลของบริษัท ทรัพย์สินของบริษัทเป็นยังไงบ้าง ราคานี้เหมาะสมแล้วหรือเปล่า? คำพูดที่จะได้ยินบ่อยๆจาก VI คือ “ราคาต่ำกว่าที่ควรจะเป็นมาก ควรซื้อ” หรือ “ราคาสูงกว่าที่ควรจะเป็นมากแล้ว ควรขาย” ตัวอย่างหุ้นที่ “น่าซื้อ” สำหรับคนกลุ่มนี้ เช่น หุ้นที่ราคาหุ้นนั้น ต่ำกว่าทรัพย์สินที่บริษัทมีทั้งหมดเสียอีก แบบนี้ก็จะถือว่าราคามันต่ำกว่าความเป็นจริง และเชื่อว่าวันนึงราคาก็จะ (ขึ้นมา) reflect เรื่องนี้ในที่สุด พวกนี้ส่วนใหญ่จะถือยาว คือ buy-and-hold ซื้อไว้แล้วก็เฝ้าดูห่างๆก็พอ ไม่ต้องเฝ้าหน้าจอรอดูจุดกลับตัวเหมือนพวก TA

เรื่องแปลกๆที่ผมสังเกตเห็น คือ VI กับ TA จะแบ่งก๊กกันชัดเจน และมักจะมี argument ให้เห็นบ่อยๆว่าแบบไหนทำเงินได้ดีกว่า ข้ออ้างอย่างนึงที่มักจะเห็นบ่อยๆคือ VI ดีกว่าเพราะว่านักลงทุนที่รวยที่สุดเป็น VI พันธุ์แท้! .. อันนี้ก็เหมือนกับการอ้างว่า ถ้าอยากรวยไม่ต้องเรียนมหาวิทยาลัยก็ได้ เพราะ Bill Gates ก็ไม่ได้จบมหาวิทยาลัย

การแบ่งก๊กระหว่าง VI กับ TA ทำให้ผมคิดถึงตัวเอง รวมถึงพวก “C++ หัวแข็ง” “Microsoft หัวแข็ง” “Linux หัวแข็ง” หลายๆคน ผมว่าการมี “ศาสนา” พวกนี้ทำให้เราพลาดอะไรดีๆไปหลายอย่าง

คำแนะนำสำหรับคนอยากเริ่ม

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

หลังจากนั้นก็ต้องเปิดบัญชีซื้อกับโบรคเกอร์ เนื่องจากว่าเราเข้าไปซื้อๆขายๆในตลาดเองไม่ได้ ต้องมี middle-man หรือนายหน้าพวกนี้จัดการให้ โดยเค้าก็จะมีการคิดค่าดำเนินการนิดหน่อย (Commission) เช่น ถ้าซื้อหุ้นราคา 1 บาท จำนวน 1000 หุ้น แบบนี้เราจะต้องจ่ายค่าดำเนินการเพิ่ม 1.5 บาท เป็นต้น รวมเงินที่ต้องจ่ายเป็น 1001.5 บาท

มือใหม่รายย่อยอย่างเราๆก็น่าจะเปิดเป็นแบบ internet trading (อีกแบบคือใช้โทรศัพท์โทรไปหาเจ้าหน้าที่การตลาด หรือเรียกสั้นๆว่า “มาร์” มาจาก marketing) แล้วก็เปิดเป็นบัญชีแบบ Cash Balance คือต้องโอนเงินเข้าไปก่อนจึงจะซื้อหุ้นได้ (เหมือนโทรศัพท์มือถือ Pre-paid) ซึ่งน่าจะปลอดภัยมากกว่า ส่วนบัญชีอีกแบบจะให้ซื้อได้ก่อน แล้วค่อยเช็คบิลทีหลัง

ตอนนี้ก็มีโบรคอยู่หลายๆที่ วิธีเลือกง่ายๆสำหรับมือใหม่คือเลือกโบรคที่ “ไม่คิดค่า commission ขั้นต่ำ” ณ เวลาที่ผมเขียนนี่ค่า commission อยู่ที่ 0.15% หมายถึงถ้าซื้อขาย 100 บาท จะเป็นค่าคอม 0.15 บาท แต่ถ้าหากมีค่าคอมขั้นต่ำ 50 บาท (สมมติ) หลังคำนวณค่าคอมแล้วได้แค่ 0.15 บาทก็จะต้องจ่าย 50 บาทเต็มๆ

อีกอย่างที่ต้องดูคือโปรแกรมสำหรับดูราคาแบบ Real-time ของโบรคมันใช้ได้กับคอมพิวเตอร์ของเรารึเปล่า หลายๆที่ใช้ technology พวก ActiveX นั่นหมายถึงต้องใช้ Windows และ IE เท่านั้นจึงจะใช้ได้ บางที่เช่นที่ผมใช้อยู่ก็จะมีส่วนที่เป็น HTML ธรรมดาให้ใช้เหมือนกัน (สำหรับ Firefox และพวก PDA) ใช้ดูราคา ส่งคำสั่งซื้อขายได้ แต่มันจะไม่ real-time เท่านั้นเอง

ตอนที่ผมเลือกโบรคที่เจ้าที่สนใจอยู่สองที่ คือ KTZmico และ Kim Eng (ไม่ได้ค่าโฆษณานะ) สุดท้ายผมเลือก Kim Eng ด้วยเหตุผลหลายอย่าง หนึ่งในนั้นคือชื่อโดเมนมันพิมพ์ง่ายกว่ามาก! สนนค่าเปิดพอร์ตอยู่ที่ 30 บาทถ้วน ถ้าใครอยากเริ่มผมแนะนำให้เริ่มเตรียมเอกสารเปิดไว้เลย เพราะหลังเปิดแล้วจะช่วยให้ Active ขึ้นมาก

Hope this helps

Tags: , ,

Oct 20 2009

ประชาธิปไตย ต้องถ่วงน้ำหนัก

Category: Generalm3rLinEz @ 23:58

200px-Election_MG_3455

ตอนแรกผม “โยนหินถามทาง” ไปใน Facebook ด้วยหัวข้อ “ประชาธิปไตย ต้องถ่วงน้ำหนัก” ปรากฎว่ามีคนมาคอมเม็นต์สองคน คือทีระพาบ (เป็นไปตามแผน) แล้วก็พี่บอย ในเชิงไม่เห็นด้วย

ผมไม่ค่อยแปลกใจเท่าไหร่ถ้าจะมีคนไม่เห็นด้วยมากมายกับเรื่องนี้ จริงๆแล้วเรื่องนี้ผมก็เคยถกเถียงกับเพื่อนๆด้วยกันมาบ้างก่อนหน้านี้แล้ว ถ้าใครยังเข้าใจคำว่า “ถ่วงน้ำหนัก” ไม่ถูก ผมขอธิบายให้เห็นภาพคร่าวๆดังนี้

  • คะแนน Vote ของกลุ่ม A คิดเป็นคนละ 10 คะแนน
  • คะแนน Vote ของกลุ่ม B คิดเป็นคนละ 1 คะแนน
  • คะแนน Vote ของกลุ่ม C ไม่คิดคะแนน

ประเด็นสำคัญคือ แล้วเราจะเอาหลักเกณฑ์ที่ไหนมาจัด “มนุษย์” ผู้มีสติปัญญาในการตรึกตรองตัดสินใจแต่ละคน มาอยู่ในกลุ่ม A B หรือ C ???

ลองมาดูตัวอย่างง่ายๆพวกนี้ดู

  • ถ่วงน้ำหนักตามการศึกษา - เรียนมาสูง น้ำหนักมากกว่า
  • ถ่วงน้ำหนักตามอายุ อายุ - อายุมาก น้ำหนักมากกว่า
  • ถ่วงน้ำหนักตามประวัติการช่วยเหลือสังคม - ยังไง ???

อย่าแปลกใจถ้าจะไม่เห็นด้วยกับอะไรข้างบนเลย เพราะว่ามันมีปัญหามากมายในการจะนิยามอะไรแต่ละอย่างออกมา -- การศึกษาไม่ได้บอกว่าการตัดสินใจของบุคคลนั้นจะดีกว่า (และไม่ bias) อายุก็เช่นเดียวกัน

ประชาธิปไตยในสังคมอินเทอร์เน็ต ที่ใช้งานอยู่

แนวคิดที่ว่านี้ ผมเห็นที่ StackOverflow.com ซึ่งมันเป็นกระดานถามตอบสำหรับพวกโปรแกรมเมอร์

จุดเด่นที่น่าสนใจสรุปเป็นข้อๆคือ

  • สมาชิกใหม่ที่เข้าไป จะตั้งคำถาม และคำตอบได้เท่านั้น
  • ทุกครั้งที่มีคน “โหวต” ให้ เจ้าของคำถามหรือคำตอบจะได้ “คะแนนความน่าเชื่อถือ” เพิ่ม
  • สมาชิกที่มีคะแนนความน่าเชื่อถือเกิน N1 จะมีสิทธิ์ในการ “โหวต”
  • ความน่าเชื่อถือเกิน N2 มีสิทธิ์ในการแก้ไขข้อความที่คนอื่นเขียน
  • ความน่าเชื่อถือเกิน N3 สามารถ “แจ้งปิด” คำถามได้
  • แจ้งปิดเกิน M1 คน คำถามจะปิดโดยอัตโนมัติ

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

จริงๆแล้วหลักการประเภทโหวตนี่ก็มีใช้กันในเว็บในประเทศเหมือนกัน อย่างเช่นการโหวตความคิดเห็นใน manager, การสั่งปิดกระทู้ / ให้ gift ใน Pantip เป็นต้น

การถ่วงน้ำหนัก กับ ประชาธิปไตยในประเทศไทย

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

"มาตรา 105 บุคคลผู้มีคุณสมบัติดังต่อไปนี้ เป็นผู้มีสิทธิเลือกตั้ง

         (1) มีสัญชาติไทย แต่บุคคลผู้มีสัญชาติไทยโดยการแปลงสัญชาติต้องได้สัญชาติไทยมาแล้วไม่น้อยกว่าห้าปี

         (2) มีอายุไม่ต่ำกว่าสิบแปดปีบริบูรณ์ในวันที่ 1 มกราคมของปีที่มีการเลือกตั้ง และ

         (3) มีชื่ออยู่ในทะเบียนบ้านในเขตเลือกตั้งมาแล้วเป็นเวลาไม่น้อยกว่าเก้าสิบวันนับถึงวันเลือกตั้ง

 

"มาตรา 106 บุคคลผู้มีลักษณะดังต่อไปนี้ในวันเลือกตั้งเป็นบุคคลต้องห้าม มิให้ใช้สิทธิเลือกตั้ง คือ

         (1) วิกลจริต หรือจิตฟั่นเฟือนไม่สมประกอบ

         (2) เป็นภิกษุ สามเณร นักพรต หรือนักบวช

         (3) ต้องคุมขังอยู่โดยหมายของศาลหรือโดยคำสั่งที่ชอบด้วยกฎหมาย

         (4) อยู่ในระหว่างถูกเพิกถอนสิทธิเลือกตั้ง"

 

สงสัยว่าในตอนเริ่มแรก ใครเป็นคนนิยามการ “ถ่วงน้ำหนัก” เหล่านี้ --  ทำไมต้องเป็นคนไทยมาอย่างน้อย 5 ปี -- ทำไมต้อง 18 ปี -- ถูกคุมขังแล้วทำไมถึงเลือกตั้งไม่ได้ – แล้วทำไมพระสงฆ์ต้อง Neutral …

จากที่ผมคุยกับเพื่อนๆ ผมรู้สึกว่า พอพูดเรื่อง “การถ่วงน้ำหนัก” ขึ้นมาทีนึง จุดโฟกัสเราจะพุ่งไปที่ “การไม่เคารพความคิดเห็นผู้อื่น” หรือ “ไม่เท่าเทียมกัน” “ดูถูกชาวนา” จริงๆแล้วเราน่าจะโฟกัสผลประโยชน์ที่จะเกิดขึ้นด้วยว่ามันมีอะไรบ้าง -- การ ซื้อสิทธิ์ ขายเสียง มันก็คือการ “สแปม” ประเทศไทยดีๆนี่เอง

ทิ้งคำถามไว้ให้คิดกันเล่นๆ แล้วถ้าจะตั้งเกณฑ์ให้การ “ถ่วง” เพิ่ม จะตั้งยังไงดี ???

ปล. หลังจากเขียนเสร็จ เพิ่งจะเอะใจ ไปหาคำแนวๆ “Weighted Vote Democracy” ปรากฎว่าเจอหน้านี้ Voting System อ่านคร่าวๆแล้วรู้สึกมีเรื่องน่าสนใจหลายอย่าง ไว้จะไปอ่านต่อ

ปล2. คนที่เค้าเรียนรัฐศาสตร์ หรืออะไรทำนองนี้มา จะมีวิธีอธิบายเรื่องพวกนี้ หรือเข้าใจปัญหาแนวนี้มากกว่ารึเปล่าหว่า

ปล3. ขอขอบคุณบลอกชื่อคล้ายๆกัน “ประชาธิปไตย ต้องเรียนรู้” – แต่ไม่ใช่ว่ะ มันต้องปรับปรุง

ปล4. ผมสนใจการเมืองน้อยมาก ถ้ามี View อะไรอยากเสริม ช่วยคอมเม็นต์มาด้วย :)

Tags: ,

Oct 14 2009

Phantom IFrames

Category: Generalm3rLinEz @ 04:25

ปัญหาคือ อยู่ๆโปรแกรม php ที่ใช้อยู่มันก็มีโค้ด iframe มาแทรกได้ยังไงก็ไม่รู้ ??? เท่าที่ผมเคยอ่านผ่านๆจากเรื่อง ประกาศเลิกใช้ FileZilla ของคุณ Ford Antitrust ก็พอจะทราบความเป็นไปได้อย่างนึงคือว่าการเซฟ password ไว้บนเครื่องก็อาจจะโดนโปรแกรมไม่ถึงประสงค์มาดูด usr/password ไปใช้ในการเอาโค้ดไม่พึงประสงค์พวกนี้มาแทรกไว้ในโค้ดของเราได้

แต่เนื่องจากว่า password ของ account ภาค ตั้งแต่โดนเปลี่ยนมาก็แทบจะไม่มีใครรู้เลย –*- (จริงๆนะ) แล้วเท่าที่ผมทราบคนเดียวที่มี password มันก็ aware เรื่อง security มากจนไม่น่าจะเกิดเรื่องแบบนี้ขึ้นได้

อย่างไรก็ตาม หลังจากไปบ่นๆไว้ใน Facebook เรื่องย้ายบอร์ด แล้วสุดท้ายก็เงียบไป (ยุ่งจัด T-T) ในที่สุดก็มีคนยื่นมือมาแก้ให้ครับ ขอบคุณกอล์ฟไม่เกมไว้ ณ ที่นี่ด้วย เรื่องนี้ ดูเหมือนผมจะลบโค้ด iframe ออกไม่เกลี้ยง =_=’ เพราะตอนลบจะเลือกลบเฉพาะไฟล์ที่ “น่าจะ” โดนโหลด อันนี้เป็นนิสัยเสียของผมเองที่เวลาจะลองอะไรจะลองแบบ minimal เสมอ พอแก้เพิ่มแล้วไม่เห็นว่าผลมันดีขึ้นก็จะเลิกทำซะงั้น ..

ของแบบนี้ต้องยกให้คนมีกระสบการณ์จริงๆ :)

GolfB

Tags: , ,

Sep 27 2009

ปัญหาภาษาไทยกับ iTunes และ Windows

Category: .NETm3rLinEz @ 12:58

เป็นปัญหาเดียวกับเรื่องภาษาไทยเป็นตัวยึกยือ มันเกิดจากข้อมูลใน ID3 Tag (เป็นส่วนของไฟล์ที่ไว้บอกข้อมูลเกี่ยวกับเพลง) มันเก็บภาษาไทยโดยใช้ Encoding แบบนึง (มักจะเป็น Windows-874 / TIS620 ซัมติง …)

MP3TagProblem

อ่านหาวิธีแก้ตามเว็บบอร์ดชุมชนคนไทยก็พบวิธีแก้ง่ายๆอย่างนึงคือต้องไปเปลี่ยน Regional Settings ให้เป็นไทยหลายๆอัน แล้วจะดิสเพลย์ได้ถูกต้อง o__O! แล้วค่อยใช้ iTunes convert ID3 ให้กลายเป็นเวอร์ชันใหม่ๆ (ที่จะเป็น unicode รองรับหลายภาษา)

การทำแบบนี้มันก็มีปัญหาอยู่บ้าง เพราะพอเปลี่ยน Regional แล้วก็จะทำให้ไม่รู้ว่าอัลบั้มไหน convert ID3 ไปเรียบร้อยแล้วรึยัง (เพราะมันแสดงได้ถูกต้องทั้งหมด) อย่างตอนนี้ผมลง OS ใหม่เป็น Windows 7 อัลบั้มเก่าๆเน่าไปหลายอันอยู่ … ก็เลยเขียนโปรแกรม convert ดีกว่า! (นั่น …. หาเรื่องเขียนบลอกอะดิ๊ๆๆๆๆ)

ประเด็นสำคัญ

  • Tool สำหรับแปลง ID3 ที่เป็น encoding หนึ่งไปอีกอันนึงก็มีอยู่แล้วบ้าง แต่ส่วนใหญ่มักจะเป็นบน Linux กับ Mac หาของ Windows ไม่เจอ (หรือผมอาจจะตาถั่วเอง)
  • ใช้ Lib สำหรับอ่าน ID3 คือ TabLig Sharp
  • ใช้ Reflection ในการวนรอบ property ทุกอันที่เป็น string และ string[] เป็นครั้งแรกที่เริ่มเห็นคุณค่าของ relfection!
  • พอมันมี Library ภายนอกก็เลยมี DLL หลายอัน รวมให้เป็น EXE อันเดียวโดยใช้ ILMerge จะทำให้ ship ง่ายกว่า (แต่ยังไม่คิดจะ ship รอให้มี demand ก่อน ฮ่าๆ)
  • อันตรายมาก: ยังไม่มีวิธีเช็คเลยว่าไฟล์ไหนถูกแปลงไปแล้วบ้าง เพราะถ้าแปลงซ้ำกันสองครั้งมันจะทำให้เนื้อหาไฟล์พังไปเลย >_< โดนไปหนึ่งดอกเรียบร้อย
  • ตอนนี้ใช้ iTunes โดยให้มัน Consolidate Library แล้ว รู้สึกทำให้ย้ายของง่ายกว่า
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace ID3ConvertToUnicode
{
class Program
{
public static string FixThaiCodePage(string str)
{
if (str == null) return null;
byte[] raw = Encoding.Default.GetBytes(str);
string res = Encoding.GetEncoding("windows-874").GetString(raw);
return res;
}

public static string[] FixThaiCodePage(string[] strings)
{
string[] res = new string[strings.Length];
for (int i = 0; i < strings.Length; i++)
{
res[i] = FixThaiCodePage(strings[i]);
}
return res;
}

static void Main(string[] args)
{
string[] files = Directory.GetFiles(".");
foreach (string file in files)
{
if (!file.EndsWith(".mp3"))
continue;

Console.WriteLine("Converting: " + file);
TagLib.File music = TagLib.File.Create(file);

foreach (PropertyInfo pinfo in music.Tag.GetType().GetProperties())
{
if (!pinfo.CanRead || !pinfo.CanWrite)
continue;

if (pinfo.PropertyType == typeof(string))
{
string s = pinfo.GetValue(music.Tag, null) as string;
s = FixThaiCodePage(s);
pinfo.SetValue(music.Tag, s, null);
}

if (pinfo.PropertyType == typeof(string[]))
{
string[] s = pinfo.GetValue(music.Tag, null) as string[];
s = FixThaiCodePage(s);
pinfo.SetValue(music.Tag, s, null);
}
}
music.Save();
Console.WriteLine();
}

}
}
}

ilmerge /target:winexe  /out:ID3Retag.exe 
ID3ConvertToUnicode.exe policy.2.0.taglib-sharp.dll taglib-sharp.dll

iTunesThaiFixed

ยอดเยี่ยม!

Tags: , , ,

Sep 20 2009

Remote Debugging J2EE Application

Category: Java | Toolsm3rLinEz @ 12:04

ตั้งชื่อบลอกไม่ถูก คำศัพท์ Java มันเยอะจัด (J2EE, Web Container, Servlet, ...)

ฐานโค้ดที่ผมดูอยู่ที่ทำงานมันค่อนข้างใหญ่มาก เป็นไฟล์ Text ขนาดรวมกันเกือบ 20 MB ซึ่งจริงๆแล้วส่วนที่เราจะเข้าไปมองจริงๆมันก็ไม่ได้เยอะอะไรหรอกครับ แต่ปัญหาก็คือว่า เราจะหาส่วนที่เราต้องการมาได้ยังไงจากข้อมูลที่เยอะขนาดนั้น ??? คำตอบหนึ่งคือใช้โปรแกรมพวก Cross Referencing เช่น OpenGrok จะช่วยให้ค้นหาส่วนของโค้ดที่ต้องการได้ง่ายขึ้นเยอะเลย นอกจากนี้ OpenGrok ยังสนับสนุนการทำ index บน repository ของพวก SCM Tools ต่างๆเช่น SVN, Git และ Mercurial อีกด้วย

เข้าเรื่อง … ปัญหาที่ผมเจอคือ OpenGrok มันดันไม่โชว์ History ให้ ซึ่งหลังจากถามไปใน mailing-list ก็พบว่ามันเกิดจากการหาโปรแกรม hg (Mercurial) ไม่เจอใน PATH ผมลองมา reproduce ที่บ้านบน environment ที่เป็น Windows ก็ยังเจอปัญหาเดียวกันอยู่ เลยต้องหาวิธี Debug OpenGrok ตอนนั้นคิดๆไว้หลายวิธี

  • Build เฉพาะ Class ที่ทำหน้าที่ส่วนนั้นขึ้นมาใหม่ แล้วใส่ให้มันโหลดขึ้นก่อนใน CLASSPATH  .. อันนี้สุดท้ายก็ทำไม่ได้เพราะผม build เป็นไฟล์ๆไม่ได้มันติดพวก dependency เลยไม่รู้ว่าสรุปแล้วใช้วิธีนี้ได้ป่าว
  • อ่านวิธี Build OpenGrok จากเว็บมันแล้วลองตั้ง breakpoint ตรงส่วนที่เป็นปัญหา อ่านแล้ววิธีนี้น่าจะง่าย แต่เนื่องจากว่าตัว Container ที่ใช้มันเป็น Tomcat แต่ปกติ Netbeans มันจะติดมากับ Glassfish เลยเกิดความขี้เกียด config ขึ้นมาในบัดดล
  • ทำ Remote Debugging คือ start Tomcat ใหม่ให้มันรันแบบ Debug และเปิด port 7001 รอไว้ แล้วเอา Debugger เข้าไป attach … อันนี้ได้ผลครับ และง่ายมากด้วย แต่ต้อง build OpenGrok ได้น่ะ หลังจากตั้ง breakpoint ไว้แล้วปรากฎว่ามัน break จริงๆด้วยว่ะ! Watch + Evaluate ได้แทบทุกอย่างเลย

จริงๆ ASP.NET ก็มีของแบบนี้เหมือนกัน มันเหมาะมากเวลาเกิดปัญหากับ Application ใหญ่ๆที่การ Setup ให้เกิดปัญหาเดียวกันมันยาก ใช้แล้วก็รู้สึกว่า Java ก็ไม่เลวครับ : )

Java Options สำหรับ Start Tomcat

-Xdebug
-Djava.compiler=NONE
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7001

แล้วใช้ Netbeans attach เข้าไปที่ port 7001 ของ localhost

Tags: , , , , ,