2010年1月14日 星期四

程式版本控管與管理流程之靠腰

很多IT 部門的軟體變更管理,會有資料管制人員負責去協助變更管理,其目的是避免程式開發人員自行變更而造成混亂,說明一下變更流程大概如下:

1.提出變更申請目的
2.AP 頭頭同意
3.附上變更軟體資料、測試報告等等。交付資料管制人員處理。
4.資料管制人員,檢查申請人所付資料是否符合?
要進入正式區軟體庫中的檔案是否與申請項目相同

要討論的是如何確認申請人所附檔案是正確的(第 4 點):
1.申請人比對正式區軟體庫內容並產生差異檔 - DiffData1
2.資料管制人員依申請人申請,比對正式區軟體庫內容並產生差異檔 -DiffData2
3.比對DiffData1 與DiffData2 內容是否一致

問題來了,Source Code 是可以這麼做,但若是非Source Code (如COM/DLL) 要如何管理呢?
subversion 的diff 檔比不出來呀,解法是產生檔案的checksum 去證明是兩者一致,
如你去網路Download 檔案,也都是會看到檔案提供者在網站公告chksum ,讓你知道你下載的檔案是正確未被篡改過,要產生Checksum 有很多種方法,普遍是用MD5,那只要可以利用Subversion 找出差異檔並產生每個檔案的MD5 並產生報表,申請人與資料管制人員都利用這種方式進行變更管裡,問題就解決了。

口說無憑,程式碼如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-


"""
SVNMD5.EXE.
Used to compare working copy and Repository ,genereate compare report.
It's 100 % Python :)
I use Python 2.6.4 , py2exe,pysvn 1.7.2 to create SVNMD5.EXE
Diff report format : Unified diff format
"""

__author__ = ' Ray Yeh <yeh_ray@hotmail.com>'
__version__ = '1.0'
__licence__ = 'GPL V3'


import sys
import os
import re
from datetime import datetime
import pysvn
import codecs
import hashlib


def Usage():
print """Usage: """ + sys.argv[0] + """ PATH >> Report_file
Usage sample1 : SVNMD5.exe d:\project >> d:\svnreport.txt --> Output report at d:\svnreport.txt
Usage sample 2: SVNMD5.exe d:\project --> Output at screen
Batch compare working copy with repository and generate report to PATH

by Ray Yeh version 1.0
"""
sys.exit(1)

#------------------------------- Process the options -------------------------
if len(sys.argv)==2 :
workingdir=sys.argv[1]
else:
Usage()

try:
os.chdir(workingdir)
except OSError:
print "Cannot change dir to " + workingdir
Usage()
#------------------------------- Find out what has changed -------------------
client = pysvn.Client()
changes = client.status(workingdir)

#print 'files to be added:'
addedlist =[f.path for f in changes if f.text_status == pysvn.wc_status_kind.added]
#print 'files to be removed:'
deletedlist=[f.path for f in changes if f.text_status == pysvn.wc_status_kind.deleted]
#print 'files that have changed:'
modifiedlist=[f.path for f in changes if f.text_status == pysvn.wc_status_kind.modified]
#print 'files with merge conflicts:'
conflictedlist=[f.path for f in changes if f.text_status == pysvn.wc_status_kind.conflicted]
#print 'unversioned files:'
unversionedlist=[f.path for f in changes if f.text_status == pysvn.wc_status_kind.unversioned]
#print 'missing files:'
missinglist=[f.path for f in changes if f.text_status == pysvn.wc_status_kind.missing]

dt=datetime.now()

print "SVN compare run at:"+ dt.strftime("%A, %d. %B %Y %I:%M%p")
print "Compare Woking directory:"+workingdir + "\n"


str_1 =u"================== 產生 Compare 資料開始 ================="
str_2 =u"================== 產生 Compare 資料結束 ================="
print str_1.encode('big5_tw')
# Added files
for item in addedlist:
buff =""
file=open(item, 'rb')
buff=file.read()
file.close()
m=hashlib.md5()
m.update(buff)
print item+ " =>MD5 Chksum:" + m.hexdigest()

