2013年12月31日 星期二

編譯 busybox 並建立一個linux 系統


編譯 busybox 把 arm-none-linux-gnueabi- 換成你的編譯器。然後記得靜態編譯 busybox(在 menuconfig 裡選擇)
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- defconfig
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- menuconfig
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- install
編譯完後的檔案會放在 _install。把他做成 img
$ cd _install
$ find . | cpio -o --format=newc > ../rootfs.img

你可以用下面指令測試一下
qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs.img -append "root=/dev/ram rdinit=/bin/sh"

建立系統必要的目錄
$ cd _install
$ mkdir proc sys dev etc etc/init.d
$ cd ..




新增一個檔案,_install/etc/init.d/rcS,加入下面的內容
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s


讓剛剛的檔案可以被執行

chmod +x _install/etc/init.d/rcS
最後的驗收

qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs.img.gz -append "root=/dev/ram rdinit=/sbin/init"
參考資料

arm cross compile 常用指令備忘



製作 initramfs image

find . | cpio -H newc -o | gzip -9 > /boot/initrd.img
或是
find . | cpio -H newc -o > rootfs
解壓縮 initramfs image

gunzip -c /boot/initrd.img-2.6.24-19-generic | cpio -i

修改 initrd image

mount -t ext2 -o loop initrd.img temp/

編譯 arm 核心,arm-linux-gnueabi-請換成你用 cross_compiler

make ARCH=arm versatile_defconfigmake ARCH=arm menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- all

編譯完後,核心路徑在 arch/arm/boot


qemu-system-arm -M versatilepb -m 128M -kernel zImage -no-reboot


第一支程式

#include <stdio.h>
int main() {  printf("Hello World!\n");  while(1);}


編譯第一支程式
arm-linux-gnueabi-gcc -static    test.c   -o test 
製作 rootfs
echo test | cpio -o --format=newc > rootfs
執行第一支程式
qemu-system-arm -M versatilepb -m 128M -kernel zImage -initrd rootfs -append "root=/dev/ram rdinit=/test" -no-reboot
啟動核心後,核心會執行你的程式。

其他:如果你要測試編譯出來的程式,也可以直接用下面指令。
qemu-arm -L /usr/arm-linux-gnueabi/ a.out

參考資料

http://backreference.org/2010/07/04/modifying-initrdinitramfs-files/
http://balau82.wordpress.com/2010/03/22/compiling-linux-kernel-for-qemu-arm-emulator/

2013年12月29日 星期日

簡介 python 的物件生成 ( how to generate an instance in python)

    在開始介紹 python 怎麼產生 instnace 前,先來看一段簡單的程式碼


class MyStr1(str):
    def __init__(self, a='', b=''):
        super(MyStr1, self).__init__()
        self.a = a
        self.b = b


    這段程式碼看起來沒什麼,就繼承自 str 。然後 override __init__ 方法。所以我們可以用下面程式碼產生 instance。


 a = MyStr1("1")

   可是當我們執行下面程式碼時,

 a = MyStr1("1", "2")


    卻會出現

Traceback (most recent call last):
  File "", line 1, in 
TypeError: str() takes at most 1 argument (2 given)

    這到底發生什麼事? 會出現這個錯誤,是因為 str.__new__ 這個方法只接受一個參數,而你給他兩個。

    做個簡單的實驗。執行這兩行 str.__new__(str) 和 str.__new__(str, '1') 程式碼不會出錯。然而 str.__new__(str, '1', '2') 會出現上面的錯誤。所以可以合理懷疑問題真的出在這了。

     接下來來談一個 class 怎麼產生 instance。當 class 要產生 instance 時,他會呼叫 class 的 metaclss 的 __call__ 方法。而 metaclass 的 __call__ 方法大概長這樣:

def __call__(cls, *args, **kwargs):
    obj = cls.__new__(cls, *args, **kwargs)
    obj.__init__(*args, **kwargs)
    return obj

    所以執行 a = MyStr1("1", "2") 時,直譯器會先做 obj = str.__new__(str, *args, **kwargs) ,其中 *args 是 (1, 2, 3),可是因為 str.__new__ 只接受一個參數,因此發生錯誤。

    要怎麼知道直譯器在建立 instance 時,會把類別名稱後面的參數全都丟進 __new__ 和 __init__ 裡呢? 用一段簡單的程式即可說明。



