2012年10月29日 星期一

Python 基礎-List 介紹 與常見BIF示範

Python保存資料使用的是類似陣列的清單結構
但型別是由Python編譯器處理
Python的List能混合存入各類型的資料,如字串和數字混合放置
另外List中也能包含其他的list,就像多重陣列一樣

Python的多行註解形式是 """註解""" ,單行註解則用#
在編譯器中執行以下程式碼

initList = []         #建立空的List,也可以用BIF方式建立 initList = list()
lists = ["new", "show", "Eclipse"]
demo = ["aa", ["bb", "cc"]]
print(initList)
print(lists[1])    
print(len(lists))     #這裡用上了len() BIF回傳List長度
print(demo[1])      

"""
output:

[]
show
3
['bb', 'cc']
"""

Python稱呼它的內建方法為BIF(built-In Function),常看到的還有

  函式                        說明                                    範例

append()   -   將一筆資料附加到尾端          lists.append("lol")
pop()        -   從最尾端取出一筆資料          lists.pop()           #output:lol
extend()    -   加入一群資料                       lists.extend(["hi", "hello"])
remove()   -   移除特定的資料項                 lists.remove("hi")
insert()      -   插入一筆資料                       lists.insert(0, "head")
list()         -   用於新建空清單的函式
len()         -   取得List長度                         len(List)
range()     -    回傳一個Iterator                    for num in range(4):  #output:0 1 2 3
                   並依照給定的範圍產生數字     print(num)
sort()       -   將List排序,由低到高
reverse()   -  逆轉陣列的順序
count()     -   回傳某個值在List中出現的次數

sum()      -   會將引數中的List數字作加總        sum(list)
randint()   -   前回介於兩引數之間的任意整數      randint(1, 10)
int()        -   將一個字串或數字轉換為整數
float()      -   將一個字串或數字轉換為浮點數
str()        -   將數字轉換成字串
id()         -   傳回一個資料物件在Python中的獨特編號
input()     -   取得並回傳使用者輸入

enumerate() - 補足Iterator的index值,使用方法如下:
           for i, n in enumerate([1, 3, 5]):
       print(i, n)

"""  output
0 1
   1 3
   2 5
"""

zip()     -   整合多個Lists,使用方法如下:
          names = ["John", "Marry", "Tom"]
          sexes = ["Male", "Female", "Male"]
          for name, sex in zip(names, sexes):
              print(name, sex)

"""  output
John Male
   Marry Female
                        Tom Male
"""

Python 安裝配置與 Eclipse PyDev 設定

參考文章:Python: Eclipse+Pydev環境安裝教學
                 在 Windows 7 環境安裝 Python 2.6.6

本篇文章介紹 Python 3 在 Windows 環境的安裝配置過程
另外開發過程會以PyDev作為IDE

首先到Python官網下載需要的版本
安裝後到 [電腦] -> 右鍵[內容] -> [進階系統設定] -> [環境變數]  中添加環境變數
環境變數的設定過程類似 Java


PYTHON_HOME :C:\Python33
PATH: ;%PYTHON_HOME%    (附加在現有內容後)


新建立PYTHON_HOME變數後,在PATH變數加上上述內容就完成了
要確認的話可以到 cmd (命令提示字元) 中輸入 Python 看看

Python雖然可以多個版本並存,但能設定在PATH裡的只能有一個版本
設定主要開發版本即可

Python本身有自帶 IDLE 可以做為簡單版的編譯器使用
它有幾個簡單的快捷鍵:

TAB鍵可以提示尚未輸入完的程式碼
Alt + P 可以召回前一組輸入的程式碼
Alt + N 移往下一個程式碼


不過因為Python是個極端重視縮排的語言
往往縮排就可以讓人在除錯過程中搞得要死不活
建議還是用IDE進行開發
個人因常使用Eclipse而選擇用其平台的PyDev

在Eclipse中安裝 plugin
[Help] -> [Install New software]  加入
name: Pydev
url: http://pydev.org/updates

就個人遇過的情形 Aptana 跟 Pydev 的安裝會有衝突
因為兩者套件都各自有引用對方的部分
最後我是只選擇安裝PyDev

安裝完後到 [Window] –> [PyDev] -> [Interpreter – Python] 設定Python編譯器的路徑
加入 Python 安裝目錄底下的所有東西就好了
之後開發時選擇Python專案就可以開始開發Python了

