顯示具有 Python 標籤的文章。 顯示所有文章
顯示具有 Python 標籤的文章。 顯示所有文章

2009年11月11日 星期三

Google IO大會上Guido van Rossum對於GAE的演講

由於python創始人Guido van Rossum被Google收錄進去...所以python可說是google開發的主力,而GAE也是基於python + django的環境改寫而成, 我們來聽聽去年Google IO大會上Guido van Rossum對於GAE的演講

然後也有介紹python的特性與其他相關部分

2009年5月26日 星期二

GAE ( Google App Engine ) 模式為什麼將來會流行?

一開始寫這篇文章標題時,本來想下"為甚麼GAE( Google App Engine )在台灣乏人問津...",但是與其批判,不如說一些真正吸引廠商或老闆的條件比較實在。

講到GAE就不能不提雲端,雲泛指網路世界,其實中國把Cloud Computing稱作雲運算,但Sam還是覺得台灣翻的好,因為重點是終"端"使用者。Google之所以能夠讓用戶端幾近立即的得到搜尋結果,在於內部程式幾乎都實作了Map和Reduce方法去驅動機器讓資料中心平行同步幫您處裡,才能夠達到如此高的效率(參見Map-Reduce)。 這時候我們開始回歸到現實面,如果您擁有一家軟體開發,或目前已經在提供現上應用服務的企業(無論大小),您會怎麼處理資料? 目前情況不外乎是砸錢設機房、買伺服器、請網管維護、負擔線路費用,或是中小企業租用虛擬伺服器。但如果以上都能省略呢? 俗話說 "打蛇打七寸",既然公司是以軟體與服務為主,我們就應該縮減實體設備造成的負擔。

GAE的聲明便是不需要再負擔實體設備成本(或極小化),只需要專心在軟體構思與服務。GAE採用的技術完全都是OpenSource,並且就算付費,也是使用公用運算(Utility Computing)的計費標準,用多少付多少,不用再像以往為了負載短時間高流量,承擔一整年其餘沒用到的費用。以下幾點為與傳統比較的好處:

1. 風險降低(不用再擔心本地伺服器硬碟毀損,雲端資料中心機器會自動複製到其他台)
2. 擴充、縮減的問題無須考慮(基本上雲端資料中心能夠任意增縮設備,當然這已經不再是您的問題)
3. 成本降低(省下設備維護費用全力開發產品)

目前GAE支援的環境為Windows、Linux、MacOS,也就是跨平台,而編寫語言除了原本的python之外,今年也加入了Java成為第二個支援語言 http://code.google.com/intl/en/appengine/

Sam 目前只有實作python的api,在安裝完GAE SDK與python2.5後便能開始編寫,裡頭大致上是追隨django這個框架的標準,包含設定檔使用yaml,與資料儲存(datastore)採ORM用物件來設定,Google也很貼心的設計了像phpMyAdmin那樣的介面來做資料表管理,而且datastore背後採用BigTable,不用太擔心效率的問題,然後除了官方API(Images, Memcache, Mail, URLFetch, Google Accounts)外,也能夠使用第三方資源庫(3rd party library),系統還能定期排程,真的甚麼事都能處理(當然還是有sandbox規範,像是socket那些不行),並且他們的free quota(免費額度)對於一般企業根本一天不會用到超量(因為非常之大),作網路服務或網站是綽綽有餘。

寫到這裡好像Sam都在幫Google打廣告,但是各位要了解,除了Google外, IBM blue cloud, Amazon EC2, 甚至微軟都在發展這個服務,拿Google來說只是因為它有free support,其它都要付費的...。

依照台灣對國際的資訊速度(差不多慢了一年或兩年),目前還很少人知道這種服務是正常的,過了不久就會像當初Google Adsence一樣在全世界掀起熱潮,只是這頭Cloud Service的小浪在Sam眼中將會是下一波科技海嘯,而未來掌握資料中心與搜尋技術的企業則會領導世界!

