หน้าเว็บ

วันจันทร์ที่ 10 ธันวาคม พ.ศ. 2555

วิธี get ค่า Window ID บน Ubuntu

บน Ubuntu นั้นถ้าเราต้องการดู Window ID ทั้งหมดที่เปิดอยู่เพื่อให้ไป focus ที่ window นั้นๆสามารถทำได้ง่ายโดยใช้ tool ชื่อ wmctrl โดยติดตั้งผ่าน apt-get ได้เลยดังนี้

sudo apt-get install wmctrl
หลังจากติดตั้งแล้วก็หารายชื่อ window ที่เปิดอยู่ทั้งหมดด้วยคำสั่ง wmctrl -l
จะแสดงรายชื่อและ id ของ window ทั้งหมดขึ้นมา

วันพุธที่ 8 กุมภาพันธ์ พ.ศ. 2555

วิธีสร้าง Category Page ที่รวม Label (Tag) สำหรับ Blogger เวอร์ชันใหม่


หลายๆคนคงอยากทำหน้า blog ที่มีการแบ่ง Category ของ post ต่างๆขึ้นมาเป็น Tab ด้านบนเฉพาะ โดยในแต่ละ Tab ก็รวมรวม post ต่างๆที่ถูกแปะ Label ที่เกี่ยวข้องมาแสดงไว้

จริงๆแล้ว Blogger ไม่ได้มีฟังก์ชันให้ทำแบบนี้โดยตรง แต่เราก็มี workaround ให้สามารถทำได้อยู่เหมือนกันครับ

ใน Blogger เวอร์ชันใหม่ (กันยา 2011+) จะมีปุ่มสร้าง Page มาให้โดยอัตโนมัติ (อยู่ใน Dashboard จะมีให้เลือก Pages อยู่)



ซึ่งเราจะใช้หน้า Page นี่ล่ะมาทำเป็น Category Page ที่รวบรวม Post ที่ถูกแปะ Label ที่ตรงกับ Category

Page ของ Blogger ถูกออกแบบมาไว้ให้ทำได้ 2 อย่าง คือ 1. Static (Blank) Page หรือหน้าเพจนิ่งที่เราสร้างขึ้นมาเอง (โดยใช้ HTML หรือ Editor ของ Blogger ก็ได้) และ 2. Web Address หรือทำไว้สำหรับ link ไปยังหน้าเว็บอื่น วิธีของเรานั้นจะใช้ Web Address นี่ล่ะครับมาทำหน้า Category กัน

มาเริ่มกันเลย
1. เริ่มจากดูก่อนว่า Label ที่เราอยากนำไปสร้างเป็น Category นั้นมี URL อะไร วิธีง่ายๆคือไปกดที่ Label ที่ต้องการแล้วมันจะพาเราไปหน้าค้นหา Label นั้น โดย URL จะอยู่ในรูป
http://yourdomain/search/label/yourlabel
โดย yourdomain แทนด้วยชื่อเว็บของคุณ ส่วน yourlabel ก็แทนด้วยชื่อ Label ที่ต้องการ
เช่น หน้า TinyOS ของผมก็จะเป็น http://ping2p.blogspot.com/search/label/tinyos
* สังเกตว่าชื่อ Label มีตัวอักษรใหญ่เล็ก แต่ใน URL จะเป็นเล็กหมด ให้ยึดตาม URL ครับ

ให้ทำการ copy URL นี้เก็บไว้ก่อน เดี๋ยวจะเอาไปใช้





2. ทำการเพิ่มหน้า Page โดยไปที่ Dashboard -> Pages -> New page -> Web address
ส่วน Page Title ให้ใส่ชื่อ Category ที่ต้องการ เช่น ผมใส่ว่า TinyOS
ส่วน Web address (URL) ให้ใส่ URL จากหน้าค้นหา Label ที่ได้มาในข้อหนึ่ง เช่น http://ping2p.blogspot.com/search/label/tinyos
เสร็จแล้วกด Save จะมีรายการที่เราเพิ่มขึ้นมาเรียบร้อย อย่าลืมสั่งให้แสดงผลโดยเลือก Show pages as เป็น Top tabs (หรือถ้าชอบไว้ด้านข้างก็เป็น Side links) เสร็จแล้วให้เลือก Save arrangement ทางขวาบน





จริงๆถึงขั้นตอนคือเสร็จเรียบร้อยแล้ว ให้ลองกลับไปดูหน้าเว็บหลักของคุณดูจะพบว่ามี Tab เพิ่มขึ้นโดยเป็น Category ที่เราตั้งไว้ ถ้าคลิกปุ๊ปก็จะไปหน้าที่รวบรวม Post ที่ตรงกับ Label ไว้ให้ แต่ว่ามันยังมีความไม่สวยอยู่คือมันจะขึ้นว่า "แสดงบทความที่มีป้ายกำกับ yourlabel แสดงบทความทั้งหมด" หรือ "Showing posts with label yourlabel Show all posts"  ตรงด้านบนติดมาด้วย ดังนั้นเราจะมาลบมาออกกัน



