Author Archives: nkuln

ทำครัวไม่เหมือนต่อเลโก้

น้ำท่วมพาเหตุการณ์สำคัญมาให้ผมอีกเรื่องนึง คือ ข้าวกล่องแดง 7-11 หมดเกลี้ยง หยุดผลิต!

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

พอมันหายไป ผมเลยต้องมองหาอย่างอื่นมาทดแทน ซึ่งก็ไม่ได้หายากอะไรเพราะนอกจาก 7-11 ใต้คอนโดยังมี Max-Value ที่เป็นซูเปอร์มาเปิดใหม่ไม่นาน มีอาหารปรุงเสร็จใส่กล่องขายด้วย

พวกข้าวกระเพราไก่ไข่ดาว ข้าวผัด blah blah มีหมด … เสียอย่างเดียวคือรสชาติมันพอๆกับข้าวที่ศูนย์ฝึก ร.ด. แค่นั้นเอง = =’’

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

ก็เลยลองทอดดู มันจะมีอะไรยาก เอามาทอดๆ ปรากฎว่าสนุกดีอะ ทำกินไปหลายอย่างเลย ทั้งแบบที่หน้าตามันดูกินได้ และดูกินไม่ได้ …

301089_10150346633527257_637427256_8542827_10672384_n  8f0498bc086d11e19896123138142014_7

พอเริ่มทอดคล่องแล้ว (หลายวัน) อยากลองของยากขึ้นฮะ แล้วไปเจอวิดิโอสอนทำคาโบนาราใน Youtube พอดีด้วยความบังเอิญ

http://www.youtube.com/watch?v=B47U6ff7SY8&feature=feedf_more

ไอ่คนในวีดิโอบอกว่าทำง่ายซะด้วย! เอาวะ ลองซะหน่อย ดูในวิดิโอก็ไม่เห็นจะยากตอนไหนเลย

ก็เลยไปหาของมาให้ครบๆ ดังต่อไปนี้

  1. เส้นสปาเกตตี (แน่นอน ต้องมี)
  2. หัวหอมใหญ่
  3. ไข่
  4. เบคอน
  5. พริกไทยดำ
  6. เกลือ
  7. พาเมซานชีส (แพง maxxx เกือบหาไม่ได้)
  8. วิปครีมเหลว (อันนี้ก็แพงเหมือนกัน)

วันแรกที่ทำยังไม่มี วิปครีมเหลว แต่ว่ามีซอสผัดอย่างอื่นที่น่าจะใช้แทนได้ เลยลองดันทุรังทำดูซักหน่อย ปรากฎว่าแง่งออกมาเป็นผัดหมี่ = =’’ แดมมม

 Photo Nov 08, 9 11 02 PM

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

นอกจากเรื่องเส้นที่มากไปแล้ว ยังมีความผิดพลาดอื่นๆอีก (ที่เรียนรู้เองจากการลองทำ)

  • ใช้ไฟแรงเกินไป จนพวกเบคอนกับหอมสับห่อเหี่ยวหมด
  • พอไฟแรง ของในกระทะเริ่มแห้ง ก็ต้องเอาน้ำเปล่าเติม (ไม่มีน้ำซุป) ออกมาแฉะไปอีก
  • อัตราส่วนวิปครีมเทียบกับไข่ ใช้วิปครีมเยอะไป ตอนกินมีแต่รสวิปครีม เลี่ยนๆ
  • ใช้วิปครีมเยอะไปมากก จนท่วมเส้นได้ทั้งกระทะ กะผิด
  • ตั้งวิปครีมไว้บนเตาไฟแรงนานมากจนนมแยกออกจากน้ำมันชัดเจนเลยทีเดียว = =’

รูปข้างล่างมาจากวันที่สอง ออกมาเป็นไรไม่รู้ แต่ก็ฝืนๆกินจนทนไม่ไหว เลยเลิก – -‘

(เพิ่งเข้าใจประโยค Eat your own dog food จากการปฎิบัติจริง ก็วันนี้)

Photo Nov 12, 9 15 12 AM Photo Nov 12, 9 48 06 AM Photo Nov 12, 10 04 55 AM

ทำกินตอนเช้า ตอนบ่ายออกไปเที่ยวเล่นด้วยความพะอืดพะอม = = กะว่าจะเลิกทำคาโบไปอีกซักอาทิตย์

แต่วันนี้ตื่นมานึกไงไม่รู้ ทำอีกรอบ คราวนี้แก้ไขข้อผิดพลาดคราวที่แล้วคือ

  • ใช้เส้นน้อยลงมาก (คราวนี้นับเลยว่าใช้ 40 เส้น)
  • เพิ่มส่วนประกอบที่เป็นเบคอนทอดกรอบ (จะได้ดูดีขึ้นหน่อย + ดับความเลี่ยน)
  • ใช้วิปครีมน้อยลง ผสมไข่แล้วข้นๆเลย
  • ใช้ไฟอ่อนลงเยอะ
  • แยกหัวหอมออกมาส่วนนึงก่อน ไว้ค่อยใส่เข้าไปตอนหลัง จะได้กินหอมดิบๆบ้าง หวานๆดี
  • ตั้งวิปครีมบนกระทะแปร๊บเดียว แล้วเทลงจานเลย กลัวมันร้อนจนน้ำมันแยกตัวแบบคราวก่อน

ค่อนข้างพอใจกับผลที่ออกมาฮะ TvT พอรับประทานได้เลยทีเดียวเชียวล่ะ ..

Photo Nov 13, 12 08 31 PM

ที่น่าจะยากหลังจากนี้ คือ จะทำให้ได้ออกมาประมาณนี้แบบคงเส้นคงวายังไง แล้วถ้าต้อง scale (เช่นทำมาเสิร์ฟสองที่พร้อมกัน) จะ scale ได้มั้ย ..

เป็นอะไรเล็กๆน้อยๆที่มากับเรื่องน้ำท่วม 2554 ฮะ ผมจะจำไว้

ปล. ราคาต้นทุนน่าจะสูงกว่ากินตามร้านแล้ว แดมมม (3)

ลองใช้ LaTeX

วันก่อนไม่รู้นึกไงเอาไฟล์ The Not So Short Introduction to LaTeX ใส่ Kindle ไปอ่าน อ่านไปอ่านมา skim ไปจนจบ ต้องลองเล่นดูซะหน่อย

สมัยเรียนมหาลัยถ้าใครเคยอ่านเปเปอร์พวกที่เป็นงานวิจัยจะรู้สึกว่ามันมีอะไร “บางอย่าง” คล้ายๆกันอยู่ แต่ไม่รู้ว่ามันคืออะไร ..

จริงๆแล้วเอกสารเหล่านี้ส่วนใหญ่มากเลยล่ะ ผลิตมาด้วย LaTeX ทั้งนั้น

ดังนั้นถ้าให้เปรียบเทียบกับซอฟแวร์ที่เรารู้จักก็คงต้องเอา LaTeX ไปเปรียบเทียบกับ Microsoft Word เพราะทั้งสองโปรแกรมใช้ผลิตงานพิมพ์ได้เหมือนกัน

ในวงการการวิจัยและการศึกษาจะยอมรับเอกสารที่ผลิตมาจาก LaTeX มากกว่า ผมเชื่อว่าถ้าส่งไฟล์ .docx ไป conference คงโดนศาสตราจารย์มองด้วยหางตา + เพื่อนเนิ้ดไม่คุยด้วยเลยทีเดียว .. (ขี้เว่อร์ซะ)

จริงๆแล้วมีโจ๊กเกี่ยวกับ LaTeX ที่เคยโพสต์ไว้ด้วยใน วิธีอ่าน Resume ของ HR กับ Programmer

วิธีการเริ่มใช้งานจริงๆมันไม่ยากอะไร แต่ถ้าจะจัด format เอกสารให้ได้ดั่งใจจริงๆผมว่ายุ่งยาก