2009年3月30日 星期一

PyPdf 讀取中文Pdf亂碼問題

最近找論文資料常常會下載一堆相關題目的pdf檔然後慢慢消化,不過這樣實在是很浪費時間,所以週末就想說寫一隻程式搜尋資料夾中所有pdf,然後給它關鍵詞,最後能夠顯示這些關鍵詞在哪幾篇pdf的第幾頁中,如此一來就省事多了。

python的好處就是擴充套件多如過江之鯽,當然光pdf就好多個,這裡挑選的是PyPdf.

安裝完成之後先以取出內容文字為主寫出一段程式測試,測試pdf為中文big5編碼,但除了標題encode("big5")能夠正常顯示中文外,內容卻是一片亂碼,於是把每段文字拆解成char再使用hex code列印出來...

0xb8 0xea ... 這不是big5的"資"嗎?表示編碼是正確的阿!為何print就是有錯誤?

於是我使用一個範例字串 zh = "\xb8\xea" ,print出來是"資"沒錯,但 u"\xb8\xea" 加上unicode就會和上面呈現一模一樣的亂碼。原來PyPdf中PageObject extractText()會將所有內容編碼成unicode,所以我們要把unicode反解回來 str.encode('latin-1') ,嗯正常了^^。

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

from pyPdf import PdfFileReader

input = PdfFileReader(file("infosafe.pdf", "rb"))

# Show title from this pdf.
print input.getDocumentInfo().title.encode("big5")

# Total pages.
pages = input.getNumPages()

# Loop to print content.
for i in range(0, pages):
    pageObj = input.getPage(i)
    str = pageObj.extractText()
    
    # The extracted text has been set to unicode, therefore, we should transfer it's format to the normal 'latin-1'.
    print str.encode('latin-1')
    
    """
    # Print hex code.
    for j in range(0, len(str)):
        print hex(ord(str[j]))
    
    break
    """
"""
# This is an example.
zh = u"\xb8\xea".encode('latin-1')
print type(zh)
print zh
"""

2009年3月25日 星期三

Python RssParser with MySQL

其實繼上次寫了python資料型態上下集之後,這次應該來寫一下迴圈與條件式等的教學,但是其實那些東西都是廢話,我下一次再把一些注意事項放上來就好了!不然難道你認為if條件式會寫成怎樣??

這次開始從實例下手,之前我寫過Java RssParser,是儲存成檔案的方式,現在用python教大家如何parse Google RSS新聞檔並儲存 發布時間、標題、連結、相關內容 等資訊到MySQL中。

把玩這支程式之前請先安裝兩個函式庫,feedparserMySQLdb(說明)。裡頭都有安裝說明與教學。

By the way, 我的python是2.5版

sql -- 建立資料庫並使用SQL新增下列資料表