#Modified files
for item in modifiedlist:
buff =""
file=open(item, 'rb')
buff=file.read()
file.close()
m=hashlib.md5()
m.update(buff)
print item+ " =>MD5 Chksum:" + m.hexdigest()
print str_2.encode('big5_tw')

#Unversionedl files
for item in unversionedlist:
buff =""
file=open(item, 'rb')
buff=file.read()
file.close()
m=hashlib.md5()
m.update(buff)
print item+ " =>MD5 Chksum:" + m.hexdigest()

deletedcount=0
modifiedcount=0
missingcount=0
addedcount=0
unversionedcount=0

i=0
for i in addedlist:
addedcount +=1
i=0
for i in modifiedlist:
modifiedcount +=1
i=0
for i in missinglist:
missingcount+=1
i=0
for i in unversionedlist:
unversionedcount +=1

str_3=u'比對目錄路徑:'
str_4=u'比對檔案清單:'
str_5=u'新增 '
str_6=u'差異 '
str_7=u'刪除 '
str_8=u'未納版'
print str_3.encode('big5_tw')
print str_4.encode('big5_tw')
print str_5.encode('big5_tw')+'%d folders/files:\n%s' %(addedcount, addedlist)
print str_6.encode('big5_tw')+'%d folders/files:\n%s' %(modifiedcount, modifiedlist)
print str_7.encode('big5_tw')+'%d folders/files:\n%s' %(missingcount, missinglist)
print str_8.encode('big5_tw')+'%d folders/files:\n%s' %(unversionedcount,unversionedlist)
print "=========================================================="

2010年1月12日 星期二

使用svn 去產生 Working copy 與 repository 的比對報表

目的: 使用svn 去產生 Working copy 與 repository 的比對報表
解決方案:
1.Ad hoc 方法:
a.安裝支援 CLI(Command Line Interface) 的 svn 軟體,利用Command Line 去產生比對報表

2.利用 程式產生,並使用svn command line :
a. 利用DiffUtils 去產生 Context format ,如果不想看Context format 就用 svn 原始的diff 去產生 unified format
b.GNU32 -DiffUtils 2.8.7 (show differences between files)
http://gnuwin32.sourceforge.net/
c.SVN- Setup-Subversion-1.6.6.msi
http://subversion.tigris.org/

#!/usr/bin/env python
# Python version of the bash shell "svnreport"

"""
SVNREPORT1.EXE.
Used to compare working copy and Repository ,genereate compare report.
It's 100 % Python :)
I use Python 2.6.4 , py2exe to create SVNREPORT1.EXE
Diff report format : Unified diff format
"""

__author__ = ' Ray Yeh <yeh_ray@hotmail.com>'
__version__ = '1.0'
__licence__ = 'GPL V3'


import sys
import os
import re
from datetime import datetime


def Usage():
print """Usage: """ + sys.argv[0] + """ PATH >> Report_file
Usage sample1 : svnreport1.exe d:\project >> d:\svnreport1.txt --> Output report at d:\svnreport.txt
Usage sample 2: svnreport1.exe d:\project --> Output at screen
Batch compare working copy with repository and generate report to PATH

by Ray Yeh version 1.0
"""
sys.exit(1)

#------------------------------- Process the options -------------------------
if len(sys.argv)==2 :
workingdir=sys.argv[1]
else:
Usage()

try:
os.chdir(workingdir)
except OSError:
print "Cannot change dir to " + workingdir
Usage()

#------------------------------- Find out what has changed -------------------

svnstatus=os.popen("svn status").readlines()

added=""
deleted=""
modified=""
commit_message=""
#print svnstatus

for line in svnstatus:

matchObject=re.match(r"^\?\s*(.*)\n",line)
if matchObject:
added = added + "\"" + matchObject.group(1) + "\" "
#print matchObject.group(1)
commit_message += "added file " + matchObject.group(1) + "\n"