3. กลับไปที่ Dashboard แล้วไปที่ Template จะแสดงหน้า Template ที่เราใช้อยู่ปัจจุบัน ให้เราเลือก "Backup / Restore" ทางขวาบน แล้วกด "Download full template" เพื่อดาวน์โหลดไฟล์ template นามสกุล .xml มาเก็บไว้ในเครื่องเรา


4. ให้ทำการ copy ไฟล์นี้เพิ่มเก็บไว้เป็น backup ก่อน เผื่อมีอะไรผิดพลาดจะได้ใช้ไฟล์นี้กู้คืนกลับมาได้

5. เมื่อมั่นใจว่ามี backup แล้ว เราจะแก้ไขไฟล์นี้กัน โดยใช้ text editor ที่ชอบอะไรก็ได้ เปิดมันขึ้นมา
ค้นหาเนื้อหาในไฟล์ที่เป็นรูปแบบดังนี้

<code>
<b:includable id='status-message'>
  <b:if cond='data:navMessage'>
    <div class='status-msg-wrap'>
      <div class='status-msg-body'>
        <data:navMessage/>
      </div>
      <div class='status-msg-border'>
        <div class='status-msg-bg'>
          <div class='status-msg-hidden'><data:navMessage/></div>
        </div>
      </div>
    </div>
    <div style='clear: both;'/>
  </b:if>
</b:includable>
</code>

ให้แก้เป็นดังนี้

<b:includable id='status-message'>
  <b:if cond='data:navMessage'>
    <div>
    </div>
    <div style='clear: both;'/>
  </b:if>
</b:includable>

(คือทำให้ส่วน div ใน if cond เหลือเป็น div เปล่าๆ ใครอยากเก็บโค้ดไว้ดูก็ใช้ !-- เพื่อคอมเมนต์ของเก่าไว้ก็ได้)
เสร็จแล้วบันทึกไฟล์

6. ในหน้า Backup / Restore เดิม ตรงส่วน Upload a template ก็ให้ browse เลือกไฟล์ที่ได้แก้ไขเรียบร้อยแล้ว upload กลับขึ้นไป ก็เรียบร้อย (ในกรณีที่อยากจะ restore ไฟล์เดิมที่ copy เก็บไว้ก็ทำเหมือนกัน)



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



อ้างอิง
http://blogger-hints-and-tips.blogspot.com/2010/12/how-to-put-put-posts-into-your-pages-in.html
http://www.spiceupyourblog.com/2010/01/remove-showing-posts-with-label-message.html

วันอาทิตย์ที่ 16 ตุลาคม พ.ศ. 2554

วิธีแก้บั๊ก TinyOS two source files specified (PLATFORM_MICAZ and BOARD_MICASB) make: *** [exe0] Error 1

ปัญหาเกิดจากผมทำการอัพเดท Ubuntu 11.04 ไปเป็น 11.10 พออัพเดทแล้วลองคอมไพล์โปรแกรมปรากฏว่าคอมไพล์ไม่ผ่านโดยขึ้น error ประมาณนี้ครับ

two source files specified (PLATFORM_MICAZ and BOARD_MICASB)
make: *** [sim-exe] Error 1


ซึ่งตัว PLATFORM_ กับ BOARD_ อาจเป็นอื่นๆได้ เช่น PLATFORM_IRIS เป็นต้น

ปัญหานี้เกิดจากการที่ gcc ถูกอัพเกรดเป็นเวอร์ชัน 4.6 ซึ่งจะถูกเรียกใช้ในขั้นตอนของการคอมไพล์ TinyOS โปรแกรม

ปัญหาคือ gcc 4.6 จะเพิ่ม space 1 ตัว ไประหว่าง option -D กับ argument ทำให้ปกติแล้วในของเก่า gcc จะสร้าง -DPLATFORM_MICAZ กับ -DBOARD_MICASB ออกมา เพื่อให้ nescc (nesC compiler) เอาไปใช้งานต่อ แต่ของใหม่จะสร้าง -D PLATFORM_MICAZ กับ -D BOARD_MICASB ออกมาแทน ซึ่งทำให้ nescc คอมไพล์ไม่ได้และเกิด error ดังข้างบน

วิธีแก้คือ
1) ดาวน์โหลด nescc ตัวใหม่มา (ของผมที่ใหม่สุดคือ 1.3.2) http://sourceforge.net/projects/nescc/files/nescc/v1.3.2/nesc-1.3.2.tar.gz/download?_test=goal