CREATE TABLE IF NOT EXISTS `FEED_MSTR` (
 `ID` int(11) NOT NULL AUTO_INCREMENT,
 `DATE` datetime NOT NULL,
 `TITLE` varchar(255) CHARACTER SET utf8 NOT NULL,
 `LINK` text CHARACTER SET utf8 NOT NULL,
 `SUMMARY` text CHARACTER SET utf8 NOT NULL,
 PRIMARY KEY (`ID`),
 KEY `DATE` (`DATE`,`TITLE`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

RssParser.py

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

# Copyright (C) 2009 Kakapo Studio.
# Author: Sam Wang
# Contact: sam.wang.0723@gmail.com

""" This program can parse any RSS or Atom type file on the internet and put it into database. """

import feedparser
import datetime
import MySQLdb

from time import mktime 

data = feedparser.parse(r"http://news.google.com.tw/news?pz=1&ned=tw&hl=zh-TW&topic=t&output=rss")

conn = MySQLdb.connect(host="localhost", user="root", passwd="********", db="YOUR_DATABASE", charset="utf8")
cursor = conn.cursor()

# Loop to get data.
param = []
for item in data.entries:

   # Make tuple to timestamp.
   ts = mktime(item.updated_parsed)
   # Transfer to datetime format.
   dt = datetime.datetime.fromtimestamp(ts)

   ntime = dt.strftime("%Y-%m-%d %H:%M:%S")
   ntitle = item.title.encode('utf8')
   nlink = item.links[0].href.encode('utf8')
   nvalue = item.summary_detail.value.encode('utf8')
  
   # Insert into param.
   param.append((ntime, ntitle, nlink, nvalue))

# Write to database.
sql = "insert into FEED_MSTR(DATE, TITLE, LINK, SUMMARY) values(%s,%s,%s,%s)"
cursor.executemany(sql, param)
  

cursor.close()
conn.close()

稍微說明一下 cursor.executemany(sql, param) 那段,executemany可以用字串當樣板然後給他list或tuples動態給予參數,假設一次update 3筆資料, 每筆有2個欄位, list儲存方式要像如此[(x,x) , (y,y), (z,z)]...這樣update時就會分開成len(list)的執行次數, 每次update len(list[i])個欄位了

2009年3月4日 星期三

Python 資料型態(下)

4. Dictionaries -> Dictionaries擁有鍵與值的對照, 類似Java中的Map類

>>> demo = {'a':123, 'b':456, 'c':789} # 使用“:“分隔鍵與值
>>> demo['a']
123

當然也可以不必在一開始就做指定動作, 能夠在不同位置指定內容讓Dictionaries擁有了極大的彈性

>>> demo = {}  #  指定一個空殼給demo
>>> demo['a'] = 123
>>> demo['b'] = 456
>>> demo
{'a' : 123, 'b' : 456}

巢狀內容的呼叫

>>> demo = {'name':{'first':'Bob', 'last':'Smith'},
      'job':['dev', 'mgr'],
      'age':40.5}
>>> demo['name']['first']
'Bob'

依照鍵值排序顯示內容:事實上我們可以發現Dictionaries顯示出的內容並不會從左到右排序, 所以有以下方法可供參考

>>> D = {'a':1, 'c':2, 'b':3}
>>> Ks = D.keys()
>>> Ks
['a', 'c', 'b']
>>> Ks.sort()
>>> Ks
['a', 'b', 'c']
>>> for key in Ks:
   print key, '=>', D[key]
a => 1
b => 2
c => 3

上面的方法是先取出鍵值陣列排序在依序取出值, 但還有一種更簡單的方式就是使用內置的sorted()方法

>>> for key in sorted(D):
    print key,'=>',D(key)
a => 1
b => 2
c => 3

5. tuples -> tuples 是python中一個特別的元件, 你可能不曾在別的語言中碰過, 它類似List但卻無法更動順序, 也無法在宣告之後指定參照

>>> T = (1, 2, 3, 4)
>>> len(T)
4
>>> T + (5, 6)
(1, 2, 3, 4, 5, 6)
>>> T[0]
1
>>> T[0] = 2   # 如果想指定參照會出現Exception

Traceback (most recent call last):
 File "<pyshell#4>", line 1,in <module>
   T[0]=2
TypeError:'tuple' object does not support item assignment

事實上tuples並不像List那麼常被用在練習中...但是tuples的好處就是在於"不可更動性"

6. Files -> 檔案操作物件通常一般不會包含在核心物件之內, 古怪的是你無法使用敘述式建立它們, 唯一的方法只有呼叫open()函式

寫入資料

>>> f = open('data.txt', 'w')    #開啟data.txt, 'w'為寫入write模式
>>> f.write('Hello\n')       # 寫入字串
>>> f.write('world\n')
>>> f.close()      # 關閉檔案flush剛剛寫入的資料

讀取資料

>>> f = open('data.txt')  # 也可以在型態上加上'r'
>>> data = f.read()  # 讀取函式read(), 但其實也可以使用 for text in f 來讀
>>> data
'Hello\nworld\n'
>>> print data
Hello
world

其他還有一堆類似Files物件的工具, 譬如pipes, fifos, sockets, keyed-access files, object persistence, descriptor-based files, relational and object-oriented database interfaces等, 以後陸續有學習到再做介紹。

Python 資料型態(上)

Python 有一個特性, 就是變數的宣告不需要使用強型態, 你可以指定 a = 2, 也可以在下一行改變成 a = 'sample', 包括陣列存放都可以使用多種不同型態的變數例如 a = [123, 'abc', 1.23]。

介紹一下 Python 核心物件內含的資料型態

1. Numbers -> 整數(integer), 含小數的數字(floating-point numbers), 另外像是一些長整數(unlimited-precision “long” integers), 複雜的數字(complex numbers)與固定精度的小數(fixed-precision decimals)等...。

範例:

>>> 123 + 456   # 整數相加
579
>>> 1.5 * 4    # 小數運算
6.0
>>> 2 ** 100   # 2的100次方
1267650600228229401496703205376L

另外有一些有趣的功能, 例如把一個高精度的小數用 print 顯示的話, 用戶只會看到部份好辨認的位數

>>> 3.1415 * 2  # 完整精度
6.2830000000000004
>>> print 3.1415 * 2 # 使用者好觀看的數字
6.283

Learning Python (Oreilly 出版) 的作者Mark Lutz說道 if something looks odd, try showing it with a print statement. (如果某樣東西看起來很莫名奇妙, 請嘗試使用print將它顯示出來)

2. Strings -> 字串, 基本上你可以將字串敘述成多個字元組合成的陣列, 譬如 'Spam' 就等於一個 ['S', 'p', 'a', 'm']。

範例:

>>> S = 'Spam'
>>> len(S)   # 字串長度
4
>>> S[0] # 該字串的第一個字元
'S'
>>> S[1]  # The second item from the left
'p'

也可以使用另外一些方式取出字元

>>> S[-1]  # 最後一個字元
'm'
>>> S[len(S)-1]  # 用總長減去一(麻煩的作法)
'm'

如果要取出範圍

>>> S[1:3]  # 取出從第一個到從頭數第三個
'pa'
>>> S[1:]  # 第一個字元以後
'pam'
>>> S[:-1]  # 最後一個字元以前
'Spa'

Python 中字串也可以用乘法運算

>>> S * 8  # 重複顯示8次
'SpamSpamSpamSpamSpamSpamSpamSpam'

字串相加

>>> S + 'xyz'  # 字串合併
'Spamxyz'

另外字串也有一些相關函式

>>> S.find('pa')   # 找尋比對字串出現位置
1
>>> S
'Spam'
>>> S.replace('pa', 'XYZ')   # 取代 'pa' 為 'XYZ', 但請注意原本字串不會被更動
'SXYZm'
>>> S
'Spam'
>>> line = 'aaa,bbb,ccccc,dd'
>>> line.split(',')  # 拆解字串為陣列
['aaa', 'bbb', 'ccccc', 'dd']
>>> S.upper( )  # 轉為大寫
'SPAM'
>>> line = 'aaa,bbb,ccccc,dd\n'
>>> line = line.rstrip( )   # 去除右方空白字元, 如同trim()
>>> line
'aaa,bbb,ccccc,dd'

3. List -> 集合, 不需指定長度並可容納不同型態的物件

>>> L = [123, 'spam', 1.23]
>>> len(L)  # List 長度
3
>>> L + [4, 5, 6]   # 串接List
[123, 'spam', 1.23, 4, 5, 6]
>>> L.append('NI')   # 新增一個元素到最後面
>>> L
[123, 'spam', 1.23, 'NI']
>>> L.pop(2)   # 將L[2]移除並返回值
1.23
>>> L      # "del L[2]" 一樣可以達成刪除目的
[123, 'spam', 'NI']
>>> M = ['bb', 'aa', 'cc']
>>> M.sort( )   # 正向排序(小到大)
>>> M
['aa', 'bb', 'cc']
>>> M.reverse( )  # 反向排序(大到小)
>>> M
['cc', 'bb', 'aa']

巢狀List

>>> M = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> M
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

>>> M[1]
[4, 5, 6]
>>> M[1][2]
6

還有一點蠻有趣的就是在中括號內寫迴圈與條件式, 個人認為能省下很多行程式碼的寫法

>>> col2 = [row[1] for row in M]  # 取出M中每一個元素的第1個元素(0,1,2...)
>>> col2
[2, 5, 8]

>>> [row[1] + 1 for row in M]  # 取出M中每一個元素的第1個元素並加上一
[3, 6, 9]

>>> [row[1] for row in M if row[1] % 2 == 0] # 判斷元素中2的倍數
[2, 8]

未完待續...

2009年3月3日 星期二

什麼是 Python?

Python的創始人為Guido van Rossum。在1989年聖誕節期間的阿姆斯特丹,Guido為了打發聖誕節的無趣,決心開發一個新的指令碼解釋程式,作為ABC語言的一種繼承。之所以選中 Python(大蟒蛇的意思)作為程式的名字,是因為他是一個Monty Python的飛行馬戲團的愛好者。

就這樣,Python在Guido手中誕生了。實際上,第一個實作是在Mac機上。可以說,Python是從ABC發展起來,主要受到了Modula-3(另一種相當優美且強大的語言,為小型團體所設計的)的影響。並且結合了Unix shell和C的習慣。

雖然 Python 可能被粗略地分類為「指令碼語言」(script language),但實際上一些大規模軟體開發計劃例如 Zope、Mnet 及 BitTorrent,Google 也廣泛地使用它。 Python 的支援者較喜歡稱它為一種高階動態編程語言,原因是「指令碼語言」泛指僅作簡單編程任務的語言,如 shell script、JavaScript 等只能處理簡單任務的編程語言,並不能與 Python 相提並論。

此外,由於 Python 對於 C 和其他語言的良好支援,很多人還把 Python 作為一種「膠水語言」(glue language)使用。使用 Python 將其他語言編寫的程式進行整合和封裝。 在 Google 內部的很多專案使用 C++ 編寫性能要求極高的部分,然後用Python叫用相應的模組。

Python是一門跨平台的指令碼語言,Python規定了一個Python語法規則,實作了Python語法的解釋程式就成為了Python的直譯器,我們用的比較多的是C版本的Python,也就是使用C語言實作的Python直譯器,除此之外還有使用Java實作的Jython和使用.NET實作的 IronPython,這些實作可以使Python使用者充分利用己有的Java及.NET資源。

同時,Python支援幾乎所有常用的作業系統,包括:Windows/DOS、Macintosh、Linux 及 FreeBSD。及很多不常用的作業系統,包括AIX、AS/400 (OS/400)、BeOS、OS/2、OS/390與z/OS、Palm OS、PlayStation與PSP、Psion、QNX、RISC OS、Series 60、Sparc Solaris、VMS、VxWorks、Windows CE或Pocket PC、Sharp Zaurus、MorphOS等。

可擴充性可說是Python作為一種編程語言的特色。新的內置模組(module)可以用C 或 C++寫成。而我們也可為現成的模組加上Python的介面。Python可以使使用者避免過分的語法的羈絆而將精力主要集中到所要實作的程式任務上。

因此Python具有非常龐大的程式庫,透過它們可以快速完成絕大部分常用的任務,如:從某個URL中獲取資訊、正則運算式、獲得某個檔案或字串的MD5特徵字串、多執行緒、XML及HTML的分析等。

Python也被稱為是一門清晰的語言。因為它的作者在設計它的時候,總的指導思想是,對於一個特定的問題,只要有一種最好的方法來解決就好了

摘錄自http://zh.wikipedia.org/w/index.php?title=Python&variant=zh-tw