Wednesday, May 30, 2007

中文分词模块 from Huang Jiahua

#!/usr/bin/python

# -*- coding: UTF-8 -*-
# Author: Huang Jiahua
# Last modified: 2004-08-25

__revision__ = '0.1'

#切分关键字,要求预先转换为 Unicode 类型
# 分开中文,非中文 -> 按 seps 列表分隔 -> 对中文二元分词 -> 合并 -> 返回数组

import sys
##sys.setappdefaultencoding('utf8')

#分隔关键字列表 seps 设置
seps=[]
seps=[" ","\t","\n","\r",",","<",">","?","!",
";","\#",":",".","'",'"',"(",")","{","}","[","]","|","_","=",
" ",",","?","。","、",""",""","《","》","[","]","!","(",")"]
# Unicode 编码的分隔关键字列表
def _utuni(strr):return unicode(strr,'utf8')
seps=map(_utuni,seps)

##_alkeys={}
_zhkeys={}
_askeys={}
# _zhstr , _asstr 存储 中文,非中文 数组
_zhstr = []
_asstr = []

def _zhsplitkey(stri):
# 对 stri 二元分词法
#存入全局字典 _zhkeys
global _zhkeys
ln = len(stri)
if ln == 1:
return stri
#拆分中文关键字,二元分词法
n = 0
while n < ln-1:
_zhkeys[stri[n]+stri[n+1]] = ''
n = n+1
## return keyy.keys()

def _fenzhas(stri):
# 分开中文和非中文,
# 存入全局数组 _zhstr , _asstr
global _asstr
global _zhstr
ln = len(stri)
_zhstr = []
_asstr = []
n = 0
m = 0
try:
stri[n] >= u'\u4e00'
except:
return 0

while n < ln:
if stri[n] >= u'\u4e00':
if m==0:_zhstr.append(' ')
_zhstr.append(stri[n])
## print 'z:',stri[n]
m=1
else:
if m==1:_asstr.append(' ')
_asstr.append(stri[n])
## print 'a:',stri[n]
m=2
n+=1
## print 'zh:',''.join(_zhstr)
## print 'as:',''.join(_asstr)

def _fenseps(stri):
# 按 seps 列表分隔, 返回分隔后数组
global seps
alkeys={}
n = 0
m = 0
ln=stri.__len__()
while n if stri[n] in seps:
alkeys[stri[m:n]]=''
m=n+1
n+=1
if n>m:alkeys[stri[m:n]]=''
return alkeys.keys()

def splitkey(stri):
"""Split the keys

Split the keys."""
# 接受 str 返回分词后数组
global _zhstr
global _asstr
global _zhkeys
global _askeys
_zhkeys = {}
_askeys = {}
_zhstr = []
_asstr = []
_fenzhas(stri) #分开中文,非中文,存入数组 _zhstr , _asstr
zhstr= _fenseps(''.join(_zhstr))
asstr= _fenseps(''.join(_asstr)) #?
_zhstr = []
_asstr = []
for i in zhstr:
_zhsplitkey(i) #中文分词放入字典 _zhkeys
for i in asstr:
_askeys[i]=''

alkeys = {}
alkeys.update(_zhkeys)
alkeys.update(_askeys)
_zhkeys = {}
_askeys = {}
return alkeys.keys()

if __name__=="__main__":
# 命令行测试
import sys
# sys.setappdefaultencoding('unicode')
enc = sys.stdin.encoding
if len(sys.argv) > 1:
keyy = sys.argv[1]
else:
keyy = sys.stdin.read()
## keyyy = splitkey(keyy.decode(enc))
keyyy = splitkey(keyy.decode('utf8'))
for i in keyyy:
## print i.encode(enc),
print i.encode('utf8'),

Monday, May 28, 2007

FreezePython with QT4

FreezePython -OOc --include-modules=sip --install-dir=dist_linux/dist2 --init-script=ConsoleSetLibPath ingc.py