matchObject=re.match(r"^\!\s*(.*)\n",line)
if matchObject:
deleted = deleted + "\"" + matchObject.group(1) + "\" "
commit_message += "deleted file " + matchObject.group(1) + "\n"

matchObject=re.match(r"^\M\s*(.*)\n",line)
if matchObject:
modified = modified + "\"" + matchObject.group(1) + "\" "
commit_message += "modified file " + matchObject.group(1) + "\n"

'''if added:
#os.system("svn diff "+added)
if deleted:
print "deleted-"+deleted
#os.system("svn diff "+deleted) '''
if modified:
os.system('svn diff ' +modified )


if not added:
commit_message += "no added files\n"
if not deleted:
commit_message += "no deleted files\n"
if not modified:
commit_message += "no modified files\n"

modifiedcount =0
addedcount = 0
deletedcount=0

addedlist=added.split()
modifiedlist=modified.split()
deletedlist=deleted.split()

i=0
for i in addedlist:
addedcount +=1
i=0
for i in modifiedlist:
modifiedcount +=1
i=0
for i in deletedlist:
deletedcount +=1

dt=datetime.now()
print "======================================================="
print "SVN compare run at:"+ dt.strftime("%A, %d. %B %Y %I:%M%p")
print "Compare Woking directory:"+workingdir
print "Add %d folders/files:\n%s" %(addedcount, added)
print "Modified %d folders/files:\n%s" %(modifiedcount, modified)
print "Deleted %d folders/files:\n%s" %(deletedcount, deleted)
print "======================================================="





3.利用程式產生,不使用svn command line ,
a.pysvn -http://pysvn.tigris.org/
b.python 2.6.4

### -*- coding: utf-8 -*-
#!/usr/bin/env python

"""
PYSVNRPT.EXE.
Used to compare working copy and Repository ,genereate compare report.
It's 100 % Python :)
I use Python 2.6.4 , py2exe,pysvn 1.7.2 to create PYSVNRPT.EXE
Diff report format : Unified diff format
"""

__author__ = ' Ray Yeh <yeh_ray@hotmail.com>'
__version__ = '1.0'
__licence__ = 'GPL V3'


import sys
import os
import re
from datetime import datetime
import pysvn


def Usage():
print """Usage: """ + sys.argv[0] + """ PATH >> Report_file
Usage sample1 : PYSVNRPT.exe d:\project >> d:\svnreport.txt --> Output report at d:\svnreport.txt
Usage sample 2: PYSVNRPT.exe d:\project --> Output at screen
Batch compare working copy with repository and generate report to PATH

by Ray Yeh version 1.0
"""
sys.exit(1)

#------------------------------- Process the options -------------------------
if len(sys.argv)==2 :
workingdir=sys.argv[1]
else:
Usage()

try:
os.chdir(workingdir)
except OSError:
print "Cannot change dir to " + workingdir
Usage()
#------------------------------- Find out what has changed -------------------
client = pysvn.Client()
changes = client.status(workingdir)

#print 'files to be added:'
addedlist =[f.path for f in changes if f.text_status == pysvn.wc_status_kind.added]
#print 'files to be removed:'
deletedlist=[f.path for f in changes if f.text_status == pysvn.wc_status_kind.deleted]
#print 'files that have changed:'
modifiedlist=[f.path for f in changes if f.text_status == pysvn.wc_status_kind.modified]
#print 'files with merge conflicts:'
conflictedlist=[f.path for f in changes if f.text_status == pysvn.wc_status_kind.conflicted]
#print 'unversioned files:'
unversionedlist=[f.path for f in changes if f.text_status == pysvn.wc_status_kind.unversioned]
#print 'missing files:'
missinglist=[f.path for f in changes if f.text_status == pysvn.wc_status_kind.missing]

dt=datetime.now()