สำหรับ Windows

  1. ไปโหลด MikTeX มา โหลดแบบ portable ก็พอ เพราะเดี๋ยวก็ลบทิ้งแล้ว
  2. ติดตั้งให้เรียบร้อย
  3. เขียนไฟล์เอกสาร myfile.tex ง่ายๆหนึ่งไฟล์ ถ้าไม่มีลองเอาตัวอย่างจากท้ายบลอกนี้ไปเล่นดู
  4. รัน MikTeX portable, คลิกขวาที่ icon ตรง tray เลือก Command Prompt
  5. รัน pdflatex myfile.tex แล้วรับผลงานในรูปแบบ PDF file

ตัวอย่างเอกสาร

\documentclass[a4paper]{article}
\author{Natthawut K}
\title{Hello Old World! I’m on \LaTeX{} now!}
\begin{document}
\maketitle
\thispagestyle{empty}
\paragraph{About Me}
My name is Natthawut Kulnirundorn, and I think it’s a long name so you can just refer to my online identity “m3rLinEz.” I am from Thailand, Land of Tom-Yum-Goong and delicious foods :)\footnote{I don’t think we’re really “Land of Smiles” any more \ldots} I am interested in Object-Oriented Design, Software Architecture, Graphics, .NET, Java. I also have a technical blog\footnote{Visit my blog –
http://www.solidskill.net (in Thai)} and a Twitter account\footnote{Follow @m3rlinez!}.
\end{document}

เห็นมั้ยล่ะ อ่านไม่รู้เรื่องเลย 555+

เรื่องข้อดีข้อเสียหรือประวัติ LaTeX วิธีใช้งานเบื้องต้น ลองไปอ่านใน The Not So Short Introduction to LaTeX  ได้

บลอกนี้จดไว้กันลืม จะได้รู้ว่าเคยเล่นแล้ว

ของเล่นใหม่ใน Java 7

duke_java7
 
เป็น major version อันแรกของ Java ใต้ร่มเงาของ Oracle! ผมเองไม่ได้เขียน Java มานานมากๆแล้วเพราะงานที่ทำงานไม่ได้ใช้ตรงๆ แต่ก็ตื่นเต้นไปกับของเล่นใหม่ๆด้วย วันนี้เลยลอง Netbeans 7 + JDK 7 มาเล่นปัดฝุ่นดู 😀

เข้าใจว่ามันมีของใหม่เติมเข้ามาในเวอร์ชันนี้เยอะ แต่ที่ลองเล่นไปจะเป็นอะไรที่เกี่ยวกับตัวภาษาตรงๆ:

Binary Literals

ให้เราแทนค่าที่เป็น binary เช่น 01010101 ลงไปใน code ได้ตรงๆ น่าจะมีประโยชน์มากกับคนที่ทำพวก network / protocol / data format programming ที่แบบว่าต้องเซ็ตบิตที่ตำแหน่งเท่านี้เท่านั้นเยอะๆ ทำให้โค้ดอ่านง่ายขึ้นด้วย (รึเปล่า ??)

int data = 0b001;
int mask = 0b101;
data |= mask;

System.out.println("Data: " + Integer.toBinaryString(data));
// prints 'Data: 101'

Underscores in Numeric Literals

เป็นเรื่อง readability คือพวกค่าที่เป็นตัวเลขก็เอา underscore ไปคั่นได้ ทำให้อ่านง่ายขึ้น (เหรอ?) เช่น

int mask = 0b1110_1010;
int colorCode = 0xFF_FF_CC;
double myAccountBalance = 3_141_592.654;

Strings in switch Statements

อันนี้ไม่มีอะไรต้องอธิบาย เป็น feature ที่ถูกขอมานานถึง 16 ปีแล้ว!

มีเรื่องที่น่าสนใจอีกเรื่อง ถ้าใครตั้งใจเรียนสมัยอยู่มหาลัยจะรู้ว่า switch กับ if ซ้อนกันหลายๆอันมันทำงานไม่เหมือนกัน (ในเชิงทฤษฎี) ในเชิงปฎิบัติ หนังสือเกี่ยวกับ JVM เล่มนี้เค้าบอกว่า ถ้า constants ใน case ต่างๆทั้งหมดรวมกันแล้วมันโล่งเตียน (Sparse) คือมันกระจายตัวกันมากๆ Java จะใช้ Binary search แทนการใช้ Offset table (แบบที่เราเข้าใจตอนเรียน) แต่ถ้าอยู่กันหนาแน่น ก็จะใช้ Offset Table ตามปกติ .. เป็น optimization อย่างนึง

Type Inference for Generic Instance Creation

เป็นการแนะนำตัวของ diamond (“<>”) ช่วยให้เวลาประกาศพวก Generic เขียนง่ายขึ้น ไม่รกหูรกตา

List<String> nameList = new ArrayList<>() {};
Map<Integer, List<String>> customerToOrders = new HashMap<>();

The try-with-resources Statement

ผมว่าอันนี้มีประโยชน์เยอะเลย น่าจะทำให้โค้ด Java ใหม่ๆเปลี่ยนไปเยอะ

ถ้าให้อธิบายแบบผมคือ มันเป็นเป็นใช้ syntax ของภาษาที่บังคับให้ทำอะไรซักอย่างก่อนออกจาก scope เสมอๆ (คล้ายๆกับ destructor ของ C++ ที่จะโดนเรียกเสมอตอนออกจาก scope, เอาไปทำเทคนิคที่เรียกว่า RAII ได้)

ตัวอย่างที่ยกมาให้ดูในเว็บของ Java เป็นการใช้ BufferedReader แต่ไม่ต้องมีการสั่ง close() เอง ทำให้โค้ดอ่านง่ายขึ้นเยอะเลย จริงมั้ย??

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
// br is auto-closed here!

ใน Java 7 ก็มีหลาย class นอกจาก BufferedReader ที่สนับสนุน try-with-resources แบบนี้ ถ้าเราอยากจะให้ Class ของเราสนับสนุน try แบบนี้ด้วย ก็แค่ implements AutoCloseable

class TestAutoCloseable implements AutoCloseable{

@Override
public void close() throws Exception {
System.out.println("== Close ==");
}
}

// ...

try(TestAutoCloseable ac = new TestAutoCloseable()){
// Doing something ..
System.out.println("== Inside try ==");
}catch(Exception ex){ // (you don't want to do this)
// Close failed!
}
System.out.println("== Outside try ==");

// Prints:
// == Inside try ==
// == Close ==
// == Outside try ==

Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking

อันนี้มีสองอย่าง

อย่างแรกคือ catch Exception ได้หลายๆแบบ (ยิงปืนนัดเดียวได้นกหลายตัว) โดยใช้ try{ .. } catch(FirstException | SecondException ex){ .. }

อย่างที่สองคือ Improved Type Checking คือ Java 7 ฉลาดขึ้นสามารถเข้าใจ Type ของ Exception ได้ละเอียดขึ้น ในตัวอย่างที่ยกมา:

public void rethrowException(String exceptionName)
throws FirstException, SecondException {
try {
if (exceptionName.equals("First")) {
throw new FirstException();
} else {
throw new SecondException();
}
}
catch (Exception e) {
throw e;
}
}

จะเห็นได้ว่าถึงแม้ใน catch จะ thorw e (ที่มี type เป็น Exception) แต่ปรากฎว่าที่หัว method เราเขียน throws FirstException, SecondException ซึ่งเป็น type ที่ specific กว่าได้! อันนี้ทำได้เพราะ Java ฉลาดพอที่จะเข้าใจได้ว่า code ใน try มัน throw  อะไรออกมาได้บ้าง

Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods

อ่านหัวข้อก็รู้แล้วว่าอันนี้เข้าใจยากแน่ๆ! = =’ (เลยเอาไว้หัวข้อสุดท้าย)  อันนี้ผมอ่านแล้วก็ยังงงๆ เลยไม่กล้าลงรายละเอียด

โดยสั้นๆคือ code แบบนี้มันถูก syntax และ compile ผ่าน แต่จะตายตอนรัน

List l = new ArrayList<Number>();
List<String> ls = l; // unchecked warning
l.add(0, new Integer(42)); // another unchecked warning
String s = ls.get(0); // ClassCastException is thrown

Java 7 มีการพัฒนาในการระแวดระวังความผิดพลาดทำนองนี้ โดยการเพิ่ม Warning และ Errors ให้ผู้ใช้ระวังตัวนั่นเอง (รากหญ้าแบบผมคงไม่เจอปัญหาทำนองนี้บ่อยๆ = =’)

..

โดยสรุปว่าผม try-with-resources เป็น highlight ของอันนี้ ถ้าเอาไปเทียบกับ C# มันคือ using(..) statement นั่นเอง

แต่ที่ดูแล้วน่าคิดอีกเรื่องคือเรื่อง throw error ได้ละเอียดขึ้น อันนี้ถ้าไม่ใช้ Checked Exception ตั้งแต่แรกก็จะไม่มีปัญหานี้เลย (เหมือนใน C#)

ชอบ features ไหนกันบ้าง ? อ่านละเอียดๆได้ที่ http://download.oracle.com/javase/7/docs/technotes/guides/language/enhancements.html#javase7

สร้างการเรียงสับเปลี่ยนด้วย Javascript

ไปเจอคำถามน่าสนใจใน Blognone forum ว่าจะเขียนโปรแกรมแก้ปัญหา Zebra Puzzle (ปัญหาที่มันบอกว่ามีคนหลายชาติ เลี้ยงสัตว์หลายแบบ บ้านหลายสี บ้านคนนั้นติดคนนี้ น่ะ) ยังไง? ตอนสมัยเรียนรู้สึกเหมือนเคยแก้ปัญหาอะไรทำนองนี้แต่ใช้ Prolog ทำ ถ้าจะเอาภาษา Imperative บ้านๆแบบ Python หรือ C# ทำจะได้มั้ย?

ผมเข้าใจว่า Prolog เองมันก็มีการทำ search หา solution ที่เป็นไปได้ แล้วมีการทำพวก branch & bound หรือ track back เวลา solution มันผิดอะไรแบบนี้เหมือน (ไม่รู้ใช้ศัพท์ถูกป่าว มันนานมาแล้ว – -‘a) ครั้งนี้กะว่าจะลองใช้ Javascript เขียน

วิธีที่อยากทำคือจะวนไปตามรูปแบบ solution ทั้งหมดที่เป็นไปได้แล้ว check กับ constraints ของโจทย์ทีละตัวเลย ปัญหาแรกที่เจอคือจะ generate solution ที่เป็นไปได้ออกมายังไง?? อันนี้ต้องใช้ Permutation

Permutation ทั้งหมดของ [1,2,3] มี 3! แบบ = 6 แบบ ได้แก่ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]

ถ้ามี list มาให้อันนึง จะวนหา Permutation ทั้งหมด Wikipedia แบบให้ทำแบบนี้

The following algorithm generates the next permutation lexicographically after a given permutation. It changes the given permutation in-place.

  1. Find the largest index k such that a[k] < a[k + 1]. If no such index exists, the permutation is the last permutation.
  2. Find the largest index l such that a[k] < a[l]. Since k + 1 is such an index, l is well defined and satisfies k < l.
  3. Swap a[k] with a[l].
  4. Reverse the sequence from a[k + 1] up to and including the final element a[n].

เขียนออกมาเป็น Javascript .. ผมทำไว้เป็น Module

/////////////////////////////////////////////
// Permutation Generator
// - generate all permutation of given string
// array
// - Natthawut Kulnirundorn <m3rlinez at email by google>
// http://www.solidskill.net 10 July 2011
/////////////////////////////////////////////

var PermutationGenerator = (function () {
var self = {};

// Get start sequence of given array
self.getStartSequence = function (list) {
return list.slice(0).sort();
};

// Get next sequence from given array
// Ref: http://en.wikipedia.org/wiki/Permutation#Systematic_generation_of_all_permutations
self.getNextSequence = function (list) {
// Make clone
var a = list.slice(0);

//The following algorithm generates the next permutation lexicographically after a given permutation. It changes the given permutation in-place.
// 1. Find the largest index k such that a[k] < a[k + 1]. If no such index exists, the permutation is the last permutation.
var k = -1;
for (var i = 0; i < a.length - 1; ++i) {
if (a[i] < a[i + 1]) { k = i; }
}
if (k == -1) return null; // means this is the last one

// 2. Find the largest index l such that a[k] < a[l]. Since k + 1 is such an index, l is well defined and satisfies k < l.
var l = -1;
for (var i = 0; i < a.length; ++i) {
if (a[k] < a[i]) { l = i };
}
if (l == -1) return null; // impossible

// 3. Swap a[k] with a[l].
var tmp = a[k]; a[k] = a[l]; a[l] = tmp;

// 4. Reverse the sequence from a[k + 1] up to and including the final element a[n].
var next = a.slice(0, k + 1).concat(a.slice(k + 1).reverse());

return next;
};

return self;
} ());

แถม test cases ให้เป็นวิธีใช้
/////////////////////////////////////////////
// Test Cases
/////////////////////////////////////////////

var PermutationGeneratorTest = (function () {
var self = {};

function getStartSequence_Test1() {
var a = ['red', 'white', 'green', 'yellow', 'blue'];
var res = PermutationGenerator.getStartSequence(a);
log('input = ' + a);
log('output = ' + res);
}

function generateSequence(list) {
var current = PermutationGenerator.getStartSequence(list);
var count = 1;
log('start = ' + current);
while (true) {
current = PermutationGenerator.getNextSequence(current);
if (current == null) { break; }
log('next' + (++count) + ' = ' + current);
}
}

function getNextSequence_TestNormal() {
generateSequence(['English', 'Spanish', 'Japanese']);
}

function getNextSequence_TestEmpty() {
generateSequence([]);
}

function getNextSequence_TestRepeat() {
generateSequence(['gant', 'gant', 'korkore', 'jan']);
}

self.runTests = function () {
log("=== getStartSequence 1 ===");
getStartSequence_Test1();
log("=== getNextSequence Normal ===");
getNextSequence_TestNormal();
log("=== getNextSequence Empty ===");
getNextSequence_TestEmpty();
log("=== getNextSequence Repeat ===");
getNextSequence_TestRepeat();
};

return self;
} ());

ตัวอย่างเต็มๆผมทิ้งไว้ที่ http://www.solidskill.net/ZebraPuzzle.htm

ส่วนอันนี้เป็นคำตอบที่ตอบใน forum .. เผื่อว่า Blognone ทำกระมุ้หายคงเสียดาย พิมพ์ตั้งนาน 😛

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

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

สิ่งแรกที่ต้องทำคือ กำหนดรูปแบบของคำตอบที่เราต้องการ ตัวอย่างอันนี้กำหนดให้อยู่ในรูป list ของ list เช่น

[[1,2,3,4,5], [yellow,blue,red,white,green], [Norwegian,Italian,English,Spanish,Japanese], [fox,horse,snails,dog,zebra], [water,tea,milk,orange juice,coffe], [diplomat,physician,photographer,violinist,painter]]

list ย่อยตัวแรกจะบอกตำแหน่งของบ้าน ตัวต่อมาบอกสีบ้าน ตัวต่อมาบอกสัญชาติ และอื่นๆ ตามลำดับ จากตัวอย่างจะบอกว่าบ้านหลังแรกสีเหลือง มีชาว Norwegian บ้านหลังที่ 3 มีชาว Italian เลี้ยงหอยทาก เป็นต้น จากรูปแบบคำตอบแบบนี้และข้อมูลที่โจทย์ให้มา เราจะต้องหาคำตอบที่ถูกต้องจากคำตอบที่เป็นไปได้ทั้งหมด (5!)^5 = 24,883,200,000 แบบ (ไม่ต้องยกกำลัง 6 เพราะจริงๆแล้ว list ย่อยตัวแรกคือตำแหน่งนั้น เรา fixed ไว้เลย)

ทำแบบตรงไปตรงมา .. เราก็ generate คำตอบที่เป็นไปได้ทั้งหมดออกมา แล้วเอามาตรวจสอบกับ constraints ว่าผ่านทุก constraints หรือไม่ หลังจากตรวจสอบแล้วก็จะเหลือแค่คำตอบที่สอดคล้องกับ constraints ทั้งหมด ถ้าลองทำกับโจทย์ข้อนี้จะพบว่ามันเหลือแค่คำตอบเดียว (จากทั้งหมด 25,000 ล้านแบบ) ถ้าลองเอา constraint ออกซักตัวจะเห็นได้ว่ามีตำตอบออกมาเพิ่มหลายคำตอบ

วิธี generate คำตอบทำได้ด้วยการหา permutation ทั้งหมดที่เป็นไปได้ ยกตัวอย่างเช่น [1,2,3] มี permutation 3! =6 แบบ คือ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] .. อัลกอริทึมสำหรับการทำดูได้ใน http://en.wikipedia.org/wiki/Permutation#Systematic_generation_of_all_permutations