class ClsA(object):
    def __init__(self, *args, **kwargs):
        print 'init: ', args, kwargs

    def __new__(cls, *args, **kwargs):
        print 'new: ', args, kwargs
        return super(ClsA, cls).__new__(cls, *args, **kwargs)

  
a = ClsA('a', 'b', 2)


   上面程式碼,當要建立 ClsA 的程式碼,他會先執行 __new__,而餵給 __new__ 的參數則是 ClsA 後面的參數。之後再把 ClsA 後面的參數餵給 __init__。而這也說明了為什麼一開始的程式碼會有問題。因為建立 instance 時,預設行為是把類別後面的參數全都丟給 __new__ 和 __init__。可是 str.__new__最多只接受一個參數,因此出錯。

    要如何解決第一個程式所遇到的問題呢?
    解法1.
    不要使用預設的 metaclass(type),自訂一個 meta class


class CustomMetaCls(type):
    def __call__(cls, *args, **kwargs):
        if len(args):
            content = args[0]
        else:
            content = ''
        obj = cls.__new__(cls, content)
        obj.__init__(*args, **kwargs)
        return obj

  
class MyStr(str):
    __metaclass__ = CustomMetaCls
 
    def __init__(self, a='', b=''):
        super(MyStr, self).__init__(a)
        self.a = a
        self.b = b


b = MyStr('a', 'b')


    解法2.
    override __new__

class MyStr1(str):
    def __init__(self, a='', b=''):
        super(MyStr1, self).__init__()
        self.a = a
        self.b = b

    def __new__(cls, *args, **kwargs):
        print args, kwargs
        if len(args):
            content = args[0]
        else:
            content = ''
        return str.__new__(cls, content)

2013年12月25日 星期三

docker 原理簡介

    Docker 官網上的簡介,寫了"Docker is an open-source project to easily create lightweight, portable, self-sufficient containers from any application."。不過 containers 是啥呢? 有點難解釋,基本上可以想像成一個 sandbox。不過 docker 還可以在上面跑完整的 linux distributions。

    先看看 Docker 怎麼實作的。他是建立在 lxc 和 aufs 的基礎上。那 lxc 是什麼呢? 官網上講"LXC is a userspace interface for the Linux kernel containment features."。官網上還有這一段話。

Features

Current LXC uses the following kernel features to contain processes:
  • Kernel namespaces (ipc, uts, mount, pid, network and user)
  • Apparmor and SELinux profiles
  • Seccomp policies
  • Chroots (using pivot_root)
  • Kernel capabilities
  • Control groups (cgroups)
    他用到 kernel 許多特性,不過和 container 有關的主要是 kernel namespace 和 control groups。不過能做到 container 主要是靠 kernel namespace。


    namespace 是什麼呢? 以 pid namespace 為例,在每個 namespace 裡,每個 pid 都是唯一的。而不同的 namespace 裡, pid 可以重複。因此在 A namespace 哩,會有一個自以為 pid = 1 的程序,在 B namespace 哩,也會有一個自以為 pid = 1 的程序。如果 A 和 B 繼承自最上層的 namespace (也就是 host 所在的 namespace,叫做 C namespace ),那麼從 C namespace 的觀點來看,前面那兩個自以為是 pid = 1 的程序,其實他的 pid 都不為 1 。這樣可以做到程序隔離的功能,也可以做到虛擬化。 lxc 用到的 namespace 就 ipc, uts, mount, pid, network and user。這篇文章有詳細說明 docker 用到的 namespace 作用。http://blog.dotcloud.com/under-the-hood-linux-kernels-on-dotcloud-part

    這樣要怎麼做到模擬作業系統呢? 一個 linux distributions 就是一個 linux kernel 加上很多其他程式。 namespace 沒辦法跑 kernel。不過那不重要,反正核心都差不多。剩下的程式,就可以把它丟進 namespace 跑,而那些程式在跑的時候,會以為整台電腦都是他的(因為被 namespace) 隔離了。所以他會建立 init(pid = 1) 程序,再做一些其他開機步驟。有 system call 就由 host 的 kernel 來處理。他活在虛擬的世界,還活得很開心。