print "SVN compare run at:"+ dt.strftime("%A, %d. %B %Y %I:%M%p")
print "Compare Woking directory:"+workingdir + "\n"



print "====================="+u" 產生 Compare 資料開始 "+"==================="
for item in modifiedlist:
difftext=client.diff('t:',item)
print difftext
print "====================="+u" 產生 Compare 資料結束 "+"==================="


deletedcount=0
modifiedcount=0
missingcount=0
addedcount=0
unversionedcount=0

i=0
for i in addedlist:
addedcount +=1
i=0
for i in modifiedlist:
modifiedcount +=1
i=0
for i in missinglist:
missingcount+=1
i=0
for i in unversionedlist:
unversionedcount +=1

print u"比對目錄路徑:"+workingdir
print u"比對檔案清單:"
print u"新增 %d folders/files:\n%s" %(addedcount, addedlist)
print u"差異 %d folders/files:\n%s" %(modifiedcount, modifiedlist)
print u"刪除 %d folders/files:\n%s" %(missingcount, missinglist)
print u"未納版 %d folders/files:\n%s" %(unversionedcount,unversionedlist)
print "=========================================================="


4. 安裝 Pysvn WorkBench Subversion

2009年12月11日 星期五

COCOMO II Model Overview

COCOMO II Model:
1.Source Lines of Code(SLOC)
a.SLOC 是logical line ( If-else-endif) 視為一個 SLOC
b.Comment 不計算在SLOC
c.宣告算在SLOC

2.Cost Drivers:
a.
Effort = 2.94 * EAF * (KSLOC)E
Where EAF=
Effort Adjustment Factor derived from the Cost Drivers
E=
an exponent derived from the five Scale Drivers
例如,EAF=1.00, E= 1.0997,8,000 source lines of code

Effort = 2.94 * (1.0) * (8)1.0997 = 28.9 Person-Months


3.Effor Adjustment Factor:
a.
Complexity (effort multiplier of 1.34)

b.
Language & Tools Experience (effort multiplier of 1.09)
c.the others normal ,set 1.00
Effort Adjustment Factor = EAF = 1.34 * 1.09 = 1.46

Effort = 2.94 * (1.46) * (8)1.0997 = 42.3 Person-Months


4.Schedule Equation:
a.
Duration = 3.67 * (Effort)SE
Where

Effort Is the effort from the COCOMO II effort equation

SE Is the schedule equation exponent derived from the five Scale Drivers


b.
0.3179 that is calculated from the scale drivers:



Duration = 3.67 * (42.3)0.3179 = 12.1 months

Average staffing = (42.3 Person-Months) / (12.1 Months) = 3.5 people



5.SCED Cost Drivers:


a.Required Development Schedule
(SCED)
b.代表若要加速工作進度,在樂觀的條件下,需要多少人力
c.
SCED rating of Very Low corresponds to an Effort Multiplier of 1.43 (in the COCOMO II.2000 model)

d.means that you intend to finish your project in 75% of the optimum schedule .



Duration = 75% * 12.1 Months = 9.1 Months
Effort Adjustment Factor = EAF = 1.34 * 1.09 * 1.43 = 2.09

Effort = 2.94 * (2.09) * (8)
1.0997 = 60.4 Person-Months


Average staffing = (60.4 Person-Months) / (9.1 Months) = 6.7 people



Remember: SCED cost driver means "accelerated from the nominal schedule".

2009年12月8日 星期二

MS SQL Role and User security

SQL server 兩種登入方式(二選一) :
1. Window 網域帳號登入,歸Window 作業系統
2. SQL server 帳號登入,SQL server 管理(Server roles are usually reserved for database and server administrators.)
3. Windows Authentication is the recommended security model when using SQL Server.

安全分等:
  • Login security—Connecting to the server (登入 Server)
  • Database security—Getting access to the database (存取DB)
  • Database objects—Getting access to individual database objects and data(存取DB的某一個object/data)

Role types:
1.Server Role -DBA 維護,管理整台server
2.Database Role - 管理單一的database
3.public role 只要一加入 SQL server,都有public role