Sunday, May 27, 2007

How to support input method in KDE/Qt application.

Author: Takumi ASAKI

Sometimes additional code is necessary to support input method in KDE/Qt application. This document will explain what's input method and how to support input method.

What's input method?

Input method is system to help user's keyboard input. Using input method, user can input characters that can not input from keyboard directly, and reduce cost of keyboard input. Input method is necessary for the user wants to input CJK(Chinese, Japanese, and Korean) and other language's characters.

In X Window System, XIM(X Input Method) is standard input method. Qt and KDE support XIM. But XIM is legacy system and lacks some features modern input method should have.

So, the input method systems other than XIM are developing now. IIIMF(Internet Intranet Input Method Framework), UIM(Universal Input Method), and SCIM(Smart Common Input Method platform).

Gtk+ supports these input methods using immodule. Qt supports only XIM. But immodule for Qt project tries to introduce immodule to Qt.

What's immodule?

immodule is plugable module for input method. It supports several input methods and can change input method dynamically.

Original Qt(without immodule patch) supports XIM only. So, user has to use XIM-bridge(ex. htt, uim-xim) when user wants to use the other input method. But with immodule patched Qt, user can use favorite input method directly.

Qt4(next major version of Qt) will take the result of the immodule for Qt project, and support immodule. If developer wants to support input method correct, sometimes some input method related code is necessary.

When do you need writing code to support input method?

case A)

Your application doesn't need input text.

You don't need to do anything.

case B)

Your application need input text. And you use only input widget in KDE or Qt library. (ex. QLineEdit, QTextEdit, and more)

You don't need to do anything. KDE and QT library's input widget supports input method correct. There is no need of additional code.

case C)

Your application need input text. And you want to support keyboard input in your own widget. (ex. kate, konsole, kolourpaint, koffice, and more)

You need writing code to support input method. See next section.

How to support input method in KDE/Qt application.

If you want to support keyboard input in your own widget(case C), you need writing code to support input method.

Step A)

Set inputMethodEnabled property to ture. inputMethodEnabled property can enable/disable input method. And default is false except some input widgets. If your widget accepts input from input method, set it to true using QWidget::setInputMethodEnabled() method.

setInputMethodEnabled( true );

note: Original qt can use input method even when inputMethodEnabled property is false. (original qt ignore this property.) it's bug(maybe) and it confuses user. ( When widget doesn't accept text input(e.g. QLabel, QPushButton), I can open input method's window on that widget. ) So qt with immodule check this property to use input method. If your qt is without immodule, it seems to do not need this step. But this is needed.

Step B)

Set microFocusHint for input method can get position of input place.

When widget shows or moves cursor, you should set microFocusHint using QWidget::setMicroFosucHint().

microFocusHint is a hint that input method get place of input. It's help for input method shows additional information at suitable place when user uses input method.

Step C)

Accpet QKeyEvent's text.

Create your widget's keyPressEvent() event handler. And check QKeyEvent::text() for input method's input.

When QKeyEvent::text() is not empty, widget should accept it as user input.

note: QKeyEvent::text() is used when user uses XIM and OverTheSpot style. If user uses OnTheSpot style or other input method, we can't get input method's input using this way. See Step D).

Step D)

Implement QIMEvent handlers.

Input method's inputs are sent by QIMEvent when user uses input method other than OverTheSpot style XIM.

Please see QIMEvent's document for detail. You should reimplement QWidget::imStartEvent(), QWidget::imComposeEvent(), and QWidget::imEndEvent().