虛線表示那兩個是同一個。箭頭表示程序間的父子關係。有箭頭的表示子程序。

                       
    如上圖所示, A namespace 的程序無法看到 root namespace 的程序。因此,我們可以在 A namespace 跑 centos 的開機程序,也可跑 ubuntu 的開機程序。在 A namespace 哩,無法察覺 root namespace 存在,他們會以為自己就是 root namespace。

    解決了程序的問題後,還有一個問題,檔案系統。基本上,用原本系統的檔案系統即可做到模擬作業系統,不過 docker 選擇使用 aufs,選用 aufs 還有個好處是可以做版本控制。

    Aufs,全名叫 advanced multi layered unification filesystem。恩,名字不太重要。基本上就分層。以下圖為例:

                                   


       上圖表示至少兩個檔案系統,你可以從 Delete file B 這個往下看,那你看到的檔案系統會是對 Base 加了C(B一加刪,最後看不到)。而從 Add file E 往下看,則看到的檔案系統是對 Base 加了 ADE 這三個檔案。每層只記錄和上一層的差異。要顯示完整的作業系統則把自己到 base 各層 union 起來。

       介紹完 lxc 和 aufs , 來看看 docker 如何整合。



    如上圖所示, docker 把客端作業系統安裝在 aufs 上,你可以 commit 你的修改,他會把你的修改當作一層新的 layer 蓋在上一層。當你要 run 客端作業系統時,他會在你要跑的 image 上面再蓋一層,叫做 container(image 是 read only)。之後 docker 會建立新的 namespace,把 namespace 的 root directory,然後執行 debian 的 init 程序(開機程序),這樣客端作業系統就成功執行了。


如果你想更了解 docker,強烈推薦閱讀  http://blog.dotcloud.com/category/under-the-hood
也可以參考我演講投影片:http://www.slideshare.net/ya790026/docker-33456641

參考資料:

2013年11月22日 星期五

mysql 常用管理指令

因為最近常常要用到 mysql ,只好做個小筆記。

給使用者所有權限
GRANT ALL PRIVILEGES ON dbTest.* To 'user'@'hostname' IDENTIFIED BY 'password';

建立一個資料庫與使用者,給他資料庫所有權限 。
CREATE USER 'test'@'localhost' IDENTIFIED BY 'password';
create database test;
grant all privileges on test.* to test@localhost ;
登入 mysql
$ mysql -u root -p 
修改使用者密碼
UPDATE mysql.user SET Password=PASSWORD('MyNewPass') -> WHERE User='root';
忘記 root 密碼,先停用 mysql server。

$ mysqld_safe --skip-grant-tables
$ mysql --user=root mysql
mysql> update user set Password=PASSWORD('new-password') where user='root';
mysql> flush privileges;
mysql> exit;

2013年11月1日 星期五

CPython 2.7.5 中使用 join 寫法來做字串加法比較快?還是使用 += ?

    如果你在 windows 下執行下面的程式碼,你會發現用 += 會比 join 寫法還快

a='''
def test_join():
    data = []
    for i in range(100):
        data.append('ad')
    return ''.join(data)
test_join()
'''
b = '''
def test_connect():
    data = ""
    for i in range(100):
        data += 'ad'
    return data
test_connect()
'''

import timeit
print timeit.timeit(a, number=10)
print timeit.timeit(b, number=10)

2013年10月20日 星期日

從 windows 8 連 samba

    這篇文章只是為了備忘。如果你在 windows 8 或其他版本,想連到 samba,明明伺服器設定
也正確。從 linux 連也可以,只有 windows 不能連。那麼,你可能需要啟用 smb 的協定。


    下面是啟用的步驟,請打開 cmd ,輸入下面的指令
  • To enable SMBv1 on the SMB client, run the following commands:
    sc.exe config lanmanworkstation depend= bowser/mrxsmb10/mrxsmb20/nsi 
    sc.exe config mrxsmb10 start= auto
  • To enable SMBv2 and SMBv3 on the SMB client, run the following commands:
    sc.exe config lanmanworkstation depend= bowser/mrxsmb10/mrxsmb20/nsi 
    sc.exe config mrxsmb20 start= auto

探討 scala 的函數呼叫與自動推論型別所產生的模糊情形

     scala 是靜態型別語言,不過他擁有自動推論型別的功能,因此可以減少重複宣告型別的情形。如以下程式碼:


    val a = 1

    由於 1 是整數,因此可以推論出 a 的型別為 int。再看看定義 function 的情形。


    def func(a:int, b:int) = a + b

    func 接受兩個參數,他的資料型別是 int,編譯器會推論出 func 的回傳值為 int。