Database Role(Predefine):
  • db_owner: Members have full access.
  • db_accessadmin: Members can manage Windows groups and SQL Server logins.
  • db_datareader: Members can read all data.
  • db_datawriter: Members can add, delete, or modify data in the tables.
  • db_ddladmin: Members can run dynamic-link library (DLL) statements.
  • db_securityadmin: Members can modify role membership and manage permissions.
  • db_bckupoperator: Members can back up the database.
  • db_denydatareader: Members can’t view data within the database.
  • db_denydatawriter: Members can’t change or delete data in tables or views.

Server Role(Predefine ):
  • SysAdmin: Any member can perform any action on the server.
  • ServerAdmin: Any member can set configuration options on the server.
  • SetupAdmin: Any member can manage linked servers and SQL Server startup options and tasks.
  • Security Admin: Any member can manage server security.
  • ProcessAdmin: Any member can kill processes running on SQL Server.
  • DbCreator: Any member can create, alter, drop, and restore databases.
  • DiskAdmin: Any member can manage SQL Server disk files.
  • BulkAdmin: Any member can run the bulk insert command.





2009年11月18日 星期三

TCP Windows Size 解答

說明TCP Windows Size 的用途與注意事項
1.TCP Windows Size 目的是 Sender 與 Receiver 最好能把Data 一次處理完,
以避免因為網路設備彼此速度不同,而造成Data Lost 的問題。

2. TCP Windows Size 要多大呢?
window size = bandwidth * delay
假設網路是 100 Mbits/s, round trip time (RTT)是 5 ms,所以 Windows Size 應為
( 100 * 10^6) *( 5 * 10^-3) = 500 * 10^3 bits (65 kilobytes)

3.最後 Client 與 Server 的buffer 要設一樣:
/* An example of client code that sets the TCP window size */

int window_size = 128 * 1024; /* 128 kilobytes */

sock = socket(AF_INET, SOCK_STREAM, 0);

/* These setsockopt()s must happen before the connect() */
setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
(char *) &window_size, sizeof(window_size));
setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
(char *) &window_size, sizeof(window_size));
connect(sock, (struct sockaddr *) &address, sizeof(address));


/* An example of server code that sets the TCP window size */
int window_size = 128 * 1024; /* 128 kilobytes */
sock = socket(AF_INET, SOCK_STREAM, 0);

/* These setsockopt()s must happen before the accept() */
setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
(char *) &window_size, sizeof(window_size));
setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
(char *) &window_size, sizeof(window_size));

listen(sock, 5);
accept(sock, NULL, NULL);
4.備註:
a.Nonstop 系統
TCP programming :setsockopt 參數(SO_SNDBUF/SO_RCVBUF)
Default 8192 bytes

5.參考:
a.A User's Guide to TCP Windows
b.Enabling High Performance Data Transfers
c.Windows 2000 TCP Performance Tuning Tips

6.
a.Max Transmission Unit (MTU) - TCP header(20 byte)- IP header (20 bytes) =Max Segment Size(MSS)
b.

2009年11月12日 星期四

Python ctypes 使用方法(2)

介紹一些使用方法:
define C library 的 header 檔
from ctypes import *

WS_MAX_USER_LEN=10
WS_MAX_PIN_LEN =4
WS_MAX_LMK_ID =1
WS_MAX_IP_ADDR_LEN =10
WS_MAX_LABEL=5
WS_MAX_DESC=10
WS_MAX_LOG_ENTRY_LEN=100
WS_MAX_ZMK_KEY_ID_LEN=10

WS_VOID=c_void_p
WS_BYTE=c_ubyte
WS_CHAR=WS_BYTE
WS_BOOL=WS_BYTE
WS_USHORT=c_ushort
WS_ULONG=c_ulong
WS_LONG=c_long