แต่ถ้าเราจะ generate คำตอบที่เป็นได้ไปได้ออกมาทั้ง 25,000 ล้านแบบแล้ว ตรวจสอบทุกแบบอาจจะใช้เวลามาก จริงๆแล้วเราสามารถตัดคำตอบที่เป็นไปไม่ได้ออกได้ตั้งแต่ตอน generate เลย เช่นมี constraint ตัวนึงบอกว่าบ้านหลังสีเขียวอยู่ถัดจากบ้านหลังสีขาว ดังนั้นระหว่างเรา generate สีบ้าน เราก็ตัดเคสอื่นๆที่ไม่สอดคล้องกับ constraint ตัวนี้ออกไปซะ ก็จะลดเวลาที่ใช้ลงไปได้มาก (pruning)

ที่ผม implement เป็น Javascript ลองเข้าไปดู (view source) ได้ที่ http://www.solidskill.net/ZebraPuzzle.htm ถ้าเข้าใจหลักการแล้วจะ implement เป็น Python หรือภาษาอื่นก็ไม่น่าจะลำบาก

ผมเข้าใจว่าถ้าเป็นวิชา Discrete Mathematics อาจารย์คงอยากให้หัดทำ permutation แหละ คงไม่ได้ต้องการให้ใช้เทคนิคยากๆจาก AI หรืออย่างอื่น

