2012/10/30

Quotes Of The Day

Summarized from http://bytes.com/topic/python/answers/28338-python-productivity-gain

They say that when you have a hammer, everything looks like a nail. When using Python, most everything is a nail.

using a tool like Python doesn't just influence the programmers, but the whole project! If prototyping and coding in general becomes significantly faster, the trade off for how much analysis and design you should do will change. Why spend weeks at a conference table arguing about different design alternatives if the programmers can supply several different implementations within a day?

Python is designed with the objective of making it easy to do the right thing, rather than making it difficult to do the wrong thing.

And Python just "felt" clean. I can't explain it very well, but Python's syntax just never got in the way of my reading, which left me free to concentrate all my attention on what the code was actually doing.

2012/10/26

Plone Isotope jQuery Plugin

isotope 是一個 jQuery plugin,可以呈現炫麗的網頁畫面。下列是我把範例檔案嵌進 Plone 網站的心得和步驟。
解開 isotope-site.zip 原始檔後,先觀察目錄結構和 index.html 內容:
isotope-site/
├── CONTRIBUTING.mdown
├── README.mdown
├── css
│   └── style.css
├── custom-layout-modes
│   ├── big-graph.html
│   ├── category-rows.html
│   ├── centered-masonry.html
│   ├── masonry-column-shift.html
│   ├── masonry-corner-stamp.html
│   ├── masonry-gutters.html
│   └── spine-align.html
├── demos
│   ├── adding-items.html
│   ├── basic.html
│   ├── combination-filters.html
│   ├── elements-complete.html
│   ├── elements-partial.html
│   ├── filtering.html
│   ├── fluid-responsive.html
│   ├── hash-history.html
│   ├── images.html
│   ├── infinite-scroll.html
│   ├── layout-modes.html
│   ├── relayout.html
│   ├── removing.html
│   └── sorting.html
├── docs
│   ├── adding-items.html
│   ├── animating.html
│   ├── extending-isotope.html
│   ├── filtering.html
│   ├── hash-history-jquery-bbq.html
│   ├── help.html
│   ├── introduction.html
│   ├── layout-modes.html
│   ├── license.html
│   ├── methods.html
│   ├── options.html
│   └── sorting.html
├── index.html
├── jquery.isotope.js
├── jquery.isotope.min.js
├── js
│   ├── fake-element.js
│   ├── jquery-1.7.1.min.js
│   ├── jquery.ba-bbq.min.js
│   ├── jquery.infinitescroll.min.js
│   └── make-big-graph-projects.js
├── pages
│   ├── 2.html
│   ├── 3.html
│   ├── 4.html
│   ├── 5.html
│   └── 6.html
└── tests
    ├── callbacks.html
    ├── combo-sort-history.html
    ├── destroy.html
    ├── elements-complete-test.html
    ├── flash.html
    ├── index.html
    ├── item-position-data.html
    ├── jquery-animation.html
    ├── no-items.html
    ├── onlayout.html
    ├── right-to-left.html
    ├── tiny-text.html
    └── unclickable-filtered.html

7 directories, 62 files
首先,把 JavaScript 和 CSS 檔案上傳到 ZMI 的 /portal_skins/custom 目錄,至少有三個檔案:

  1. jquery-1.7.1.min.js - 這個檔案在原始檔的 js 目錄裡找得到,從 ZMI 下拉選單點選 File 來新增。
  2. jquery.isotope.min.js - 仿照上述方式上傳。
  3. style.css - 這個檔案在原始檔的 css 目錄裡找得到,從下拉選單點選 DTML Method 來新增。由於 Plone 原本也有 style.css 同名稱的檔案,為避免衝突,我改用 isotope.css 名稱來上傳。
再到 ZMI 的 portal_css 新增 stylesheet 設定值,在這個例子裡,名稱就是上述新增的 isotope.css 檔案。