2) แตกไฟล์ออกมา แล้วไปแก้ source code ที่ไฟล์ nesc-1.3.2/src/nesc-compile

3) หาบรรทัด

($i, $idir) = &extractarg($i);
push @nesc_args, "-I$idir";
}
elsif (/^-o/) {
($i, $objtarget) = &extractarg($i);
}


แก้โดยเพิ่มอีกเงื่อนไขไปเป็น

($i, $idir) = &extractarg($i);
push @nesc_args, "-I$idir";
}
elsif (/^-D/) {
($i, $ddef) = &extractarg($i);
pop @nesc_args;
push @nesc_args, "-D$ddef";
}
elsif (/^-o/) {
($i, $objtarget) = &extractarg($i);
}


4) เสร็จแล้วให้ออกมาที่โฟลเดอร์หลัก nesc-1.3.2 ทำการคอมไพล์โค้ด

./configure
make
sudo make install


5) ลองทดสอบดูว่า nescc ตัวใหม่ติดตั้งแล้วหรือยังโดยสั่ง

ncc --version

ผลลัพธ์ควรจะแจ้งเวอร์ชันของ nescc ออกมาเป็น 1.3.2

ถ้ายังไม่เป็นให้เรา move binary ใหม่ไปแทนเอง

sudo cp /usr/bin/nescc /usr/bin/nescc.old
sudo cp /path/to/nesc-1.3.2/tools/nescc /usr/bin/nescc


6) เมื่อเสร็จแล้วก็ลองสั่งคอมไพล์ TinyOS โปรแกรมใหม่อีกรอบ เช่น

make micaz sim

ก็น่าจะคอมไพล์ผ่านเรียบร้อย

ระบบที่ทดสอบ
OS: Ubuntu 11.10
TinyOS: 2.1.1
ncc: 1.2.4
gcc: 4.6.1
nescc: 1.3.2

อ้างอิง
http://sourceforge.net/tracker/index.php?func=detail&aid=3153727&group_id=56288&atid=480036

วันอาทิตย์ที่ 9 ตุลาคม พ.ศ. 2554

วิธีการหา replace บรรทัดที่ขึ้นต้นด้วย pattern ด้วยข้อความใหม่

สมมติว่ามีไฟล์นึงอยู่ชื่อว่า file.txt โดยมีเนื้อหาดังนี้

hello world
how are you
hello man
Long time no see
no hello


ถ้าเราอยากจะเอาคำว่า "Hi" ไปแทนในทุกบรรทัดที่ขึ้นต้นด้วยคำว่า "hello" สามารถทำได้โดยใช้คำสั่ง sed ดังนี้


sed "s/^hello.*\$/Hi/" file.txt > temp
mv temp file.txt


คราวนี้เมื่อเปิดไฟล์ใหม่เนื้อหาก็จะถูกเปลี่ยนเป็น

Hi
how are you
Hi
Long time no see
no hello


โดย s หมายถึง search and replace
^hello.*\$ หมายถึงขึ้นต้นด้วย hello ไปจนสุดบรรทัด
Hi หมายถึงคำที่จะนำมา replace

ระบบที่ทดสอบ
OS: Ubuntu 11.04

วันเสาร์ที่ 10 กันยายน พ.ศ. 2554

วิธีแก้ไข Metadata Title ของไฟล์ PDF

ถ้ามีไฟล์ pdf แล้วอยากแก้ไข metadata เช่น Title ของไฟล์สามารถทำได้ง่ายๆโดยใช้ Tool ชื่อ exiftool

เวลาใช้งานก็สั่งดังนี้
exiftool -Title="New Title" filename.pdf

วันพุธที่ 1 มิถุนายน พ.ศ. 2554

วิธีใช้ latex สร้างไฟล์ pdf โดยให้ embed font ติดไปด้วย

ผมมีปัญหาว่าเขียนไฟล์ .tex (latex) แล้วพอจะคอมไพล์เป็นสกุล .pdf แล้วมันไม่ยอม embed font บางตัวติดไปให้ โดย font ส่วนใหญ่ที่ไม่ embed ติดไปให้นั้นจะเป็น font พวก Base 14 ได้แก่
ผมจึงนำวิธีที่แก้ไขปัญหานี้มาเขียนไว้ครับ (ผมใช้ latex, dvips, ps2pdf)

1. ทำการคอมไพล์ไฟล์ .tex ให้ได้เป็นไฟล์ .dvi
latex filename.tex

2. หลังจากนั้นแปลงไฟล์ .dvi ให้เป็นไฟล์ .ps
dvips filename.dvi

3. สุดท้ายก็แปลงเป็น .pdf
ps2pdf -dPDFSETTINGS=/printer -dEmbedAllFonts=true filename.ps