เข้าฝูง

iphone4

ส่วนตัวผมฝังใจมาตลอด ว่าถ้าจะซื้อมือถือเครื่องหน้าคงเป็น Android ชัวร์ๆ

ปรากฎว่ามีอะไรให้เปลี่ยนใจนิดหน่อย ตอนนี้ก็เลยไปถือ iPhone 4 ตามบางคนแทน ^ ^a ปลดระวาง Samsung i780 ไปแล้ว ซึ่งถึงตอนนี้ถ้าเทียบกับค่าตัวที่ซื้อมาก็ถือว่าใช้คุ้มแล้วล่ะครับ

เรื่องรีวิวทั่วๆไปคงไม่ต้องมีอะไรมากเนื่องจากคนใช้เต็มไปหมด เอาเป็นว่าจากมุมมองของผม:

ข้อดี

  • ตามแบบฉบับ iPhone ใช้ง่ายมาก ง่ายเกินไปด้วยซ้ำ ถ้าเทียบกับ Android แล้วคิดว่าง่ายกว่า ไม่ต้องลากบนลากล่างเพื่อเข้าถึง App หรือ Notification

  • เนื่องจากระบบมันค่อนข้างปิดมาก ไม่ยอมให้ app มา extend ระบบส่วนกลางได้ง่ายๆ (ยกเว้น app สำหรับเครื่อง jailbreak) อันนี้ต้องลองมองเทียบกับ Windows Mobile — โอกาสที่ผู้ใช้ไม่รู้อิโหน่อิเหน่จะโหลด app มาลงเยอะๆ แล้วทำเครื่องพังแบบ WM เกิดขึ้นได้น้อย

  • FaceTime เจ๋ง ลองเล่นเทียบกับ Skype Video Call แล้วผมประทับใจ FaceTime มากกว่า กำลังจะได้ลองข้ามประเทศเร็วๆนี้

  • ราคาค่อนข้างตกช้า เทียบกับมือถืออื่นๆในตลาด สภาพคล่องสูงมาก

  • เรื่อง sensitivity ต่อการ touch พอๆกับ Windows Phone 7 และเหนื่อกว่า Android ค่อนข้างชัดเจน (ที่ทีมมีให้ลองทุกรุ่น เหอะๆ)

ข้อเสีย

  • เรื่อง push notification ยังดูไม่ค่อยเป็นระเบียบ ถ้าเทียบกับ android ที่ notifcation ทุกอย่างมารวมอยู่ที่เดียว

  • ถ้าไม่ jailbreak เครื่อง ก็ไม่มี app เถื่อนๆที่มันยุ่งกับระบบเยอะๆให้เล่น ผมคิดว่าคงยังไม่ jailbreak ไปซักพัก เพราะตอนนี้ก็โอเคดี

  • ถ้าอยากเขียนโปรแกรมลงไป ต้องใช้ Mac เท่านั้น อันนี้หนักอกที่สุด คนเป็น developer (ที่ใช้ PC) คงรู้สึกคล้ายๆกัน ตอนนี้เลย enjoy user-mode experience อย่างเดียว

  • app ซื้อง่ายเกินไป ตังค์ออกจากกระเป๋าครั้งละ 30 บาทได้ง่ายๆ (ตอนนี้จ่ายไปแล้ว 3 apps)

หลังๆจะเห็นข่าว Android เริ่มปิดระบบตัวเองมากขึ้น ซึ่งผมว่าเดินมาถูกทางแล้ว ไม่งั้นสุดท้ายถ้ายอมให้แก้โน่นแก้นี่ customize ได้เยอะๆก็จะซ้ำรอยความผิดพลาดของ Windows Mobile แต่ถ้าไม่ยอมให้ผู้ผลิต customize อะไรได้เลยก็จะเป็นการปิดโอกาสที่แต่ละรายจะสามารถสร้างข้อแตกต่างให้ผลิตภัณฑ์ของตัวเอง มันเลยควรจะเป็นอะไรกลางๆ

ส่วนตัวมองว่า Google พลาดที่ไปสร้างความคาดหวังว่า Android เป็นระบบเปิดให้ผู้ผลิตแก้ไขอะไรยังไงก็ได้ แต่ตอนนี้พอมีปัญหาเรื่องประสบการณ์ที่ผู้ใช้ที่ซื้อมือถือแปะป้าย “Android” ไป แต่ละคนมันต่างกันมาก เลยพยายามสร้าง policy มาจัดการเรื่องนี้มากขึ้น แฟนบอย Apple ก็เลยด่าเรื่องนี้กันสนุกปาก

ถ้ามองจริงๆพอคนใช้มือถือ “Android by Google” แล้วพบว่ามันห่วย คนที่โดน blame คงไม่ใช่แค่ LG, Samsung, HTC แต่รวมถึง Google ด้วย มันก็เลยต้องมีการควบคุมกันหน่อย

กรณีคล้ายๆกันที่ผมเคยเห็นคือเรื่องของ Firefox กล่าวคือ Mozilla ถือว่า Firefox เป็น trademark ของตัวเอง ดังนั้นถ้าจะเอา code ไป build แล้วเอาไป market ก็ได้ แต่ห้ามมีส่วนประกอบ Firefox ในชื่อเด็ดขาด (ยกเว้นจะเป็น official build ที่ Mozilla เห็นชอบด้วย) ถ้า Google จะเอาวิธีนี้มาใช้ก็น่าจะได้เหมือนกัน ก็แค่ใครจะ customize แบบที่เราไม่เห็นด้วย ก็ห้ามเอาชื่อ Android ไปโปะ แต่แนวทางตอนนี้ดู Google ใจดีกว่านี้นิดนึง (แค่ตัดสิทธิ์ไม่ให้เข้า early access program)

กว่าจะมีโอกาสซื้อเครื่องใหม่คงอีกอย่างต่ำๆสองปี ไว้เจอกันอีกรอบนะหุ่นยนต์เขียว! เขียนไปเขียนมาทำไมเป็นเรื่อง Android วะเนี่ย!!

PS. ว่าจะเขียนเรื่องทำงานครบสองปี คงไม่ได้เขียนวันนี้แล้ว ไว้ก่อนละกัน Smile with tongue out

แบ่งเวลาไม่เป็น

สิ่งดึงดูดความสนใจบนโลกนี้มันเยอะเกินไปครับ

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