WS_RV=WS_ULONG
WS_UNIT_ID=WS_ULONG
WS_DEVICE_ID=WS_ULONG
WS_CLUSTER_ID=WS_ULONG
WS_FLAGS=WS_ULONG
WS_UNIT_TYPE=WS_ULONG
# WebSentry  Specific Return Codes #
WSR_OK= 0x00000000
WSR_CANCEL = 0x00000001
WSR_HOST_MEMORY= 0x00000002
WSR_UNIT_ID_INVALID =0x00000003
WSR_GENERAL_ERROR=0x00000005

class WS_ITEM(Structure):
_fields_=[('pData',POINTER(WS_BYTE)),('len', WS_ULONG)]

class WS_VERSION(Structure):
_fields_=[('major', WS_BYTE), ('minor', WS_BYTE)]

from wapich  import *   #import python wrap data
from ctypes import *

libc=cdll.LoadLibrary('wapicd.dll')
WS_Initialize=libc.WS_Initialize  #define  function
WS_Initialize.restype=WS_RV    # set return type  = WS_RV, if none, always return int

rv=WSR_OK
rv=WS_Initialize()

if rv != WSR_OK:
print rv
else:
print 'WS_Initialize is Ok'

WS_GetInfo=libc.WS_GetInfo
WS_GetInfo.restype=WS_RV

myInfo=WS_INFO()
myInfo_p=pointer(myInfo)
myInfo_p.contents=myInfo   # assign  myInfo_ptr pointer to myInfo

rv=WSR_OK
rv=WS_GetInfo(myInfo_p)
if rv !=WSR_OK:
print rv

print myInfo.manufacturerID[:]
print myInfo.description[:]
print myInfo.version.major
print myInfo.version.minor

2009年11月6日 星期五

Python ctypes 使用方法(1)

因為要使用C libray ,所以要使用ctypes 去 wrap C function
from ctypes import *
from ctypes.util import find_library

print '---Begin Show----'

print find_library('c')
print windll.kernel32
print cdll.msvcrt
print find_library('wapicd')
libc=cdll.LoadLibrary("msvcr90.dll")

print "---------- char --------"
x=c_char_p("Hello World")
print x
print x.value
print sizeof(x)

print '---------- int ----------'
i=c_int(42)
print i
print i.value

p = create_string_buffer("Hello", 10)
print sizeof(p), repr(p.raw)

print "---------- Bo class---------------"
class Bo(object):
def __init__(self, number):
self._as_parameter_=number

bo=Bo(33)
printf = libc.printf
printf("%d bottles of beer \n", bo)

strchr=libc.strchr
print strchr('abcdef', ord('c'))
strchr.restype=c_char_p # set retyrn type is char_pointer
print strchr('abcdef', ord('d'))


print '----Passing by reference---------'
i=c_int()
f=c_float()
s=create_string_buffer('\000'*32)
print i.value, f.value, repr(s.value)

libc.sscanf("1 3.14 hello", "%d %f %s", byref(i), byref(f), s) #Passing by ref
print i.value, f.value, repr(s.value)

print '---- Pointer ---------'
ptr_i=pointer(i)
ptr_f=pointer(f)
ptr_s=pointer(s)
libc.sscanf("1 3.14 hello", "%d %f %s", ptr_i,ptr_f,ptr_s)
print i.value, f.value, repr(s.value)
print 'point of i:', ptr_i.contents
print 'point of f:', ptr_f.contents
print 'point of s:', ptr_s.contents

print '------------ Test Structure ---------'
class POINT(Structure):
_fields_=[('x', c_int), ('y', c_int)]

p=POINT(10, 20)
print p.x, p.y

def testptr(a):
b=POINT()
b=a
b.x=a.x+100
b.y=a.y+100
return b


testptr.restype=POINT()
g=testptr(p)
print g.x, g.y



測試結果:

---Begin Show----
msvcr90.dll