2013年10月13日 星期日

浮點數除於零的行為

    程式語言中,整數除於零,基本上都會讓程式無法執行或是拋出類似例外的錯誤。可是如果是浮點數除於零的話,則行為就不一定。在 IEEE 754 的標準,浮點數除於零的話,會產生代表無窮大的值。c, c++, tcl, ruby, scala, java 遵循 IEEE 754。不過 perl, python , go 語言,發生浮點數除於零的情形,則是產生類似例外的訊息,而非給定無窮大的值。其他的語言沒有測試,這篇純粹紀錄各種語言的細微差異。

2013年8月20日 星期二

一個 golang 的非同步 stdin 的範例

    這篇文章只是一個簡單的例子,示範 golang 的 go 與 select 用法。 golang 原生就支援多序了,因此可以寫起來很簡潔。


2013年8月8日 星期四

C語言中,在呼叫函數前和呼叫函數後,執行某段程式碼

    gcc 有很多強大的選項,可以讓我們作到一些特別的事情。假設我們希望每次呼叫函數前,都先執行特定的動作。我們可以這樣寫。


在 C 語言中,發生錯誤時,顯示 backtrace

    在很多語言中, 如 python, java 等,當程式遇到錯誤時,他會顯示 backtrace( 就走到目前函數位置的呼叫流程)。在 C 語言中,預設只會出現錯誤訊息,就沒了。

    不過在 linux 下,你可以使用 catchsegv 來顯示程式錯誤時的 backtrace。用法大概向這樣
catchsegv ./a.out

2013年7月6日 星期六

python 的 gc ( garbage collection) 演算法介紹

    最近無聊看了一下 python 的 garbage collect 的實作。還蠻簡單易懂的。 python 回收沒用的物件,主要是靠參考計數 (reference count)。然而,他無法解決自己參考自己或是參考循環(a 參考 b, b 參考 a)的問題。這篇文章是講 python 如何解決這個問題。

2013年6月15日 星期六

在 python 中呼叫 java,JPype 簡介

    之前我以為如果要在 python 中呼叫 java lib ,只能用 jython。然而查了一些資料,發現有些神人已經幫我們做好在 CPython 中呼叫 java lib 的方法,JPype 可以幫我們完成這個神奇的需求。


2013年6月9日 星期日

以 html5 撰寫 單機(離線)程式,以 pyside 與 qwebkit 為例。

    現在 html5 蔚為潮流,而 html5 也將觸手伸向單機程式。新的 html5 技術可以使用 ApplicationCache 來達成。而 XULRunner 又是令一個技術,讓你可以用寫網頁的方式來寫單機程式。用 pyside 加上 qwebkit 也可以達到類似的應用。事實上,pyside 加上 qwebkit 的作法不過是作個客製化瀏覽器而已。

2013年6月2日 星期日

如何在 C 語言中模擬繼承與多型

    在 C 語言中,並沒有繼承與多形。然而,我們可以利用一些方法來模擬繼承與多型。在開始講之前,我們先來看看電腦如何取得變數的值。

2013年5月8日 星期三

python 中 is 和 ==(等於) 的差別

    在很多程式語言中,相等的意義有兩種意涵,一種是指那兩個變數實際上是指向同一個物件,另外一種意涵是雖然他們不是相同物件,但是他們的值一樣(什麼叫做值一樣,可以自己寫函數定義)。在 java 中,我們用 == 還比較這兩個變數是否指向相同物件,而使用 object.equal(other) 還比較兩個變數物件的值是否一樣。 在 python 中,則是使用 is 這個關鍵字來判斷這兩個變數是否指向相同物件,而使用 == 來判斷兩個變數物件的值是否一樣(值是否一樣由 __eq__ 這個函數定義)

2013年5月4日 星期六

pdb 的運作原理

    要了解 python debuger 的運作方式前,需要先了解 python 如何實作 function call。在 C語言中,每個被呼叫函數都有自己的 call stack拿來存放區域變數之類的東西。而在 python 中, call stack作用是由 frame object 物件完成。下面是官網對 frame object 的屬性介紹

generator 和 list 簡單比較

這篇文章我第一次發表在 ptt.cc。之後在把它複製過來。下次應該先寫在網誌,在貼 ptt.cc 的 XD

python 的 list comprehension 有分兩種,