แต่พอเริ่มเปิดเทอมแล้วผมจำไม่ได้ว่าทำไมที่บ้าน limit ให้เล่นได้เฉพาะวันศุกร์ เสาร์ อาทิตย์ และ enforce เรื่องนี้อย่างจริงจังมากกกก! เคยกลับมาแอบเล่นอยู่พักนึง แต่โดนจับได้ –*-

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

limit อันนี้มาอยู่ๆก็หายไปตอนประมาณผมอยู่ ป.4 – ป.6 ล่ะมั้ง จำไม่ได้แระ แต่ตอนนั้นก็เริ่มคิดได้อะไรได้บ้าง + เริ่มมีอย่างอื่นให้ pursue เช่นเรื่องการสอบเข้าหรือที่ตอนนั้นเริ่มชอบ math มากขึ้น อะไรพวกนั้น

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

สมัยมัธยมปลาย เริ่มได้ทำกิจกรรมนู่นนี่นั่น เยอะขึ้น (แต่ก็หนีไม่พ้นเรื่อง nerd) ความขยันอ่านหนังสือเรียนลดลง! ตอนนั้นมีเครื่องเกม PS2 ที่เคยอยากได้มาตลอด แต่สุดท้ายก็ได้เล่นเกมนับเป็นเกมคงไม่เยอะเท่า PS1 ส่วนนึงเพราะมันมีอย่างอื่นน่าสนใจ + บันเทิง ให้ทำเยอะกว่าก็เลยเลิกเล่นเกมไปเลย ก

ารแบ่งเวลานับว่าทำได้แย่ รู้สึกได้อ่านหนังสือสอบ Ent (รุ่นสุดท้าย) น้อยมาก มาเร่งอ่านเอาช่วงท้ายๆ โชคดีตกใส่หัวที่ได้โควต้าคอมตรงของโครงการโอลิมปิก ตอนเทอมสองเลยไม่ต้องอ่าน Ent แล้ว –/\- กราบขอบพระคุณ สสวท. และ Turbo C++ เวอร์ชันเถื่อน

สุดท้าย สมัยมหาลัย นับเป็นจุดต่ำสุดของการแบ่งเวลา!

  • ไม่เคยเข้าเรียนฟิสิกส์ 2 … เลย!
  • ไม่ยอมนั่งทำโจทย์เก่าวิชาพวก Calculus เกรดเลยออกมาเน่ามาก (แมวตรึม)! ถ้าอยากไปเรียนสาขาพวก Finance จะไม่ได้ไปก็เพราะไอ่ถั่วงอกพวกนี้แหละ
  • นอนดึก ตื่นเที่ยง เป็นปกติ
  • มีเหตุผลนับล้านให้โดดเรียน
  • ไม่สามารถใช้เวลาว่าง (คาบว่าง วันไม่มีเรียน) ให้เกิดประโยชน์สูงสุดได้
  • ทำตัวเหลวไหล บัดซบ

 

จนตอนนี้มาถึงช่วงการทำงาน แน่นอนว่าพอเริ่มทำงานปุ๊บก็ต้องปรับเวลาในชีวิตอย่างมาก

  • เวลาว่างที่เคยมีเยอะๆเหลือแค่ 2 วันต่อสัปดาห์ + เย็น 5 วัน และให้ลาได้ปีละ 15 วัน
  • ต้องตื่น และไปทำงานเช้าขึ้น (อันนี้ก็ยังต้องพยายามปรับอยู่)

 

เวลาว่างที่เหลือน้อยลงเหล่านี้ก็นำมาใช้ประโยชน์ได้ยาก กลับมาจากที่ทำงานวันธรรมดา ถึงบ้านประมาณ 2 ทุ่ม ก็ไม่อยากทำอะไรแล้ว (กลับช้าเพราะไปสาย) ส่วนวันเสาร์อาทิตย์ก็อยากพักผ่อน … ด้วย internet!

เวลาถูกเผาไปด้วย pattern นี้นับปี … อันนี้เป็นจำนวนการค้นหาด้วย Google ของผม แบ่งตามชั่วโมง ของปีที่ผ่านมา

year

เห็นได้ชัดว่า ไอ่ผู้ชายคนนี้มันใช้ net อะไรเยอะแยะวะเนี่ย! แถมยังมีช่วง ตี 1 – 6 โมงเช้า เป็นจำนวนนึงอีก! อย่าลืมว่านี่มาจาก stat ของผู้ชายที่ทำงาน full-time ตลอดทั้งปี

จนเมื่อเร็วๆนี้เอง ผมเพิ่งย้ายเข้าไป condo ที่ไม่มี net ใช้ แน่นอนว่าเวลาตอนเย็นถูกใช้ไปกับอย่างอื่นที่ไม่ใช่ internet แน่นอน ที่ผ่านมาได้ทำ:

  • ออกกำลังกาย
  • อ่านหนังสือ (มากมายนับไม่ถ้วนใน Kindle)
  • เขียนโค้ด (แบบที่ไม่ต้องถาม Google ตลอดเวลา)
  • นอนฟังเพลง
  • ใช้เน็ตมือถือ (อ่าว เฮ้ย!!!)

 

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

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

month

เสียดายที่ Google ไม่เปิดให้ดูเดือนใดๆ ไม่งั้นคงเทียบกับ pattern การใช้ของตัวเองในสมัยก่อนได้ดีขึ้น

แนะนำ practice นี้ให้ทุกคนที่มีปัญหากับชีวิตและโดน internet ดูดเวลาครับ

เอาจริงๆเร็วๆนี้มีเรื่องให้ต้องติด net ที่คอนโดซะแล้ว ไม่รู้จะกลับไปเป็นแบบเดิมมั้ย T^T

ทดลอง IKVM

IKVM เป็น run-time ที่ใช้แปลง byte code ของ Java ไปเป็น IL บน .NET รวมถึงมี Base Class Library ของ Java ที่ implement เป็น .NET ให้เรียกใช้ด้วย ตอนนี้ใช้งานได้ในสองโหมดคือ

1. เอา IKVM ไปแทน Java ไปเลย สั่งรัน class ของ Java หรือ .JAR ที่ build มาแล้วได้ทันทีบน .NET Framework

2. แปลง byte code ไปเป็น IL ให้เสร้จก่อน แล้วเรียกใช้เหมือน app ปกติ (หรือ add reference ไปในกรณ๊ที่เป็น library)

กรณีทั่วๆไปคงหาโอกาสใช้ให้เกิดประโยชน์ได้ยาก ถ้าโปรแกรมเล็กๆเขียนใหม่จาก Java –> .NET ดูจะเป็นวิธีแก้ปัญหาที่ดีกว่า ถ้าแต่โปรแกรมมันเริ่มซับซ้อนและใหญ่ และการใช้งานจริงๆเราก็มองว่าเป็น black box (give input, get output) แก้ปัญหาโดยใช้ IKVM ก็ไม่เลว เคสของผมคือมันมี logic สำหรับการแกะ format อะไรซักอย่างที่มัน proprietary มากๆ spec ก็คงหาค่อนข้างยาก ให้แกะ spec จากโค้ดลองดูแล้วนิดหน่อยก็คิดว่าคงใช้เวลามหาศาล แต่โชคดีที่มันมี implementation ที่เป็น Java อยู่แล้ว ก็ใช้ IKVM แปลงมาเป็น library ใน .NET แล้วเรียกใช้ได้เลย

ตอนแรกคิดว่าคงมีปัญหาแน่ๆ เพราะ library มันก็ใหญ่มากอยู่ แต่ปรากฎว่าผ่านฉลุยตั้งแต่รอบแรกอย่างน่าตกใจ o__o! วันนี้กลับมาบ้านเลยมาลองกับ project วิชา programming methodology ที่เคยเขียนเป็น game คู่กับแบงค์ ทิ้งไว้เมื่อตอนปีสอง ถ้าวัดในแง่ขนาดของโค้ดคงเล็กกว่าที่แปลงก่อนหน้านี้หลักร้อยเท่า แต่เนื่องจากมันเป็น game เลย depends on libraries หลายตัว อาทิ:

  • Swing ทำ GUI
  • อ่านเขียนไฟล์
  • Audio เล่นเสียง
  • คลาสพวกจัดการ Image
  • Math
  • อ่าน Image จากไฟล์ใน JAR (เทียบได้กับ Resource ล่ะมั้ง)
  • ..