C:\WINDOWS\system32\wapicd.dll
---------- char --------
c_char_p('Hello World')
Hello World
4
---------- int ----------
c_long(42)
42
10 'Hello\x00\x00\x00\x00\x00'
---------- Bo class---------------
12838358
def
----Passing by reference byref()---------
0 0.0 ''
1 3.1400001049 'hello'
---- Pointer pointer()---------
1 3.1400001049 'hello'
point of i: c_long(1)
point of f: c_float(3.1400001049041748)
point of s:
------------ Test Structure ---------
10 20
110 120




2009年10月29日 星期四

Python in Plurk

因為看到Plurk 是可以用網路程式去發送訊息的,所以想說用Python 試試看,說明方法如下:
1.Install SimpleJSON
Ans: easy_install simplejson ,它會自動Download 到你的Python 目錄去

2.Download plurkapi ,Copy plurkapi.py 到 D:\Python26\Lib (這是我的python 目錄)
plurkapi download location


3.因為無法發中文,看來應該是沒宣告Coding ,所以在 plurkapi.py 加入
# *- coding: UTF-8 -*-

4.Sample Code 做法:
# *- coding: UTF-8 -*-
import plurkapi
import sys

# Create an API object.
# Pass in your own username and password to the "login" method.
#

plurk_api = plurkapi.PlurkAPI()

if plurk_api.login('nickname', 'password') == False:
print "Login failed!"
sys.exit(1)

plurk_api.addPlurk(lang='tr_ch',qualifier='says',content='中文化Say Hello 222222!!!')

2009年5月27日 星期三

NonStop Server 試用Python

目標:使用python 開發Client/Server Thread program
測試結果:Nonstop server 不支援 Thread,只能使用 fork 。
Client 程式:
#######################################################
## Demo:Opening a Client-Side Socket for Sending Data
#######################################################
print '#'*60
print '# Demo:Opening a Client-Side Socket for Sending Data'
print '#'*60

import thread
import sys,time,os
from socket import *

def client(id):
serverHost = '192.168.110.93'
serverPort = 12343

def now():
return time.ctime(time.time( ))

message = 'I am ID: %s' %id + '- Time: %s' %(now())

if len(sys.argv) > 1:
serverHost = sys.argv[1]

#Create a socket
sSock = socket(AF_INET, SOCK_STREAM)

try :
#Connect to server
sSock.connect((serverHost, serverPort))
except Exception, e:
sSock.close()
os._exit(0)

#Send messages
sSock.send(message)
data = sSock.recv(1024)
print 'Client received: ', data
sSock.close()
os._exit(0)

def main():
i=0
while True:
newpid = os.fork()
if newpid == 0:client(i)
i=i+1
if i > 10 :break


if __name__ =='__main__':
main()



Server 程式:

import SocketServer,time
myHost=''
myPort=12343

class MyClientHandler(SocketServer.BaseRequestHandler):
def handle(self):
print 'Welcome Clinet:',self.client_address
while True:
data=self.request.recv(1024)
time.sleep(1)
if not data:break
print 'Send Back:',data
self.request.send(data)
self.request.close()


myaddr=(myHost,myPort)
server=SocketServer.ThreadingTCPServer(myaddr,MyClientHandler)
server.serve_forever()

2009年5月20日 星期三

Python 複利計算

都是同事問我複利計算,微積分早就還給老師了,不知公式如何,只好自個想啦!
Amt-定期定額
Rate-利率
Y1=Amt*(1+Rate)
Y2=(Y1+Amt)*(1+Rate)
Yn=(Yn-1+Amt)*(1+Rate)

Python sample 程式如下:
# Directory 解法
f={}
base=100
rate =0.05
f[1]=base*(1+rate)
i=1
for i in range(2,5):
f[i]=(f[i-1]+base)*(1+rate)

for key in f:
print key,f[key]

#Generator 解法
def f(first,n):
while True:
result= (first+100)*(1.05)
first=result
n=n+1
print n,first
yield first

base=100
rate =0.05
i=1
gh=f(0,0)
for i in range(1,5):
gh.next()


-------------------------------------------------