QWidget::imStartEvent()
Remember cursor position to show composing string. (QIMEvent doesn't have it.)
QWidget::imComposeEvent()
Remember composing string(QIMEvent::text()) and cursor position(QIMEvent::cursorPos()) in it and selecting string length(QIMEvent::selectionLength). Then show it as composing(preedit) strings.
QWidget::imEndEvent()
In imEndEvent(), QIMEvent sends final text user commits. Accept QIMEvent::text() as final text.

Maybe that's all of input method support.

Please read and comment it.

Saturday, May 26, 2007

QCoreApplication::setLibraryPaths

void QCoreApplication::setLibraryPaths ( const QStringList & paths ) [static]

Sets the list of directories to search when loading libraries to paths. All existing paths will be deleted and the path list will consist of the paths given in paths.

See also libraryPaths(), addLibraryPath(), removeLibraryPath(), and QLibrary.

Friday, May 25, 2007

GIf support in Windows

(To configure Qt with GIF support, pass -qt-gif to the configure script or check the appropriate option in the graphical installer.)

Tuesday, May 22, 2007

MixIn

MixIn 技术 (感谢 limdou 的介绍)

def MixIn(pyClass, mixInClass):
print "Mix class:",mixInClass, " into: ",pyClass,'\n'
pyClass.__bases__ += (mixInClass,)

class A:
def __init__(self):
self.name = "Class A"
def fun(self):
print self.name

class B:
def __init__(self):
self.name = "Class B"
def add(self, a,b):
print 'function defined in B'
return a + b

obj_a = A()

print obj_a
print dir(obj_a),'\n'

MixIn(A,B)

print obj_a
print dir(obj_a),'\n'

print obj_a.add(3,5)


-----------------------------------------〉
执行结果:

>>>
<__main__.a>
['__doc__', '__init__', '__module__', 'fun', 'name']

Mix class: __main__.B into: __main__.A

<__main__.a>
['__doc__', '__init__', '__module__', 'add', 'fun', 'name']

function defined in B
8

解释一下 MixIn 技术,就是使 一个类成为另一个类的基类, 这样会使 被 MixIn 的那个类具有了新的特性。
在例子程序中, 我们将 B 类 MixIn 进 A 类, 成为 A 的基类,于是, A 类的实例便具有了 B 类的方法(add)


obj_a = A() obj_a 是 类 A 的一个实例

print obj_a <__main__.a>
print dir(obj_a),'\n' ['__doc__', '__init__', '__module__', 'fun', 'name']

MixIn(A,B) 将B MixIn 进 A

print obj_a <__main__.a>

print dir(obj_a),'\n' ['__doc__', '__init__', '__module__', 'add', 'fun', 'name']
注意,这时候,多了一个 add 方法(类B 中定义)

print obj_a.add(3,5) 现在 A 的实例可以使用 B 中的方法了

python中实现Single模式

#!/usr/bin/env python

#-*- coding:utf-8 -*-

class Singleton:

""" A python singleton """

class __impl:

""" Implementation of the singleton interface """

def spam(self):

""" Test method, return singleton id """

return id(Singleton.__instance)

# storage for the instance reference

__instance = None

def __init__(self):

""" Create singleton instance """

# Check whether we already have an instance

if Singleton.__instance is None:

# Create and remember instance

Singleton.__instance = Singleton.__impl()

# Store instance reference as the only member in the handle

self.__dict__['_Singleton__instance'] = Singleton.__instance

def __getattr__(self, attr):

""" Delegate access to implementation """

return getattr(self.__instance, attr)

def __setattr__(self, attr, value):

""" Delegate access to implementation """

return setattr(self.__instance, attr, value)

class SingletonType(type):

"""Singleton Metaclass"""

def __init__(cls, name, bases, dic):

super(SingletonType, cls).__init__(name, bases, dic)

cls.instance = None

def __call__(cls, *args, **kwargs):

if cls.instance is None:

cls.instance = super(SingletonType, cls).__call__(*args, **kwargs)

return cls.instance

class MyClass:

__metaclass__ = SingletonType

if __name__ == '__main__':

#print dir(MyClass)

ob1 = MyClass()

ob2 = MyClass()

print id(ob1), id(ob2)

#print dir(Singleton)

s1 = Singleton()

s2 = Singleton()

print id(s1), s1.spam()

print id(s2), s2.spam()