接著,要選一個「網頁」位址,來實際展示畫面,實作方法很多種,以根目錄為例,我是在 ZMI 根目錄裡新增一個 Page Template,請留意,這裡的 Id 要指定為 index_html,系統發現目錄裡有這類名稱時,會優先執行它,index_html 內容先複製自 Sunburst main_templage.pt 檔案,可參考這系列 gist 的第一次版本

這時候的畫面,很可能會變得清爽,主內容的區塊全部清空了:

我們想把 Plone Demo 字樣換掉,也就是改用新標題。從 ZMI 根目錄點選剛才建立的 index_html 檔案,在 Title 欄位填上 Python Periodic Table 當作新標題:

還要修改一段程式碼才能真的生效,把 <h1> 改成 TAL 敘述式,讀取 template/title 變數值:

重頭戲上場了,要把原始碼 index.html 內容嵌入 Page Template 裡。依序是:
接下來是許多微調的動作,特別是要把檔案路徑、CSS 衝突或不適宜的設定值改掉,例如:
如果 poortal-column-content 的 CSS class 改用 width-full 的話,可以擁有全螢幕的顯示效果。

2012/10/24

Plone Development Quick Tips

This document hints how to build a Plone development environment with minimum effort. Here we focus on development baby steps, not deployment. If possible, Ubuntu Linux 12.04 or later is preferred. Make sure you have installed the needed libraries. For newbies, it's much easier to install Plone with regular user account, not with root permission.

Useful Unified Installer Options

Linux Unified Installer provides a install.sh script, that makes things easy. Installation target directory and admin password can be specified.

$ tar xvpzf Plone-4.2.2-UnifiedInstaller
$ ./install.sh standalone \
  --target=/home/marr/plone422 --password=secret

Stand-Alone Zope Instance selected

Detailed installation log being written to
/home/marr/Downloads/Plone-4.2.2-UnifiedInstaller/install.log

Rootless install method chosen. Will install for use by system user marr

Installing Plone 4.2.2 at /home/marr/plone422

Skipping libjpeg build
Skipping readline build
Installing Python-2.7.3. This takes a while...
Installing distribute...
Python build looks OK.
Unpacking buildout cache to /home/marr/plone422/buildout-cache
Compiling .py files in egg cache
Copying Plone-docs
Your platform's xml2/xslt are missing or out-of-date. We'll need to build them.
Copying buildout skeleton
Fixing up bin/buildout
Building lxml with static libxml2/libxslt; this takes a while...
Building Zope/Plone; this takes a while...

#####################################################################
######################  Installation Complete  ######################

Plone successfully installed at /home/marr/plone422
See /home/marr/plone422/zinstance/README.html
for startup instructions

Use the account information below to log into the Zope Management Interface
The account has full 'Manager' privileges.

  Username: admin
  Password: secret

This account is created when the object database is initialized. If you change
the password later (which you should!), you'll need to use the new password.

- If you need help, ask the mailing lists or #plone on irc.freenode.net.
- The live support channel also exists at http://plone.org/chat
- You can read/post to the lists via http://plone.org/forums

- Submit feedback and report errors at http://dev.plone.org/plone
(For install problems, specify component "Installer (Unified)")

Preparing Package in the src Directory

In the above case, the directory ~/plone422/zinstance/src is used to store development source codes. Here is an example checking out the package source code from GitHub:

$ cd ~/plone422/zinstance/src
$ git clone https://github.com/collective/collective.masonry.git
Initialized empty Git repository in
/home/marr/plone422/zinstance/src/collective.masonry/.git/
remote: Counting objects: 314, done.
remote: Compressing objects: 100% (228/228), done.
remote: Total 314 (delta 147), reused 185 (delta 73)
Receiving objects: 100% (314/314), 52.36 KiB, done.
Resolving deltas: 100% (147/147), done.

Running buildout

buildout.cfg is the main file, which is extended by develop.cfg, so that development tools are included. After configuring the develop.cfg file, we run buildout to make it effective:

$ cd ~/plone422/zinstance
$ vi develop.cfg