一種是[i for i in xrange(5)],這種形式產生出來的是 list

另外一種形式是 (i for i in xrange(5)),這種形式產生出來的是 generator

python yield 語法與 generator 物件介紹

    這篇介紹 yield 語法以及用來維護 yield 行為的 generator 物件。
    事實上,yield 和 return 很像,只是當函數呼叫 return 時,該函數 call stack (python 中是 frame) 就會被清除,程式主導權回到呼叫該函數的手上。 而 yield 會把程式主導權交給呼叫該函數的手上,但是他不會把函數的 call stack 清除,因此下次呼叫時,可以從上次未執行的部分開始執行,而不是重新建立一個新 stack。

2013年4月21日 星期日

如何取得 facebook 的 access_token。

    要取得 facebook 的 access_token 目前我知道的有兩個方法,一種是利用你的 api id 和 secreet key 。透過 'https://graph.facebook.com/oauth/access_token?client_id=%s&client_secret=%s&grant_type=client_credentials' % (FACEBOOK_APP_ID, FACEBOOK_APP_SECRET) 這個 api 來取得。這個方法適用於 server 端,因為它會暴露 secreet key。

安裝 jdownloader 在 Raspberry Pi wheezy 系統上

    jdownloader 真是一個佛心的軟體,提供完整的功能以及擁有跨平台的能力。不過因為它是用 java 寫的,自然速度會比不上 native program 。

    我是使用下面的方法來安裝 jdownloader。
  1. wget must be installed on system!
  2. Download jd.sh
  3. chmod +x jd.sh
  4. start jd.sh
Note: Open jd.sh to read Manual or change Settings!

2013年4月20日 星期六

tcl 的語法簡介

    因為網路上有不少的 tcl 教學(中文英文都不少),所以這篇文章就不是做 tcl 的教學。就只是當成備忘。當我要用的時候,可以讀這篇文章快速回憶。

    tcl 這個語言想法很簡單,每行程式碼都是一個指令,指令後面接參數。指令與參數間用空格隔開。指令的結尾一般是換行符號,有可能是]  (當然,放在 {} 裡的字串不會被當作用該字串作為參數的指令當成指令結尾,下面有範例)。例如:

puts "abcd"
    上面指令會顯示 abcd

puts {123
456}

2013年4月9日 星期二

如何使用 django 的 i18n

    因為今天被 django 的 i18n 搞很久。所以只好寫篇文章作個紀錄。

    django 要做到 i18n。首先,你需要把程式中要翻譯的字串都改成 _("string") 這種形式。其次,你需要在 template 加上 {% load i18n %},以及把 template 的字串改成 {% trans "string" %}。在程式碼和 template 加完上面的東西後。接下來就是重點了,至少是我犯錯的地方。

2013年4月8日 星期一

python runtime 產生物件與 compile-time 產生物件方法的比較

    python 是一個很有彈性的語言,可是彈性也意味著,完成一件事情會有很多方法。這篇文章介紹產生產生 dict 與 type object 的方法。注意,以下討論都是未最佳化的情形。

    首先介紹產生 dict 的方法。在 python 中,產生 dict ( list 和 tuple 相同) 方法至少有兩種,一種是使用 {}, 另外一種是使用 dict() 的形式。前者是 compile-time 就會決定要產生 dict 物件,而後者是函數呼叫型式,他必須等到 run-time 時期才知道是產生 dic。至於後者較前者有何好處我就不清楚了。

你的選擇,是你的選擇? 還是程式的選擇?

    現在是資訊爆炸的時代,每秒都有數不完的資料產生。毫無疑問的,有些資料是正確的,有些資料是錯誤的。當我們去報社的網站瀏覽資料時,我們所接受的資料,都是經過報社選擇過的。當我們去看 google news ( 或其他網站時 ) 時,資料有被篩選過嗎?

    毫無疑問,答案是有的。只是變成程式幫我們選擇資料,選擇那些資料要呈現給用戶 (就是我們) 看。

    有程式幫我們選擇(過濾)資料,在大部分的情形下是好的。然而,在某些狀態下,他卻能左右你的思想。

2013年3月30日 星期六