2012年10月24日 星期三

Java 數值轉換函式區別 - 以Integer.parseInt()、Integer.valueOf()為例

之前對於Java在數值轉換中為什麼會提供這兩種功能幾乎一樣的方法感到疑惑
看了原始碼就可以得到解答
public static Integer valueOf(String s) throws NumberFormatException {
  return new Integer(parseInt(s, 10));
}

public static int parseInt(String s) throws NumberFormatException {
  return parseInt(s,10);
}

答案在於回傳型別的不同
parseInt()回傳 int 基本型別,valueOf()則回傳Integer型別
除了Integer外,其他的數值型別也有同樣的方法(Double、Float...etc)

在Java1.4版本以前這兩種方法有差異,但在後來版本裡因為有auto boxing機制而沒差了

2012年10月22日 星期一

JavaScript 少用全域變數的理由

在 JavaScript: The Good Parts 書中即有討論到這個議題(心得文連結)
容易造成變數名稱紊亂這點,可以盡量用匿名函式的寫法解決
在匿名函式中使用的變數名稱就不會跟全域變數產生衝突
但除了這個問題外,還有效能的考量
JavaScript搜尋變數的方式是 區域變數 -> 更上層的區域變數 -> .... -> 全域變數
若有常用到的全域變數,把它另存成區域變數對效能有很大的幫助

function displayData(){
  //caching variables
  var _ctrl=ctrl;
  var _nui=nui;
  ....
}

Excel 開啟產出的 .CSV檔為亂碼的解決方式

CSV檔為以逗號區隔欄位,用來儲存資料的純文字格式
指定了編碼的純文字格式應該是與亂碼無緣
但有時以微軟的Excel開啟.csv檔卻會發現內容為亂碼
發生的原因是微軟內部系統處理格式時會在開頭暗中寫入一串判別的字碼
而微軟系統就以文字檔案中是否含這串暗碼來判定要以UTF-8或ASCII格式讀取檔案

所以我們若要讓我們產出的CSV檔能正確的被Excel讀取,就要在檔案開頭加入暗碼


public CSVWriter(OutputStream out){
    this.out=out;

    //Corresponding to Microsoft Excel, make file won't open with scrambles in Excel
    byte[] BOM_UTF8 = { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };
    try {
    out.write(BOM_UTF8);
    } catch (IOException e) {
    System.err.println("BOM寫入CSV失敗");
    }
    ....
}

2012年10月16日 星期二

IE 中checkbox的checked=true不打勾問題解決


這個問題是發現在IE中會沒辦法看到checkbox的選項被打勾
檢查其屬性checked=true無誤

追查下發現原因為在該checkbox尚未被IE初始化(還沒加入DOM樹中)前設定此屬性

解決方法有兩種 -
1.將其加入DOM樹中再設定屬性
2.改為設定其 defaultChecked=true

2012年10月15日 星期一

動態加入CSS 與 IE 的 innerHTML 屬性討論

這幾天有遇到一個情況是動態加入CSS時發現在IE會遇到問題
查過後才發現 IE 會限制部分Element的 innerHTML 屬性值的設定
col, colgroup, frameset, html, style, table, tbody, tfoot, thead, title, tr
上述標籤的innerTML attribute 在 IE 中均為唯讀

以下有兩種處理方式可通用在所有瀏覽器中

1.
....
    var se = document.getElementById("ieStyleApplier");
    se.innerHTML = "";
    se.innerHTML = "_<style>" + o.responseText + "</style>";
...

先設定一個空的div element
再再將CSS內容將入到div的範圍內用(本例中的o.responseText 為Ajax取得CSS內容)
注意stye tag 前加入 '_' 作為前綴字元(prefix character)
這是避免IE解析div element時讀到style tag會停止解析的情形
猜測這是IE的安全性考量
加入前綴字元後就沒問題了,也可以對應到其他的browser

2.

  (function(o){
      var newStyle = document.createElement("link");
      newStyle.rel = "stylesheet";
      newStyle.href = o;
      var head = document.getElementsByTagName('head')[0];
      if(head)
          head.appendChild(newStyle);
      else
          document.body.appendChild(newStyle);
  })(url);

用一次性的函式動態加入link element後引入CSS