[sources]
collective.masonry = fs collective.masonry

eggs +=
    collective.masonry

$ bin/buildout -c develop.cfg
mr.developer: Queued 'collective.masonry' for checkout.
mr.developer: Filesystem package 'collective.masonry' doesn't need a checkout.
Develop: '/home/marr/masonry/zinstance/src/collective.masonry'
...
Got collective.registry 1.0.
Got collective.js.imagesloaded 2.1.
Got collective.js.masonry 1.0.
Generated script '/home/marr/masonry/zinstance/bin/instance'.
Installing zopepy.
Generated interpreter '/home/marr/masonry/zinstance/bin/zopepy'.
Installing zopeskel.
Generated script '/home/marr/masonry/zinstance/bin/zopeskel'.
Generated script '/home/marr/masonry/zinstance/bin/paster'.
Installing omelette.
Updating backup.
Updating chown.
chown: Running echo Dummy references to force this to execute after referenced parts
echo /home/marr/masonry/zinstance/var/backups
chmod 600 .installed.cfg
find /home/marr/masonry/zinstance/var -type d -exec chmod 700 {} \;
chmod 744 /home/marr/masonry/zinstance/bin/*
Dummy references to force this to execute after referenced parts
/home/marr/masonry/zinstance/var/backups
Installing test.
Generated script '/home/marr/masonry/zinstance/bin/test'.
Updating repozo.
Updating unifiedinstaller.
*************** PICKED VERSIONS ****************
[versions]
collective.js.imagesloaded = 2.1
collective.js.masonry = 1.0
collective.registry = 1.0

*************** /PICKED VERSIONS ***************

Reading Buildout Messages

Don't panic when you see messages like these:

Thery are non-fatal errors.

Creating Dexterity Product Skeleton

For those who want Dexterity development environment for Plone 4.2.x, zopeskel.dexterity is your friend. After zopeskel.dexterity installed, you can run zopeskel to create dexterity package project:

$ cd src
$ ../bin/zopeskel dexterity

dexterity: A Dexterity-based product

This template expects a project name with 1 dot in it (a 'basic
namespace', like 'foo.bar').

Enter project name: myproj.dxcontent

In this case, add myproj.dxcontent in the develop.cfg file and run buildout -c develop.cfg to make it effective:

[sources]
# Examples: to check out plonetheme.sunburst from Plone's svn, use:
# plonetheme.sunburst = svn https://svn.plone.org/svn/plone/plonetheme.sunburst/trunk
#
# To use a python package that is being developed in your src subdirectory, use:
# myproduct.betterplone = fs myproduct.betterplone
myproj.dxcontent = fs myproj.dxcontent

Later, run paster addcontent to create dexterity_content or dexterity_behavior.

Here are the activated packages for Plone 4.2.2:

  • Dexterity Content Types 1.2.1
  • collective.z3cform.datetimewidget 1.2.1
  • plone.app.intid: install utility 1.0.1

2012/10/23

folder_contents Customization

之前看過 collective.edm.listing 例子,它提供類似 Contents 頁籤看到的顯示介面,不過,究竟 Contents 頁籤的表格式管理介面該如何修改呢?

每個目錄網址後面,加上 /folder_contents 就可以進入 Contents 管理介面,它的程式碼到 plone.app.content 找得到,先看 browser/configure.zcml 檔案:

<browser:page
    for="*"
    class=".foldercontents.FolderContentsView"
    name="folder_contents"
    template="folder_contents.pt"
    permission="cmf.ListFolderContents" />

再看 browser/foldercontents.py 檔案:

class FolderContentsView(BrowserView):
    ...
    def contents_table(self):
        table = FolderContentsTable(aq_inner(self.context), self.request)
        return table.render()

class FolderContentsTable(object):
    ...
    def __init__(self, context, request, contentFilter=None):
        self.context = context
        self.request = request
        self.contentFilter = contentFilter is not None and contentFilter or {}
        self.items = self.folderitems()

        url = context.absolute_url()
        view_url = url + '/folder_contents'
        self.table = Table(request, url, view_url, self.items,
                           show_sort_column=self.show_sort_column,
                           buttons=self.buttons)

    def render(self):
        return self.table.render()

其中的 Table() 是載自 plone.app.content.browser.tableview:

class Table(object):
    """
    The table renders a table with sortable columns etc.

    It is meant to be subclassed to provide methods for getting specific table info.
    """
    def __init__(self, request, base_url, view_url, items,
                 show_sort_column=False, buttons=[],
                 pagesize=20, show_select_column=True, show_size_column=True,
                 show_modified_column=True, show_status_column=True):

這 Table() 執行的結果,不只是產生內容項目的列表,它可以透過 checkbox 選擇項目,再個別或批次執行 portal_actions 的 Copy、Cut、Rename、Delete、Change State 等動作,或是利用 drag 功能 (配合 draggable 和 draggingHook 的 CSS 設定值) 來調整項目的順序,項目數量超過預設的 20 之話,就會啟用分頁功能。

2012/10/17

News from PloneConf 2012

PloneConf 2012 在荷蘭 Arnhem 舉行,研討會有許多簡報檔講題值得記錄分享:

其他同時期的進展包括:使用介面打算多整合 jQuery 和 JSONplone.batching 將讓 batch 資料有一致的處理方式Diazo Theme Editor 範例影片collective.z3cform.widgets 持續更新,目前 AutocompleteWidget 推薦使用 plone.formwidget.autocomplete,到 Plone 5 預計會有新的 widget 套件冒出頭,看來 plone.app.widgets 是候選之一。

2012/10/12

Heavy Usage of Python at Google

summary from http://stackoverflow.com/questions/2560310/heavy-usage-of-python-at-google

有人問道:Google 大量使用 Python,只是想要展現品味,還是真的帶來競爭優勢?

在 Google 擔任 Über Tech Lead 的 Alex Martelli 說:很難有明確的答案,不過,2004 年之際,Python 已在 Google 扮演重要角色,Google 確實召募許多 Python 大咖,但選用 Python 的思惟早在招雇之前就已決定,他們的技術策略是 Python where we can, C++ where we must,在緊密操控硬體資源的場合使用 C++,在快速開發和需要維護的場合使用 Python。早期雇用的系統管理員通常是 Perl 或 Bash 好手,許多內部系統先用 Perl 寫成,日後再用 Python 改寫,因為併購而帶進來的系統,如果是用 C# 寫成,常會用 Java 改寫。

想要獲得更多資訊的話,可以參考 Weisley Chun 在 Google I/O 2011 的演講

2012/10/05

Geo-Statistics Tools

summary from http://stats.stackexchange.com/questions/3069/among-matlab-and-python-which-one-is-good-for-statistical-analysis

很多人認為 R 是很棒的統計工具,像 gstat、geoR 讓它更切合特定領域的應用,也有人會考慮 Matlab,特別它有強大的 profile 工具。

當然,也有人快樂地拿 Python 當作統計平台,豐富的函式庫和整合其他系統的彈性肯定是一大賣點,例如在 R 跑得太慢的情況下,用 ctypes 來建置 C data structure,大幅改善效能問題,例如搭配 Natural Language Toolkit 處理文字資料。更多實務經驗,可參考 Data Crunching: Solve Everyday Problems Using Java, Python, and more 一書,作者 Greg Wilson 致力於讓科學家更有生產力

終究 Python 不是一個 Domain Specific Language,拿來和 R 相比,有其天生侷限,"Compared to R, Python is a low-level language for model building." - 有人如是說。

不過,也有人這樣評論:"In fact, I’ve anecdotally observed that becoming better at R leads to skill at interacting with data, becoming better at MATLAB leads to skill at quick-and-dirty scripting, but becoming better at Python leads to genuine programming skill."

如果有人想要用 Ruby 的話,可以貨比三家