รัน

ikvmc CPLander100.jar

ได้มาเป็น CPLander100.exe ผลคือ

  • Start up นานได้ใจ (เกือบ 3 วินาที)
  • เปิดเมนูหน้าแรกได้ ใช้ได้ Hooray!
  • In game ใช้ได้ แต่ออกมาเมนูข้างนอกอีกรอบไม่ได้ T_T
  • เสียงหาย
  • ช้ากว่ารันด้วย Java มาก (สมเหตุสมผล)
  • Component ของ Swing ที่ใช้ทำงานถูก
  • พวก Math มีคำนวณพลาดจน paint ภาพผิดตำแหน่ง คิดว่าน่าจะเกิดจากตอนเขียนโค้ดไม่ระวังเรื่องพวกใช้ floating point (มั้ง)

 

ถึงจะรันได้ไม่ perfect แต่โดยรวมถูกใจ IKVM มาก ว่างๆไปหาโอกาสเล่นกันดู ยกนิ้วให้คนทำ –/\-

IKVMx

ประสบการณ์ Heisenbug

รู้จักคำนี้ครั้งแรกมาพักนึงแล้ว สั้นๆคือ Heisenbug เป็น bug ที่ตรวจไม่เจอหรือ reproduce ไม่ได้ถ้าพยายามจะ debug มัน … อึ้ยยย ฟังก็งงแล้วว่ามีจริงเหรอวะของแบบนี้ ชื่อก็ตั้งตาม Heisenberg คนที่คิด “หลักความไม่แน่นอนของไฮเซนเบิร์ก” ที่เคยเรียนในฟิสิกส์แหละครับ เนิ้ดร้องอ๋อแน่นอน

นอกจากนี้ยังมี bug อื่นๆ ที่จัดว่าเป็น bug แบบ “แปลกๆ” อีก แปลมาให้ฟังเล่นๆดังนี้

Bohrbug – นานๆเป็นทีนึง แต่ condition แน่นอน มักจะเกิดกับ condition ที่ rare มากๆ ส่วนใหญ่มักจะโผล่มา say hi บน production และเราก็จะหาไม่เจอว่า condition อะไรที่มัน trigger อาการนี้ออกมา – -‘

Mandelbug – ต้นเหตุของปัญหาซับซ้อนมาก จนมองจากภายนอกแล้วเหมือนจะไม่มี pattern อะไรแน่นอนที่ทำให้เกิดปัญหานี้เลย ซึ่งปัญหาอาจเกิดจากการ interact กับระบบภายนอกระบบอื่น หรือว่ามันอาจใช้เวลานานกว่าปัญหาจะฟักตัวออกมาให้เห็นนับจากตอนที่มีการ execute อะไรบางอย่างผิดๆ

Schrödinbug – ปัญหาที่ไม่เคยปรากฎตัวเลย จนมีคนไป observe source code แล้วพบว่ามันผิด! อันนี้มันเป็นเรื่องที่เกี่ยวกับแนวคิดของ quantum นิดๆ คนสายเราน่าจะเคยอ่านเรื่อง แมวของชโรดิงเจอร์ มาบ้าง อันนี้เป็นเรื่องเดียวกัน แต่ผมนึกสถานการณ์ตัวอย่างไม่ออก .. เท่าที่คิดก็คงแบบว่าพวก hacker ที่อ่าน source code แล้วพบว่ามันผิด ก็เลยไป exploit ซะเองล่ะมั้ง ..

Phase of the Moon bug – อันนี้เกิดจากการคาดการณ์ว่า bug ตัวนึงจะเกิดขึ้นเนื่องจากปัจจัย A,B,C แล้วก็พยายาม isolate ปัญหาโดยลองกับปัจจัย A,B,C ทีละตัว … ทั้งๆที่จริงๆแล้ว A,B,C ไม่ได้เกี่ยวข้องกับปัญหาเลย ทำให้สุดท้ายแล้วหาสาเหตุไม่เจอซักที … อันนี้ลองมองเทียบกับเรื่อง ดูลายนิ้วมือ หรือ โหงวเฮ้ง ก็พวกดูดาวแล้วเอาไปเป็นสัญญาณ trade หุ้น คล้ายๆกัน

Statistical bug – เป็นประเภทที่ไม่สามารถมองเห็นปัญหาได้จากการรันทดสอบเพียงครั้งเดียว ตัวอย่างที่วิ่งขึ้นมาในใจตัวอย่างแรกคือเรื่องการการเขียนโปรแกรม shuffle ไพ่ ซึ่งเป็นโปรแกรมที่เขียนให้ผิดได้ง่ายมากเพราะบางทีผลการสับไพ่หลายๆครั้งอาจจะไม่กระจายออกมาในทุกรูปที่เป็นไปได้แบบ uniform … พูดง่ายๆคือสับออกมาแล้วออกมาแบบนี้บ่อยกว่าอีกแบบนึงอะไรแบบนั้น อ่านมาจาก http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html

Noob bug (or Noobug) – เป็นอะไรที่ง่ายมาก แต่นู้บหาสาเหตุไม่เจอ อันนี้เจอเองบ่อย (ฮาาา) ยกตัวอย่างซะหน่อย มือใหม่อาจแปลกใจว่าทำไมโปรแกรมข้างล่างถึง print ออกมา 101 ตลอด กะจะเขียนโปรแกรม 1 + 2 + 3 + 4 + … + 100 ไปส่งคุณครูซะหน่อย Smile with tongue out

int increment, sum = 0;
for (increment = 1; increment <= 100; ++increment) ;
sum += increment;

Console.WriteLine(sum);