輸家競標

    網路上有種競標方式,它的特性是每次下標都要付錢,我不知道到該怎麼稱呼這種競標方式。姑且叫他輸家競標。

    為什麼我要叫他輸家競標呢? 因為你一下標你就輸了(輸了錢和時間),在這種競標模式下,只有兩個贏家,賣家、平台提供者。

    在一般的競標模式下,競標者為了確保自己的最大利益,通常不會一次加碼太多錢。直到沒有人願意再加碼,此時競標就成立,買家確定。

2013年3月26日 星期二

單一職責原則 ( Single Responsibility Principle )

    在寫 django view 的時候,如果你是在寫列出該使用者所有文章,或是列出該使用者所有評論、活動之類的 view。 你會發係每個 view 基本上做的事情都差不多,不外乎就撈資料 -> 排列資料 -> 做分頁 - > 丟給 template 去呈現。像下面程式碼(以下程式碼都省略很多東西,所以請看 function name、call function 與 function doc 部分)

2013年3月25日 星期一

source code tag system

    因為最近要開始看很長很長的 source code。想說找個方便的 tag 工具。就想起從前有用過一個很好用的 tag system。叫做 gnu global 。他看中他的特色是這一點
support C, C++, Yacc, Java, PHP4 and assembly. (definition and reference)
    這意味著我可以很快的從一堆 source code 中找出物件在哪裡定義,有哪些程式碼參考他。

    要使用 global 前,要先用 gtags 作索引。做完索引後就可以開始使用了。下面是我常用的用法。

2013年3月22日 星期五

無法安裝星海爭霸 2

星海爭霸2 的安裝程式大概是寫得太爛了,很容易陷入在一直更新畫面,卻無法完成更新。爬文找了結果,只要上次安裝失敗就會導致這個結果。解決辦法就是把上次安裝失敗的暫存檔案全部刪除,即可安裝了。

2013年3月20日 星期三

callback function 與 decorator ( 以 python 為示範 )

    在網路上看到有人問 callback function 和 decorator 有何不同。 基本上,他們兩個完全是不同概念的東西。 callback function 是指 A function  呼叫 B  function 時,傳入 C function 作為參數。B function 在做一些事情後,可能會呼叫 C function。 C function 在這個情境下就是 callback function。


2013年3月18日 星期一

比較c++、python、go、與javascript的 lambda語法

C++11 算是出了一段時間了,而最近編譯器對 C++11 的支持也越來越完善了。 C++11 有一個新特性,就是支援 lambda 的語法,所以就把一些語言的 lambda 語法拿來做比較。首先是python。

map(lambda s: s * s, [1, 2, 3])
python 的 lambda 語法很好理解,冒號前是參數,冒號後是程式碼。lambda   的限制就程式碼只能夠一行。lambda 可以存取外部變數,但是不能使用 assignment statement。

2013年3月9日 星期六

EZ430-Chronos 運動手錶介紹

 
    這是一隻你可以寫程式在上面的手錶,德州儀器出的。使用 msp430 系列的晶片。 內建溫度、氣壓、電壓感應器、蜂鳴器、三軸加速器、RF收發器(就可以無線溝通,不太確定中文怎翻)。

2013年3月7日 星期四

dict literal 與 dict constructor 的比較

    基本上, dict literal ( 使用{}建立物件 ) 和 dict constructor ( 使用 dict() 建立物件 ) 結果一樣。 只是他們之間仍有些許的差異。

    首先是速度上的差異,當 interrupter 執行到 {} 時,interrupter 會知道是要建立 dict 物件。 然而,當 interrupter 執行到 dict() 時,他會認定執行 function call。因此多個函數呼叫與參數傳遞。不過這兩者間的效能差異不算大,也可能會被最佳化。我用下面程式碼做簡單測試

2013年3月1日 星期五

在 python 中較快的字串加法

在 python、java 中,字串都是不可變的(immutable)。意味著,字串被建立後就不能夠被修改。因此,當你在做 n 個字串加法時,它會產生 n - 2 個暫時字串物件。 為了避免在做大量字串加法時,產生過多的暫時物件。 java 中有 stringbuffer 可以使用。用法如下:

2013年2月28日 星期四

免費跨平台的好用編輯器/ ide

這篇文章是介紹認為不錯的跨平台免費編輯器/ide。因此,要錢的或是不能跨平台的不在考慮範圍內。這篇介紹的軟體都支援多種程式語言,不限於特定程式語言。

