Saturday, March 05, 2005
Web Form โดยไม่ใช้ Table tag
http://www.themaninblue.com/writing/perspective/2004/03/24/
อยากทำ form โดยไม่ใช้ table tag มานานแล้ว
พอแยก Semantic ออกจาก presentation แล้ว code
clean ขึ้นเยอะ
Related link from Roti
Azureus Stat Component
ชอบใจตรงหน้าจอ Statistic ที่แสดงผลเป็น graph หน้าตาสวยงาม
เนื่องจากช่วงนี้พัฒนา Eclipse plugin อยู่ ก็เลยสนใจ UI ของคนอื่น
ที่พัฒนาด้วย SWT หรือ JFace

azureus stat view

เกิดความสงสัยว่า เขาใช้ opensource library ในการทำ graph
หรือเปล่า ถ้าใช่จะได้เอาไปใช้บ้าง ก็เลยเข้าไปดู source code
ปรากฎว่าเขา implement เอง ไม่ได้ใช้ library ของใคร
เท่าที่ดูก็ออกแบบ clean ดี
แบ่ง package เป็นส่วน View กับ Component
ตัว View จะ delegate ให้ component ทำหน้าที่ render
ในที่นี้ก็คือ
ActivityView delegate ให้ SpeedGraphic รับหน้าที่ render

Class Diagram