ส่วนเคส Heisenbug ที่เจอ โค้ดมันเป็นประมาณนี้ (C#)

public class MyEventGen { }

class Program
{
public static void Main()
{
var gen = new MyEventGen();
var wr = new WeakReference(gen);

// run the collector
GC.Collect();
while (true)
{
Thread.Sleep(1000);
Console.WriteLine(wr.IsAlive);
}
}
}

ถ้าเอาไปรันแบบ Debug หรือ Release ใต้ Visual Studio โปรแกรมจะ print True ออกมาตลอด (การใช้ WeakReference ไปชี้แล้วตรวจ IsAlive บอกได้ว่าโดน Garbage Collector เก็บไปรึยัง) … แต่ถ้ารันนอก Visual Studio (without debugging) จะกลายเป็น False ตลอดทันที ตอนแรกก็เลยไม่รู้จะ debug ยังไง

ตามความเข้าใจผมตัวแปร gen ควรจะยังมี reference อยู่ตลอดเวลาเพราะยังไม่ออกจาก scope Main เลย … ซึ่งถ้าตาม syntax มันก็เป็นแบบนั้น คือผมสามารถเขียนโค้ดเพื่อ access ตัวแปร gen ได้ภายใน scope Main … แต่ run-time behavior มันไม่ได้เป็นแบบนั้น เพราะ GC ใน Release mode มันค่อนข้าง aggressive มาก เลยเก็บตัวที่ไม่ได้ใช้เรียบ T_T อันนี้ส่วนหนึ่งโดนฝังแนวคิดมาจาก C++ ด้วย เพราะปกติพวก object ที่ alloc ไว้บน stack จะโดน destruct ตอนออกจาก scope … ซึ่งมันไม่เหมือนกับภาษาที่มี GC.

อันนี้ตอนแรกมองว่าเป็ Heisenbug แต่จริงๆมองเป็น Noob bug ก็ถูก เพราะถามปุ๊บมีคนตอบทันที!! Open-mouthed smile http://stackoverflow.com/questions/4757869/is-this-com-object-subject-to-garbage-collection

เรื่อง bug ส่วนใหญ่ก็แปลมาจาก http://en.wikipedia.org/wiki/Unusual_software_bug ใครเจอเคสอะไรแปลกๆมาแชร์ให้ฟังหน่อยก็ดี อยากฟังครับ

รีวิว Kindle DX Graphite

รีวิวนี้เหมาะกับคนกลั่นข้อมูลมาเต็มที่แล้วนะครับ อะไรที่มันซ้ำๆกับรีวิวอันอื่นจะละๆไปละกัน

ในที่สุดกิเลสที่สั่งสมมายาวนานของผมก็ก่อตัวเป็นรูปร่างของแข็งครับ TvT จุดประสงค์หลักๆเลยที่ซื้อมาคือเพื่อจะเอามาอ่าน PDF ที่เก็บๆไว้มากมาย ยังไม่ค่อยสนใจจะซื้อของจาก store ของ Amazon เท่าไหร่ ส่วน 3G ถึงจะแถมมาให้ฟรี แต่ก็ด้วยข้อจำกัดของตัวจอ E-ink ที่ refresh ช้ามากรวมถึงตัว web browser บน Kindle DX นั่นแหละ ที่ทำให้การเล่นเน็ตบน DXG ไม่ค่อยสะดวกสบายเท่าไหร่ เหมือนเค้าตั้งใจให้เอาไว้แค่เวลาซื้อหนังสือผ่าน Kindle จะได้ง่ายๆมากกว่า ขอสรุป requirement ของตัวเองดังนี้

  • เอามาใช้อ่านไฟล์ PDF เป็นหลัก ส่วนใหญ่เป็นหนังสือวิชาการ บทความ เอกสารประกอบซอฟแวร์ การ์ตูนบ้างบางเวลา
  • ไม่ได้พกไปข้างนอกมากเท่าไหร่ อ่านบนโต๊ะบนเตียงที่บ้าน
  • ยังไม่ค่อยสนใจซื้อหนังสือผ่าน Kindle store
  • 3G มีก็ดี เผื่อเอาไว้ไปเช็คเมล์ขำๆไม่ต้องเสียตังค์

มีคนถามบ่อยว่าทำไมไม่เอา iPad เปิด PDF ได้เหมือนกัน หลักๆเลยคงเป็นเรื่องจอ E-ink นี่ล่ะครับ

หลังจากอ่าน review มาหลายเจ้าก็ได้ข้อสรุปว่า ถ้าจะเอามาอ่านหนังสือ PDF นั้น ควรจะเป็นจอขนาด 9.7” ของ DXG เท่านั้นครับ (จอเล็กมันเล็กไป) ปรึกษาคนโน้นคนนี้อยู่หลายวันว่าจะสั่งยังไงให้มันถูกๆดีหว่า สุดท้ายก็ไม่ได้ทำไร –_-‘ สั่งตรง Amazon โดน Tax เต็มๆ ส่วนตัวก็รู้สึกอุ่นใจกว่านะที่มันมาส่งให้ถึงบ้านเลยไม่ต้องทำ action อะไรแล้ว แต่ถ้าคิดเป็นเม็ดเงินก็ >_<” (อยากจะร้องไห้)

เวลาจัดส่งประมาณ 4 วัน (คลิกดูรูปใหญ่) ติดตามผ่านเว็บ DHL ได้ตลอด (มันมี tracking number ให้) ดูผ่านเว็บจากที่ทำงานว่าพี่ที่บ้านเซ็นรับให้แล้วก็อุ่นใจ .. แต่ก็แอบไม่มีสมาธิทำงาน ฮ่าๆๆ

00_DELIVER

เข้าเรื่องตัวของเล่นกันเลยดีกว่า

จอ E-ink

เปิดกล่องมาครั้งแรกเห็นมันมีพลาสติกใสทับเครื่องอยู่แล้วก็มี instruction สอนให้เสียบปลั๊กแบบโน้นแบบนี้ ตอนแรกนึกว่า instruction มันเป็นหมึกพิมพ์ลงบนพลาสติกใส ปรากฎว่ามันเป็นรูปจากจอ E-ink ว่ะ o__o’ โอ้! ใช้ได้ๆ บางคนพอได้ยินคำว่า E-ink หรือจอกระดาษ อาจจะงงว่าแล้วมันต่างจากจอคอมหรือ iPad ยังไง? อ่านในที่มืดได้รึเปล่า? คำตอบคือมันไม่เหมือนกัน แล้วมันอ่านในที่มืดไม่ได้ครับ แต่ถ้าอยากอ่านก็ต้องเอาไฟฉายมาส่งเหมือนกระดาษ อ่านที่แดดจ้าไม่มีปัญหา (แต่อยู่เมืองไทยใครจะไปอ่านกลางแดด ….)

จอของ DX ขนาด 9.7” ตามแนวแทยงมุม (เหมือนเวลาบอกขนาด TV)  หรือ 20 x 14 cm

Pixel Count:
1200 x 825 (SVGA)

Active Area:
202.9 x 139.5 mm
246.38 mm (9.7") diagonal

DPI:
150

ส่วนจอ Kindle 3 (Kindle ตัวใหม่ที่จะออกปลายสิงหานี้) ขนาด 9 x 12 cm ผมแนะนำว่าให้ตัดกระดาษออกมาขนาดเท่านี้ดู ถ้าอยากรู้ว่ามันเล็กเกินไปรึเปล่า

Pixel Count:
800 x 600

Active Area:
122.4 x 90.6 mm
152.3 mm (6") diagonal

DPI:
166

อีกเรื่องนึงที่มารู้ไม่นานก่อนซื้อเครื่องคือ ตัว firmware ของ Kindle มันจะทำหน้าที่ตัดขอบขาวๆของ PDF ออกให้ด้วย โอ้ววว >_< พูดง่ายๆคือไม่ต้องทำอะไรกับ PDF เลย แค่โยนลงเครื่องแล้วตอน display มันก็จะไม่แสดงขอบขาวๆพวกนี้ให้เห็น เป็นการใช้พื้นที่หน้าจออย่างมีประสิทธิภาพ ดังนั้นขนาด 20 x 14 หรือ 9 x 12 cm อาจจะเทียบตรงๆกับขนาดกระดาษไม่ได้ ให้มองเฉพาะส่วนที่เป็น text (ถ้าจะเปรียบเทียบ)

ผมประทับใจจอมากๆ วันที่สองที่ได้มา อ่าน pocket book เล็กๆไปประมาณ 2 – 3 ชม. ไม่ล้าเหมือนอ่านหน้าคอมเลย

01_DXG_VS_A4

สีขาวเป็นกระดาษ A4

06_SHADE

เฉดสีเทามี 16 ระดับ

ปุ่ม

ตอนแรกคิดว่าจะเป็นปุ่มหยาบๆ (แบบกดแล้วไม่ค่อยนุ่มเท่าไหร่ เหมือน Mouse) แต่พอลองของจริงแล้วมันก็นุ่มระดับนึงนะครับ แต่ก็ไม่ได้ดีมาก

และเนืองจากจอ E-ink ที่มัน refresh ช้าด้วยนี่แหละ เลยทำให้บางทีเวลาพิมพ์หรือเลื่อน cursor หรือกดปุ่มอะไร มันจะตอบสนองไม่ค่อยทันใจเรามาก แต่ก็ไม่ได้รู้สึกว่ารำคาญกับเรื่องนี้มากนะ

keyboard ถือแล้วใช้นิ้วโป้งพิมพ์ไม่ได้ อันนี้เคยอ่านมาจาก review อันอื่นเหมือนกัน แต่ผมคงไม่ได้พิมพ์อะไรบ่อยๆอยู่แล้ว ยกเว้นเวลาจะ jump ไปยังหน้าที่ระบุ หรือเวลาจะ search ใน PDF ถ้าอยากพิมพ์จริงๆควรจะตั้งกับพื้นแข็งๆแล้วพิมพ์

ปัญหาตลกๆอีกอย่างคือเวลาจะพิมพ์ตัวเลขต้องกด Alt ก่อน = =’ อันนี้แอบลำบากจริงเพราะต้องใช้บ่อย

03_KEYBOARD

น้ำหนัก

หนักประมาณ 0.5 kg เบากว่า iPad ขีดนึง เพื่อนผมบอกว่าถือนานๆคงเมื่อยมือ หนักไป ใหญ่ไป แต่ผมไม่มีปัญหากับข้อจำกัดเรื่องนี้เพราะว่ากะจะใช้ที่บ้านอยู่แล้ว เนื่องจากจอมันค่อนข้างจะใหญ่ด้วย กลัวพอไปมากระแทกแล้วแตก

3G

ฟรี ช้า และไม่บันเทิง

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

มีคนถามมาบ่อยว่าแล้วมันใช้ 3G ผ่านเครือข่ายของใคร? AIS, True, DTAC? อันนี้ก็ไม่รู้เหมือนกัน รู้แต่เคยเห็นเว็บที่มันแกะเครื่องออกมา ข้างในจะมีซิมจาก Amazon ใส่มาอันนึง (เปลี่ยนเองไมได้)

การใช้งาน PDF

มีเรื่องที่งงๆกันเกี่ยวกับ Kindle และ PDF อยู่หลายอย่าง

  • Firmware Kindle ปัจจุบันใช้ zoom PDF ได้แล้ว แต่ก็เพราะจอ E-ink มัน refresh ช้าจัด บางทีจะให้มา zoom บ่อยๆมันก็ไม่สะดวกนะ (ยกเว้นเป็นพวก map ที่นานๆใช้ทีนึง)
  • ภาษาไทยหรือภาษาอะไรก็ตามใน PDF จะอ่านได้เสมอ ตามที่ผมเข้าใจคือ ส่วนใหญ่เอกสารที่เป็น PDF มันไม่ต้องใช้ข้อมูลพวก font จากข้างนอกมา render
  • ปรับขนาด font ใน PDF ไม่ได้แน่นอน ถ้าเป็น E-reader รุ่นอื่นอย่างเช่นของ Sony จะมีฟังก์ชันที่เรียกว่า reflow (แต่ก็ไม่ควรไปคาดหวังว่ามันจะทำงานได้ดี) แต่หนังสือและเอกสารส่วนใหญ่ผมเปิดใน DXG แล้วได้ font ที่ขนาดกำลังดี อ่านได้นะครับ ยกเว้นบางเล่มจริงๆที่รู้สึกว่ามันเล็กไปมากๆ หรือไม่ก็เล่มที่ขอบหนังสือมันไม่ขาวหมดจด มีขอบโน่นขอบนี่ตัว firmware เลยตัดไม่ได้
  • ถ้าเป็นหนังสือที่ซื้อจาก Amazon จะทำ text to speech ได้, take note ได้, เปลี่ยนขนาด font ได้ แต่ถ้าเป็น PDF ดาดๆ จะทำอะไรพวกนี้ไม่ได้เลย

ลองมาดูตัวอย่าง

04_AI_CHART

05_MANGA

05_MANGA_ZOOM

อันนี้เป็นอีกปัญหาที่หลายคนเจอเหมือนกัน คือ font ที่เป็นสีๆ บางทีพอมาดูบน Kindle แล้วสีมันจะเทาอ่อนเกินไป ทำให้อ่านไม่ออก

08_CODE 

09_CODE_NORMAL

บางไฟล์ตัวอักษรจะเล็กเกินไปจริงๆ แต่ถ้าพลิกเป็นแนวนอนก็จะใหญ่ขึ้นพออ่านได้เหมือนรูปด้านล่าง

10_HOR

สรุป คือผมพอใจกับมันนะครับ รู้สึกขอขวดที่ขวางผมกับ PDF ที่มีบน harddisk มันหายไปเกือบหมด >_< (เว่อซะ)  ค่อนข้างมั่นใจว่านี่จะไม่ใช่ E-reader เครื่องสุดท้ายที่จะซื้อในชีวิตนี้ มันมีตลาดตรงนี้จริงๆซึ่งตอนนี้อาจจะยังไม่ใหญ่ แต่คงไปได้อีกไกล

ข้อเสียส่วนใหญ่ก็เป็นเรื่องที่รู้มาจาก review อื่นแล้วเกือบจะทั้งหมด ไม่เจอเรื่อง surprise อะไรพิเศษ

ถ้าพยายามกว่านี้คงสามารถหาวิธีสั่งซื้อที่มันถูกกว่านี้ได้ เช่น ฝากเพื่อนที่ US หิ้วหรือหาคนที่เค้ารับส่งของจาก US มาให้ ในกรณีของผมที่สั่งตรงกับ amazon จะโดน tax ไปเยอะมากกกก…ก (โดนตัดไปตั้งแต่ตอนสั่งผ่านเว็บ) ถือว่าเป็นค่าขี้เกียจละกัน แต่ก็สบายใจดีในแง่ที่ว่าถ้าเปิดกล่องแล้วจอมันแตก ก็คงโวยกับ customer service ได้อย่างสะดวกใจ เสียตังค์กับของเล่นชิ้นนี้ไปเยอะเหมือนกัน TvT ขออนุญาตไม่คูณเป็นเงินบาท

34260_423955127256_637427256_5086573_7611058_n

รายละเอียดเพิ่มเติมไปดูที่หน้าสินค้า คนแถวนี้ใครจะซื้อมาคุยกันก่อนก็ดี :’P

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

วิธีคำนวณ ROA ในเว็บ SET

เพิ่งอ่านหนังสือเล่มแรกจบใน Kindle ไปได้ไม่นาน (The Little Book that beats the market) หนังสือมันสอนวิธีกรองหุ้นง่ายๆโดยใช้ reuturn on capital + earning yield แต่วิธีที่หนังสือมันใช้คำนวณสองค่านี่มันต้องใช้ค่าดิบๆบางอย่างจากงบการเงิน ซึ่งหามายากพอควร ( .. แปลว่า automate ไม่ได้ ..) ผมเลยลองมาดูๆค่าที่ใช้แทนได้ใกล้เคียงที่สุดแทนและมีบนเว็บ SET คือ ROA (return on assets – ผลกำไรต่อสินทรัพย์) และ ROE (return on equity – ผลกำไรต่อส่วนผู้ถือหุ้น)

 

ค่าสองตัวนี้ควรจะหาได้ง่ายๆ Wikipedia กล่าวว่า

ROA_FORM

แต่ทำไปทำมาปรากฎว่าคำนวณแล้วไม่เห็นจะตรงกับที่เขียนไว้ในเว็บเลยว่ะ ….’’ นั่งงงอยู่นาน

FS

จากรูป ถ้าจะหา ROA ปี 2009 (ปี 2010 ยังได้ข้อมูลไม่ครบ เด๋วจะงง) จะได้ 10190.22 / 115698.28 = 8.8076 %  … ไม่เห็นจะตรงกับ 13.33 % เลยอ้ะ

ถามอากู๋คนเดิมได้ความจากกระทู้ในพันทิบว่า SET มันใช้วิธีคำนวณคนละวิธี ใช้เป็น ROAA (return on average assets) แทน

ROAA = EBIT of nth year  / (0.5 * (NET assets n-1th year + NET assets nth year))

ตัวย่อแปลกๆในข้อความนี้อีกตัวคือ EBIT (Earnings before interest and taxes) ซึ่งเป็นกำไรแบบที่ยังไม่ได้คิดดอกเบี้ยเงินกู้กับภาษี ถ้าดูจากตารางข้างบนจะเห็น กำไร/ขาดทุน = 10,190.22 ล้านบาท แต่ถ้าไปเปิดงบกำไรขาดทุนละเอียดดูแล้วจะได้ EBIT = 14,878.46 ล้านบาท

INCOME

สุดท้ายเอาไปคำนวณ 14878.46 / ((115698.28 + 107510.00) / 2) ~ 13.3 % ตรงแล้ว

วันนี้แมงเม่าหนุ่มจึงอ่านงบการเงินเป็นมากขึ้นพอสมควรหลังจาก trade มานานเกือบปีแล้ว จดไว้นิดนึงเผื่อมีคนงงเหมือนกัน

หลักๆ หนังสือเล่มที่อ่านมันสอนให้ดูค่าพวกนี้เพื่อบอกว่าหุ้นตัวไหนน่าซื้อแบบ relative เค้าบอกว่าการทำนายอนาคตหรือราคาที่เหมาะสมนี่มันไม่ใช่เรื่องที่ใครๆก็จะทำได้ง่ายๆ แล้วหุ้นที่ undervalued แบบที่ Ben Graham เจ้าพ่อ VI ชอบซื้อปัจจุบันมันก็ไม่ได้เจอได้ง่ายขนาดนั้นอีกแล้ว ดังนั้นเรามาดูข้อมูลปีล่าสุดกันดีกว่า … ใครสนใจลองหาไปอ่านกันดู