PyICU

หลังจากพยายามนั่งทำ Binding ของ libthai ให้เป็น Python อยู่หลายวัน พบว่ามีคนทำ PyICU อยู่ก่อนแล้ว T_T แต่ก็นับว่าได้ความรู้การใช้งาน Python ระดับล่างๆ ได้ดีขึ้นเยอะ

pyicu

ถึงตอนนี้โครงการ ZWSP คงเห็นทางเสร็จทันปลายปี

Bug

As I’m working in my personal project about Thai language. I try to learn GUI programming with wxPython anf face some problem in following code.

[ftf w=”400″ h=”300″ def=”python.xml”]#!/usr/bin/env python

-- coding: utf-8 --

generated by wxGlade 0.4 on Tue Mar 21 20:06:06 2006

import wx import codecs

class MainFrame(wx.Frame): def init(self, *args, **kwds): # begin wxGlade: MainFrame.init kwds[“style”] = wx.DEFAULT_FRAME_STYLE wx.Frame.init(self, *args, **kwds)

    # Tool Bar
    self.wdMainFrameToolBar = wx.ToolBar(self, -1)
    self.SetToolBar(self.wdMainFrameToolBar)
    self.wdMainFrameToolBar.AddLabelTool(wx.NewId(), "Auto", wx.Bitmap("C:\\Documents and Settings\\Wason Lewlompaisal\\My Documents\\My Download\\more-smilies\\tango\\dialog-information.png", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_CHECK, "Break Thai Word Automatic", "")
    self.wdMainFrameToolBar.AddLabelTool(wx.NewId(), "ShowZWSP", wx.Bitmap("C:\\Documents and Settings\\Wason Lewlompaisal\\My Documents\\My Download\\more-smilies\\tango\\applications-multimedia.png", wx.BITMAP_TYPE_ANY), wx.NullBitmap, wx.ITEM_CHECK, "Show Zero Width Space in Text Box", "")
    # Tool Bar end
    self.SingleTextControl = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE)

    self.__set_properties()
    self.__do_layout()

    self.Bind(wx.EVT_TOOL, self.OnAutoWordBreak, id=-1)
    self.Bind(wx.EVT_TOOL, self.OnShowZWSP, id=-1)
    self.Bind(wx.EVT_TEXT, self.OnTextChange, self.SingleTextControl)
    # end wxGlade

def __set_properties(self):
    # begin wxGlade: MainFrame.__set_properties
    self.SetTitle("Thai Input Demo")
    self.SetSize((400, 300))
    self.wdMainFrameToolBar.Realize()
    # end wxGlade

def __do_layout(self):
    # begin wxGlade: MainFrame.__do_layout
    MainGridSizer = wx.GridSizer(1, 1, 0, 0)
    MainGridSizer.Add(self.SingleTextControl, 0, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
    self.SetAutoLayout(True)
    self.SetSizer(MainGridSizer)
    self.Layout()
    # end wxGlade

def OnAutoWordBreak(self, event): # wxGlade: MainFrame.<event_handler>
    print "Event handler `OnAutoWordBreak' not implemented!"
    allText = self.SingleTextControl.GetValue()
    print "ALLTEXT>>", repr(allText)
    event.Skip()

def OnShowZWSP(self, event): # wxGlade: MainFrame.</event_handler><event_handler>
    print "Event handler `OnShowZWSP' not implemented!"
    event.Skip()

def OnTextChange(self, event): # wxGlade: MainFrame.</event_handler><event_handler>
    sentence = self.ExtractCurrentSentence()
    print "Current Sentence::", sentence.encode("utf-8")

def ExtractCurrentSentence(self):
    allText = self.SingleTextControl.GetValue()
    print "ALLTEXT>>", repr(allText)
    curPos  = self.SingleTextControl.GetLastPosition()
    sentenceList = allText.split(u" ")
    for word in sentenceList:
        print word.encode("utf-8"), "==>", len(word)
    runPos = 0;
    curSentence = 0;
    while (True):
        if (len(sentenceList[curSentence]) + runPos > curPos - 1):
            break
        runPos += len(sentenceList[curSentence]) + 1
        curSentence += 1
    return sentenceList[curSentence]

end of class MainFrame

class ThaiBreakApp(wx.App): def OnInit(self): wx.InitAllImageHandlers() wdMainFrame = MainFrame(None, -1, “”) self.SetTopWindow(wdMainFrame) wdMainFrame.Show() return 1

end of class ThaiBreakApp

if name == “main“: app = ThaiBreakApp(0) app.MainLoop() [/ftf]

Program seems to be fine at start but when some of That character appear in the TextCtrl the EVT_TEXT which call function OnTextChange just stop working, all thing back to work properly again when all those character removed.

After hours of debugging and searching for information about unicode bug in wxWindows, I noticed that there’s python exception in SPE’s shell. This bug is nothing but SPE’s coding without aware of non-latin chracter.

I’m going to happily sleep now.

Bug

ด้วยเหตุผลบางประการ เวลาพิมพ์ตัวอักษรที่ wxPython ไม่ชอบ เช่น “ฟ” มันจะทำให้ EVT_TEXT เดี๊ยงสนิท ไม่ทำงานอีกเลยจนกว่าจะลบตัวที่มันไม่ชอบออกหมด

ไม่รู้ว่าบั๊กหรือคนใช้โง่เองกันแน่ฟ่ะ

Decimal

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

print (0.05 + 0.05 == 0.1) True

เมื่อการทำงานในขั้นต้นทำงานดี โปรแกรมเมอร์อาจจะเชื่อว่าส่วนนี้ทำงานถูกต้องดี จนกระทั่งการทำงานในแบบที่คล้ายๆ กันมีการทำซ้ำจำนวนมากๆ เช่น

d1 = 0.0 for i in range(1000): d1 += 0.0001 print repr(d1) 1.0000000000000007 print (d1 == 1.0) False

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

ใน Python 2.4 เป็นต้นมา มีการอิมพลีเมนต์เอกสาร PEP-327 ซึ่งเป็นสเปคของเลขทศนิยมฐานสิบ ที่ทำงานในส่วนนี้ได้ถูกต้องกว่า อย่างในตัวอย่างต่อไปนี้

dec1 = Decimal("0.0"); for i in range(1000): dec1 += Decimal("0.001") print repr(dec1) Decimal("1.000") print (dec1 == Decimal("1.0")) True

เท่านี้เราก็จะได้การทำงานที่เป็นไปตามคาดโดยไม่ต้องกังวลความไม่แน่นอนของโปรแกรมอีกต่อไป