Note ไว้กันลืม เพื่อ project ไหนต้องการ monitor tool จะได้
มีตัวอย่างไว้ Assign
Related link from Roti
Thursday, March 03, 2005
ทดลองใช้ JGAP
JGAP เป็น genetic algorithms component
ไปได้ยินโจทย์่ว่า
เดิมในฐานข้อมูลลูกค้า อนุญาติให้ลูกค้าเลือก bank
ได้มากกว่า 1 bank ปัจจุบันต้องการเปลี่ยนให้ลูกค้า
ใช้ได้เพียง bank เดียวเท่านั้น
ปัจจุบันมีลูกค้าประมาณ 400000 ราย
มีจำนวน bank อยู่ 6 bank
ต้องการให้ computer ทำการเลือกธนาคารให้ลูกค้า
โดยให้แต่ละธนาคารได้จำนวนลูกค้าไปเท่าๆกัน
หลังจากได้ยินโจทย์ก็เกิด idea อยากลองใช้ JGAP solve
Step 1.
เริ่มแรกสุดที่ต้องทำการก็ออกแบบ Chromosome ว่า
จะประกอบด้วย Gene อะไรบ้าง
ลองกำหนดให้ Gene หนึ่งๆ คือ รูปแบบการเลือกธนาคาร
bank-> A B C D E F
รูปแบบที่ 1 1 0 0 0 0 0
รูปแบบที่ 2 0 1 0 0 0 0
....
รูปแบบที่ 64 1 1 1 1 1 1
ดังนั้นใน 1 chromosome จะมี gene ยังสิ้น 64 gene
จากนั้นก็เขียนโปรแกรมให้อ่านข้อมูล Raw Data
ทำการนับจำนวนคน โดย group ตาม pattern
ตัวอย่างการนับที่ได้
010011=>6370 (มีคนที่เลือกธนาคาร B, E, F ทั้งหมด 6370 คน)
ค่า 6370 จะเป็น constrain ของ Gene นั้น
ที่จะสามารถ distribute จำนวนคนไปยัง bank B หรือ E หรือ F
รวมแล้วไม่เกิน 6370 คน
ข้อมูลใน gene 1 gene ประกอบด้วย
- constrain (ข้อมูลนี้ fix ไ่ม่เปลี่ยนไปในแต่ละรุ่น)
- pattern การเลือก bank
- จำนวนคนทั้งหมดที่เลือก bank ตาม pattern นี้
- data (ข้อมูลนี้จะเปลี่ยนไปเรื่อยๆ เมื่อ evolution ไปยังรุ่นต่อไป)
- ข้อมูลจำนวนคนที่แต่ละ bank ได้รับ
implement random method ของ Gene
ในตอนเริ่มต้น chromosome แต่ละ chromosome
จะถูกสร้างโดยการ random ขึ้นมา
ดังนั้นต้อง implement method นี้ให้ gene แต่ละ gene
ทำง่ายๆโดยใช้วิธี random ไปเลยว่าแต่ละธนาคารจะได้รับแจกคนไปเท่าไร
Step 3.
implement Mutation mehod ของ Gene
ทำง่ายๆโดย สุ่มโอนคนระหว่าง ธนาคารภายใน Gene นั้นๆ
Step 4.
ออกแบบ Fitness Fuction โดยถ้า chromosome ไหนได้แต้มสูง
chromosome นั้นก็มีโอกาสอยู่รอดสืบลูกสืบหลานได้
ทำง่ายๆ โดย จำนวนคนที่แต่ละธนาคารได้ ต้องไกล้เคียงกับ
400000/6 (จำนวนคนทั้งหมด/จำนวนธนาคาร)
ยิ่ง chromosome ไหนเข้าไกล้ค่าอุดมคติก็ยิ่งได้ค่าสูง
ในการ Run
สิ่งที่ต้องกำหนดก็คือ จำนวน Population ที่ใช้
จำนวนครั้งของการ evolution ที่เกิด
เลือกใช้ Population -> 500
evolution -> 10 รุ่น
ได้ผลลัพท์ดังนี้
ธนาคาร A ได้คนไปทั้งสิ้น 64162,
ธนาคาร B ได้คนไปทั้งสิ้น 65580,
ธนาคาร C ได้คนไปทั้งสิ้น 66109,
ธนาคาร D ได้คนไปทั้งสิ้น 63307,
ธนาคาร E ได้คนไปทั้งสิ้น 66026,
ธนาคาร F ได้คนไปทั้งสิ้น 68684,
เวลาในการ run = 7370 ms
ตัวอย่าง ผลลัพท์การ distribute
pattern จำนวนรวม A B C D E F
-------------------------------------------------------
111010=>6311 1337,1116,1913,0,1945,0,
001100=>6393 0,0,1161,5232,0,0,
010000=>6125 0,6125,0,0,0,0,
100100=>6422 1396,0,0,5026,0,0,
000011=>6398 0,0,0,0,82,6316,
สรุป
ผลลัพท์ที่ได้ยังไ่ม่น่าพอใจนัก
คงจะเป็นผลจากการออกแบบ fitness function ,
mutation method
ที่ยังไม่ค่อยดีนัก
่
ทดลองเปลี่ยนค่า จำนวน evolution
พบความประหลาดใจว่า จำนวนรุ่นยิ่งสูง
ผลลัพท์ยิ่งผิดผลาดมากขึ้น
สงสัยเราออกแบบ fitness function ผิดแน่ๆเลย
ไว้ถ้ามีโอกาสได้ data จริง ก็จะลอง
run ดูกับ data จริงดูว่าจะได้ผลลัพท์เป็นอย่างไร
(คิดว่ารูปแบบการเลือกธนาคารใน data จริง
จะมีลักษณะเฉพาะมากกว่า data test ที่เกิด
จากการ random)
Related link from Roti
Monday, February 28, 2005
GeoPhrase - Get a GeoPhrase on your page
"Ary you from Bangkok"
ก็เลยสงสัยว่าเขา integrate logic เข้าไปใน blogger อย่างไร
ดูใน html ก็พบ tag
Are you from
ที่แท้เป็นบริการของ
GeoPhrase - Get a GeoPhrase on your page
แต่เขาบอกว่าบริการนี้จะมี ad ด้วย
ก็คือ 1 ใน 50 ครั้งจะเกิดการ open ad
แต่ก็จำกัดว่า ip หนึ่งจะเกิด Ad ได้ไม่เกิน 1 ครั้งต่อ 1 วัน
รู้สึกว่า Service เล็กๆน้อยๆเหล่านี้มีเยอะขึ้นทุกวัน
Related link from Roti
CSDL - Software Tools and Services - Jupiter
CSDL - Software Tools and Services - Jupiter
Related link from Roti
Sunday, February 27, 2005
อยากขี่จักรยาน !!!
วนไปทาง ม.เกษตร
ค่อยรู้สึกหายอยากหน่อย
เดิมทีมีนัดขี่จักรยานกับพี่ๆปีละ 1 ครั้ง
เป็น trip ขี่รอบประเทศไทย
(ทำมาได้ 2 ปีแล้ว ปีแรกขี่จากกรุงเทพ ไป อุบล
ปีที่ 2 อุบลไปนครพนม)
ปีนี้เริ่มต้นที่นครพนม เลาะลำโขงขึ้นไปต่อ
ติดว่ามีลูกอ่อน
หวังว่าปีหน้าแม่เด็กจะลาพักร้อนมาเลี้ยงลูกแทน
http://www.thaimtb.com/cgi-bin/viewkatoo.pl?id=45141
Related link from Roti
Saturday, February 26, 2005
Federated Identity Management
SourceID | SAML, Liberty Alliance, WS-Federation | Federated Identity Management
Related link from Roti
Friday, February 25, 2005
ทบทวน Antlr
วันนี้แกะ code Jakarta Slide ส่วน Client command line tool
พบว่าใช้ Antlr ช่วยเขียน เลยขอ note ทบทวนเกี่ยวกับ Antlr หน่อย
เนื่องจากห่างหายไม่ได้ใช้มา 2-3 ปีแล้ว
เวลาเราเขียน Gramma spec ด้วย Antlr
เราจะเขียนผ่าน file ที่มีนามสกุล .g โดยเราสามารถเขียน Lexer, Parser
แล้วก็ Tree Parser จากนั้นก็จะใช้ Ant ช่วย
compile ให้กลายเป็น java file อีกที
ในส่วน Slide Client command line จะใช้เฉพาะ Lexer และ
Parser เมื่อ parser parse ได้ ก็จะเกิด Action เลย ไม่ได้มีการสร้างเป็น Abstract
Syntax Tree แต่อย่างไร
Lexer Spec
class ClientLexer extends Lexer;
// ------------------------------------------------------------ options section
options {
k = 2;
caseSensitiveLiterals = false;
charVocabulary = '\u0003'..'\uFFFF';
}
// ------------------------------------------------------------- tokens section
tokens {
EXIT = "exit";
QUIT = "quit";
BYE = "bye";
HELP = "help";
....
}
//---------------------------------------------------------------- lexer rules
WS : (
' '
| '\t'
)
{
_ttype = Token.SKIP;
}
;
EOL // the end of line
: "\r\n" // DOS
| '\r' // MAC
| '\n' // UN*X
;
// Backslashes are accepted by CHARS,
// but STRING replace them into slashes !!
STRING
: ( CHARS (CHARS | '-')*
| '"'! ( ~'"' )* '"'!
)
{ String txt = $getText;
txt = txt.replace('\\', '/');
$setText(txt);
}
;
protected
CHARS
: 'a'..'z'
| 'A'..'Z'
| '0'..'9'
| '.'
| ':'
| '/'
| '$'
| '#'
| '%'
| '&'
| '('
| ')'
| '!'
| '+'
| '\\'
| '_'
;
....
ส่วนที่อยู่ในเครื่องหมายปีกกาเรียกว่า action
ซึ่งจะถูกแปลงเป็น java code ตรงๆ ใน Lexer class
และจะถูกเรียกทำงานเมื่อ lexer recognize rule ส่วนนั้น
สังเกตุได้ที่ STRING lexer rule เมื่อ lexer
จับได้ว่าเป็น String token
ก็จะทำการแปลงเครื่องหมาย \\ ให้เป็น /
ส่วน protected ที่นำหน้า Rule นั้น
เนื่องจาก Antlr แปลง rule ทุกตัวให้เป็น java method
ดังนั้นคำว่า protected ก็คือบอกให้ method
ที่ gen ออกมามี scope เป็น protected
k=2 ก็คือ บอกว่า Look ahead เท่ากับ 2
Parser Spec
class ClientParser extends Parser;
// ------------------------------------------------------------ options section
options {
k = 2;
exportVocab = Slide; // call this vocabulary "Slide"
defaultErrorHandler = false; // abort parsing on error
// TODO: use a tree-parser rule
// buildAST = true; // build tree construction
buildAST = false; // uses CommonAST by default
}
// Java code
{
// ------------------------------------------------------------- properties
/**
* The Slide WebDAV client.
*/
protected Client client;
// --------------------------------------------------------- helper methods
/**
* Set a client.
*
* @param client a client
*/
void setClient(Client client) {
this.client = client;
}
// --------------------------------------------------------------- parser rules
commands
: {
client.prompt();
}
( command
{
client.prompt();
}
)+
;
exception catch [ANTLRException ex] {
// XXX bad hack for bug #28100
if (ex.toString().indexOf("null") != -1) System.exit(-1);
// handle parse errors gracefully
client.print("Error: "+ex.toString());
}
command
:
( exit
| help
| invalid
| nothing
| spool
| run
| echo
.... (ตัดออก)
| commit
| abort
)
;
help
: ( HELP
| QUESTION
)
EOL
{
client.help(null);
}
;
exception
catch [RecognitionException ex]
{
printUsage("help");
}
connect
: ( CONNECT
| OPEN
)
uri:STRING
EOL
{
client.connect(text(uri));
}
;
exception
catch [RecognitionException ex]
{
printUsage("connect");
}
จะเห็นได้ว่าเราสามารถ embed method setClient
เพื่อที่เราจะได้ set helper class ลงไปได้
โดยเมื่อ parser recognise syntax ได้
ก็จะมีการทำ action (ส่วนที่อยู่ในเครื่องหมายปีกกา)
ซึ่ง implement ในลักษณะ delegate
ต่อไปยัง Client class อีกที
กฎง่ายๆของการเขียน Parser Rule ก็คือ
ถ้าเขียนตัวใหญ่หมด อันนั้นคือ token
ส่วนถ้าเป็นตัวเล็ก ก็หมายถึง sub rule
action code สามารถอ้างถึง token value
ได้โดยใส่ ชื่อตัวแปรตามด้วย colon
นำหน้า token ดังจะเห็นได้ในตัวอย่างของ
connect rule ซึ่งเขียนกฎ token STRING
-> uri:STRING
ข้อดีของ Antlr คือเมื่อแปลงเป็น java code แล้วก็ยังอ่านง่าย, debug ง่าย
ตัวอย่างของ code ที่ gen ออกมาในส่วนของ rule connect
public final void connect() throws RecognitionException,
TokenStreamException {
Token uri = null;
try { // for error handling
{
switch ( LA(1)) {
case CONNECT:
{
match(CONNECT);
break;
}
case OPEN:
{
match(OPEN);
break;
}
default:
{
throw new
NoViableAltException(LT(1), getFilename());
}
}
}
uri = LT(1);
match(STRING);
match(EOL);
client.connect(text(uri));
}
catch (RecognitionException ex) {
printUsage("connect");
}
}
Related link from Roti
ส่วน Search และ Index ของ Slide
วันนี้ลองไล่ดู wiki และ source code ของ Slide ในส่วน
Index และ Search ดู ได้ความเบื้องต้นดังนี้
กรณี Search
ในส่วนของ WebDAV protocol Slide support DASL Extension
แต่ไม่พบเอกสารว่า support แค่ไหนอย่างไร มิหนำซ้ำ
DASL Spec. จริงๆแล้วก็ยัง
เป็นแค่ Draft
version
อยู่ แต่ถ้าพูดถึงในแง่ว่าเพียงพอต่อการใช้งานธรรมดาแล้ว
หรือยัง ก็ถือว่าเพียงพอแล้ว
กรณี Index
ตัว Slide เองถ้าติดตั้งแบบ default จะไม่มีการทำ index เก็บไว้
แต่ถ้ามี search method ส่งเข้ามา
ก็จะใช้วิธี search หากับเนื้อข้อมูลจริงเลย
กรณีที่เราต้องการทำ
Index. Slide ก็ bundle
Basic Index feature มาให้เรา 2 กรณีคือ
- ทำ index ในส่วน MetaData ของ Resource
- ทำ index ในส่วน Content
Note: ทั้ง 2 กรณีนี้ใช้ lucene เป็น engine
กรณีที่ทำ index ในส่วน MetaData ถือว่ายังอยู่ในขั้นทดลอง
จะ release จริงใน version 2.2
ส่วนกรณี content indexer ที่มีมาให้ ก็เป็น simple case
ถ้าจะใช้จริงต้อง implement เพิ่มเติมเอง
ถือว่ามี source ให้ดูเป็นแนวทางเท่านั้น
Feature ที่เกี่ยวเนื่องกับเรื่องนี้อีกอันก็คือ Extractor
เดิมเข้าใจว่า feature นี้น่าจะใช้กรณีที่เราต้องการ automatic สร้าง
metadata จากเนื้อ content เลย (เรียก PropertyExtractor)
แต่ใน source code เห็นมี Indexer ตัวหนึ่งเรียกใช้ตรงๆ จาก ExtratorManager เลย
เข้าใจว่าเป็นส่วนเพิ่มมาที่หลัง (เรียก ContentExtractor)
ใช้ extract เฉพาะส่วนที่สมควรทำ index ออกมาจากเนื้อ content
โดย slide มี extractor ให้ดังนี้
- excel
- word
- powerpoint
วิธีที่กะว่าจะใช้
- ใช้ PropertyExtractor สำหรับ extract content ออกมา
- ใช้ Property Indexer ทำ index แบบ asyncronous
สิ่งที่ต้อง check ต่อก็คือ ลำดับของ slide ในการเรียก extractor กับ
เป็นไปตามที่เราคิดไว้หรือไม่
Related link from Roti
Tuesday, February 22, 2005
Jakartal Slide Performance & websphere problem issues
1. maximum file per Directory
1.1 Files Directory ต้องแนะนำให้ user จัด folder โดยคำนึงถึง limit ด้วย
(maybe 500)
1.2 History Directory ต้องเพิ่ม
parameter name="history-collection-hack"
ใน Configuration Element
เพื่อให้ file structure กระจาย ไม่เช่นนั้นจะ slide จะเก็บ history file ไว้
ใน directory เดียว
2. Memory Leak ที่ต้องทำให้ re-start server บ่อยๆ
issue นี้มีพูดถึงใน this tread
3. jdom.jar ใน Websphere 5.0 กับ Slide conflict กัน (look at this thread)
4. Slide on Websphere มีหลาย tread ที่ระบุปัญหา Authenticate
แต่ถ้าดูใน thread นี้ก็ชัดเจนดี คงต้องทดสอบอย่างเดียว
5. มีคนพูดถึง performance issue กรณีที่ว่า slide เหมาะสำหรับ
light to medium load เท่านั้น
ให้ check user requirement ด้วย
6. ปัญหาเรื่อง config servlet (look at this thread)
เห็น issue ก็เหนื่อยแล้ว
Related link from Roti
Cutom authentication for Slide
RE: Cutom authentication for Slide
ในประเด็น client ที่ไม่ใช่ browser นั้น ต้องขอ Ticket จาก CAS มาให้ได้ก่อนแล้วค่อยใช้
CasProcessingFilter.CAS_STATELESS_IDENTIFIER เป็น principal
(อ่านได้ใน reference guide)
Related link from Roti
Monday, February 21, 2005
Sunday, February 20, 2005
slide admin
web ซึ่งภายในมี admin application ออกไป แต่ไปเพิ่ม admin app ใน
framework ที่ชื่อ projector ซึ่งไม่มีเอกสารอธิบายเลย จึงต้องแกะเอาเอง
ในส่วนของ projector จะใช้ concept workflow โดยมองเป็น process
ย่อยๆ หลายอัน ซึ่งแต่ละอันก็จะมี step ต่างๆ เท่าที่ดูก็ยังมีปัญหาต้องแก้อีก
พอสมควร (tag version พึ่งจะ 0.1)
ดังนั้นปัญหาตอนนี้ก็คือ จะทำ admin ด้วยอะไรดี
ตัว DAVExplorer ก็มีข้อเสียว่า ถ้าจะ config ส่วน security
ก็ต้องใช้วิธี manual config เอาเอง
ส่วน WebDAVPilot มีส่วน ACL ที่ทำค่อนข้างดีแล้ว แต่ขาดตรง
ไม่มี source code provide มาให้ ทำให้ไม่สามารถ extend ได้
ทางเลือกเร็วสุดตอนนี้ก็คือ ใช้ tapestry + lib WebDAVClient
Related link from Roti
Blue Gate Crossing
ขนาดดูครั้งที่ 2 ก็ยังซึ้งอยู่เหมือนเดิม หนังเรื่องนี้เล่าเรื่องได้ดีจริงๆ
ดำเนินเรืองสบายๆ (เหมือนจังหวะของชีวิตจริง ไม่มีการเน้นเกินจริง)
ยิ่งรู้โครงเรื่องทั้งหมดแล้วเห็นรายละเอียดที่นักแสดงแสดงออกมา
แถมยังเป็นการแสดงทีดูเป็นธรรมชาติมาก ไม่รู้ว่าคนอื่นเป็นเหมือนเราบ้างหรือเปล่า
ดูแล้วรู้สึกเหมือนหัวใจพองโต เหมือนมีอะไรอัดแน่นอยู่ข้างใน
มีความรู้สึกเอ่อท้นออกมา (บอกไม่ได้นะว่าเป็นความรู้สึกประเภทไหน
มันมีส่วนผสมระหว่าง ความสุข ความเศร้า และก็ผสมความเหงา)
แถมตอนจบยังได้ฟังเพลงโปรดอีกต่างหาก
(อิ่มอกอิ่มใจจริงๆ)