以下是我認為編輯器/ide 應該有的功能:

  1.  code/word complement: 這個功能很重要,可以避免打錯字
  2. 可以改字體顏色、與大小
  3. 能夠快速執行或編譯
  4. code navigation: 這個功能主要是在看 code 時比較方便

python 的 functools.partial 函數

很久以前,就看過這個  functools.partial 了。 只是一直不太明瞭它的實際作用。直到最近我在讀 c++11 時,看到 std::bind 時,我突然領悟 functools.partial 和 std::bind 做的事情一樣。

2013年2月12日 星期二

2013年2月8日 星期五

淺談 go 語言的defer關鍵字

在寫程式,我們時常犯一種錯誤,就是要了資源,忘了釋放。舉例來說,你 fopen 了檔案,卻沒有 fclose 。你 malloc 一塊記憶體,卻忘了 free 它。 你 acruire 一個 locker,卻忘了 release等等。記憶體管理也許可以藉由GC技術,而減輕許多負擔。但是另外兩種呢?

要怎麼減少犯錯的機會呢?盡量減少fopen和fclose之間的距離,越近越好。最好是fopen完就呼叫fclose,這樣犯錯的可能性就降低很多了。

2013年2月4日 星期一

淺談python繼承

最近無聊翻了一下書櫃,找到一本買了卻沒讀完的書,exceptional c++。就稍微看了一下,看看裡面有沒有什麼文章對於寫python code有助益的

那本書條款24(第104頁),是在討論有關使用/濫用繼承。

2013年2月3日 星期日

arduino與人體紅外線感測器 (PIR Motion Sensor)

這篇文章使用的是焦電型人體紅外線感測器 ( PIR Motion Sensor )。焦電型人體紅外線感測器有三個接腳,分別是汲極(D)、源極(S)、和閘極(G)。汲極接arduino的5v腳位,源極接arduino的類比輸入腳位,閘極接arduino的gnd腳位。最簡單的電路就完成了。

2013年2月2日 星期六

如何透過serial和 launchpad溝通(使用energia)

如果你的板子是msp430g2553的launchpad,你會發現energia的communication範例無法使用。原因很簡單,因為msp430g2553的板子要改跳線才能通訊,r1.4和r1.5的方法又不一樣。r1.5的改法比較簡單,只要把rxd和txd從直的改成橫的(當你看板子時,VCC到P2.2時是直的情形)。

2013年1月31日 星期四

將raspberry pi改成bt下載器


raspberry pi 是一台價值美金$25美元的電腦。處理器是ARM1176JZF-S (armv6k) 700 MHz,記憶體規格有256MB和512MB的版本。可以安裝Linux上去。

雖然他是在arm板子上,可是能跑Linux,自然而然可以跑許多Linux上的應用。以下內容是基於Raspbian “wheezy”作業系統。Transmission 是一個網頁介面的BT下載器,讓你可以遠端操控你的BT下載電腦,而不用特地為BT下載器電腦加裝螢幕或是使用switch。

2013年1月24日 星期四

MSP430_LaunchPad在ubuntu使用教學



安裝指令
sudo apt-get install gcc-msp430 msp430-libc mspdebug msp430mcu
編譯用的指令,記得加-mmcu,不然會發生一些變數無法link的情形,我的板子是msp430g2553,所以用下面的指令。

2013年1月20日 星期日

程式語言分析



這篇文章是當初我找工作時,履歷的附加檔案。基本上只是我個人的主觀意見。每種語言都有各自的愛好者,且每個人的偏好也不一定相同。選擇自己最喜歡的語言即可。



2013年1月5日 星期六

[程式語言] 淺談Python的預設參數

這篇文章是要討論python的預設參數


def fun1(a=0):
        print a

def fun2(a=[]):
        a.append(1)
        print a
        print 'address: ', id(a)

class DefaultObject:
        def __init__(self):
                print 'call me'

def fun3(a=DefaultObject()):
        print 'address: ', id(a)

2013年1月4日 星期五

[軟體工程]如何寫出意圖使人犯錯的程式碼

因為一些因素,讓我學習到一段程式碼,這段程式碼就是這篇主題的主角,意圖使人出錯的程式碼。
這段code的規格是
初始化玩遊戲後,確保有一個使用者在遊戲裡面,所以要在init結束前呼叫join。
至於規格為什麼要這樣設計,不要問我XD
 原本的code是python的。我把python的code轉成用c++來表達,所以function前面都會有virtual,以符合python情形。