จุดสำคัญคือข้อ 3 ครับ ตรง -dPDFSETTINGS ถ้าเกิดผมไม่ใช่ option นี้เข้าไป ตรงส่วน -dEmbedAllFonts จะไม่ทำงาน ซึ่งผมคิดว่าค่า default ของ -dPDFSETTINGS ในเครื่องผมเป็น screen ไม่ใช่ printer ซึ่ง screen จะทำให้ EmbedAllFonts เป็น false โดยอัตโนมัติ

สำหรับการตรวจสอบว่า Font ได้ถูก embed เข้าไปรึยังนั้นให้ใช้คำสั่ง
pdffonts filename.pdf
โดยดูชื่อ Font ที่ใช้ และดูที่คอลัมน์ emb ว่าเป็น yes

ส่วนวิธี embed font ด้วยโปรแกรมและระบบปฏิบัติการอื่นดูเพิ่มเติมได้จาก
http://www.sas.upenn.edu/computing/help/students/dissertation-pdf



ระบบที่ทดสอบ
OS: Ubuntu 11.04
latex: TexLive 2009 (pdftex 3.1415926-1.40.10-2.2)
dvips: 5.98
ps2pdf: 9.01

ที่มา
http://www.sas.upenn.edu/computing/node/1225/
http://ismir2005.ismir.net/pdf.html

วันจันทร์ที่ 23 พฤษภาคม พ.ศ. 2554

Double.NaN == Double.Nan ได้ false !!!

วันนี้เพิ่งรู้ว่า Double.NaN == Double.Nan จะได้ค่าเป็น false เสมอ (ทดสอบในภาษา Java)

ขอสรุปวิธีแก้ปัญหาไว้ตรงนี้เผื่อคนขี้เกียจอ่านครับ
ถ่าจะทดสอบว่าค่าหนึ่งๆเป็น NaN รึเปล่าจะใช้ x == Double.NaN ไม่ได้ แต่สามารถใช้ Double.isNaN(x) ได้แทน (ภาษา Java)


ส่วนคำอธิบายขอก๊อปปี้จาก twitter ตัวเองมาแปะตามลำดับเวลาล่ะกัน (ขี้เกียจเรียบเรียงเช่นกัน :P)

- ที่ไม่เท่ากันเกิดจากคอมไพเลอร์ทำตามมาตรฐาน floating point IEEE 754 ที่บอกว่า NaN ไม่เท่ากับ NaN

- จริงๆแล้ว bit pattern ที่ represent ค่า NaN นั้นไม่ได้มีค่าเดียว แต่มีเป็น range เลย

- โดย Double.NaN จะไปเรียกเมธอด Double.longBitsToDouble(0x7ff8000000000000L) ซึ่ง 0x7ff8000000000000L เป็น bit pattern หนึ่งที่เป็นไปได้

- ซึ่งถ้าดูผิวเผินแล้วเหมือนว่า Double.NaN กับ Double.NaN ก็น่าจะได้ค่าเดียวกัน เพราะส่ง bit pattern เดียวกันเข้าไป

- (เสริม NaN มี 2 แบบถ้า bit ขึ้นต้นด้วย 0 คือ signaling NaN (sNaN)ถ้าขึ้นต้นด้วย 1 คือ quiet NaN (qNaN) ดังนั้น 0x7ff8000000000000L คือ sNaN)

- ซึ่งถ้า sNaN ถูกกระทำการทางคณิตศาสตร์แล้วค่าจะเปลี่ยนเป็น qNaN ซึ่งค่าไม่เท่าเดิม

- ในขณะที่บางโปรเซสเซอร์ เพียงแค่มีการ copy ค่า (ในระดับโปรเซสเซอร์) ก็จะทำการแปลงค่าทันที

- นอกจากแปลงประเภทแล้ว bit pattern ก็อาจเปลี่ยนไปใน range ของ NaN ที่มีอยู่

- ดังนั้นการเรียก Double.NaN หรือ Double.longBitsToDouble(0x7ff8000000000000L) ก็อาจจะได้ค่า NaN ในรูปแบบ double ที่มีbit patternไม่เหมือนเดิม

- ดังนั้นถ่าจะทดสอบว่าค่าหนึ่งๆเป็น NaN รึเปล่าจะใช้ x == Double.NaN ไม่ได้ แต่สามารถใช้ Double.isNaN(x) ได้แทน (ภาษา Java)

อ้างอิง
Javadoc
- http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Double.html#NaN
- http://download.oracle.com/javase/6/docs/api/java/lang/Double.html#longBitsToDouble(long)

IEEE 754 Standard
- http://en.wikipedia.org/wiki/IEEE_floating-point_standard
- http://en.wikipedia.org/wiki/NaN
- http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=4610935&con=yes&userType=inst