2011年11月30日 星期三

Linux和Windows的換行字元

Linux和Windows所使用的換行字元是不一樣的
在Windows底下是使用\r\n (0x0D 0x0A)
在Linux底下是使用\n (0x0A)

因此如果你把Windows上建立的文件搬到Linux上用editor看的話
會在每一行的最後面看到一個 '^M' 的字元
這是因為Linux的換行字元只有\n,因此會把\r給印出來

這點可以做個簡單的實驗來觀察
sway:~/tmp$ ls
hello_linux  hello_windows.txt
hello_linux是在Linux產生出來的檔案
hello_windows.txt是在Windows產生出來的檔案
之後我們用od把ascii dump出來看
sway:~/tmp$ od -c hello_windows.txt
0000000   h   e   l   l   o  \r  \n
0000007

sway:~/tmp$ od -c hello_linux
0000000   h   e   l   l   o  \n
0000006
可以發現Linux下是使用\n當換行字元
而Windows是使用\r\n

這些多出來的'^M'有時後會造成程式的錯誤
當我們把檔案從Windows搬到Linux底下有沒有什麽解決方法呢?
有一些方法,解決方法如下:

1.
dos2unix [-kn] filename [new filename]
sway:~/tmp$ dos2unix -k -n hello_windows.txt new_hello_windows
2. 在Vim下輸入指令,用Regular Expression把\r取代掉
 :%s/\r//g  
3. 用tr把\r給清掉
cat filename | tr -d '\r' > new filename
sway:~/tmp$ cat hello_windows.txt | tr -d '\r' > new_hello_windows

2011年11月28日 星期一

學徒模式:優秀軟體開發者的養成之路

一開始我以為這本書是在講軟體工程的書,不過實際看過才知道跟我想的完全不一樣。這本書的重點不是那些技術性的內容,而是在講解如何成為一個優秀軟體開發者。這本書教了一些態度以及一些方法。

本書主要圍繞幾個重要的觀念。第一就是要熱愛你的工作,一個偉大的工匠必定十分熱愛自己的工作,而不是只是為了錢在工作。本書也教了一些方法幫助你找回你當初學程式的熱情。再來你要找到一些志同道合的朋友以及導師和他們討論學習,如果你在一個周圍每個成員都比你厲害的團隊,相信你一定會成長的很快。這部份書中也舉了一些建議,比如說多參加研討會或是參加社群的活動。除了持續學習以外,本書也提到保持謙虛的重要性。當你學得越多越會覺得這條路是永無止境的,只有水還沒裝滿的杯子才有辦法繼續裝更多的水。

這本書很適合有一些經驗的程式設計師看,也很適合剛學程式的新手。總而言之,保持對軟體開發的熱情非常的重要,一個沒有熱情的程式設計師絕對沒有辦法成為一位軟體大師。

2011年11月22日 星期二

C語言之修煉與實踐


這本書是我看過C語言入門書籍中,少數有講解到一些比較進階議題的書。作者一開始就先介紹了GDB和Makefile,在介紹function call時順便介紹了memory layout,在講static和extern的時候介紹了binding等一些compiler的issue。因此我覺得這本書不但適合新手看,也很適合有寫過一些程式但是還不太熟的人看。如果是新手的話,這本書可以幫助你稍微瞭解一些底層的觀念。比如說call by value,這本書就有簡介了一下stack frame會怎麼長,variable會放在什麽地方。這些部份是我在傳統的C的教科書中比較少見的。至於有些經驗的程式設計師則可以再複習一次這些觀念,書中有些範例我個人覺得還蠻有用的。

我一直覺得學程式很多盲點就在於這些compiler幫你做的事情,因為這些東西你看不到,感覺起來就會很抽象。大多數的書本也只要你死背而沒跟你說為什麽。但是這些東西我覺得對於一位程式設計師來說是很重要的,這本書做了一些簡單的介紹,有興趣的讀者看完這本書後可以再看一些更進階的書。

一個整數中有多少個bits被set成1(How Many Bits Set)

這個問題有一個很好記的解法
此方法是在C的聖經 The C Programming Language 的一段範例程式
#include <iostream>
using namespace std;

int main() {
    int val;
    unsigned int count = 0;

    cin >> val;

    while (val) {
        val &= (val - 1);  // clear the least significant bit set
        count++;
    }

    cout << count << " bits set" << endl;

    return 0;
}
val &= (val - 1)這行code每做一次就會把最右邊的bit清成0
因此用這個簡單好記的方法就可以算出有多少bit被set
當然,這個方法並不是最快的方法
worst case會出現在所有bit都被set的情況
這個網站提供了很多神奇的演算法
有興趣的人可以上去看看

2011年11月17日 星期四

[MFC]從螢幕擷取畫面並存成bmp檔的範例程式

這段MFC範例程式會從目前視窗擷取800*600的圖片,並存成.bmp檔
檔名為目前時間,所以需要#include <ctime>
存好的檔案會放在C:\
 
 CDC* pDC = GetDC();

 //create a memory dc
 CDC memDC;
 memDC.CreateCompatibleDC(pDC);

 //Create a memory bitmap
 CBitmap newbmp;
 newbmp.CreateCompatibleBitmap(pDC, 800, 600);

 //select the bitmap in the memory dc
 CBitmap *pOldBitmap = memDC.SelectObject(&newbmp);

 //blit from screen into memory dc
 memDC.BitBlt(0,0,800,600,pDC,0,0,SRCCOPY);

 //select old bitmap back into the memory dc
 memDC.SelectObject(pOldBitmap);

 //release the Display DC
 ReleaseDC(pDC);

 time_t timestamp;
 timestamp = time (NULL);
 CString loc;
 loc.Format(_T("C:\\%ld.bmp"), timestamp);
 LPCTSTR img_name = (LPCTSTR)loc;
 CImage img;
 img.Attach((HBITMAP)newbmp.Detach());
 img.Save(img_name,Gdiplus::ImageFormatBMP);

2011年11月11日 星期五

Designing Embedded Hardware(設計嵌入式硬體)


這是一本給嵌入式初學者看的書,不過這本書和市面上大部分嵌入式的書籍都不太一樣,對大多數資工背景的學生來說,這是一本很硬的書。作者花了很多時間在介紹硬體相關的議題。前幾章在介紹簡單的電子電路學、焊接工具、示波器,中間幾張花了一些時間在介紹嵌入式常見的協定(SPI, I2C, USB, 紅外線, RS232),最後是介紹幾個常見的處理器架構。

和一般書籍不同的地方,這本書每一章幾乎都會舉一個實際的例子,示範怎麼真的把線路圖兜起來,並講解一些電路是如何實做的。因此如果你之前沒有修過微處理機相關課程的話,這本書對你來說會很難看懂他。

這本書我一共看了兩遍,第一遍的時候幾乎都看不太懂。因為我當時完全沒有什麽嵌入式的底子,只是一個會寫軟體的程式設計師。之後實際接觸嵌入式系統一兩年後,我回來再看了一遍這本書。有點底子之後才發現這本書寫得真的不錯,書中舉的一些例子也都是實際上會用到的,尤其是最後幾章介紹了許多常用微處理器的架構(這是2005年的書,不過大多數微處理器到現在2011年都還可以在市面上看得到),非常值得一看,其中甚至有講解Address Decoder和MMU電路的實做。

因此我的建議是,如果你是軟體背景新手的話可以先大概看看就好。幾個重要的協定先看過有概念就好,因為SPI, I2C這些協定沒有實際實做過,只看書是不可能會得(而且書上也只有講最簡單的概念,詳細相關協定還是要去看spec比較好懂)。電路圖如果都看不懂可以先跳過沒關係。等到你真的有實做經驗後再回來看,相信收穫一定會不少。

2011年11月9日 星期三

[Python]畫圖表的好工具 - Matplotlib


碩班要寫論文時常常會需要畫一堆圖表,由於我不太會用Excel於是就選擇Python + Matplotlib來當做我畫圖表的工具。

http://matplotlib.sourceforge.net/
Matplotlib是Python一套功能很強大的畫圖表Library

http://matplotlib.sourceforge.net/gallery.html
上面連結是畫出來的一些範例,基本上所有圖表都可以畫得出來。就算你要自創一個圖表也很簡單,只要自己加進去就好了,因為是他是open source。


  • 以下提供一些簡單的範例,有興趣的讀者可以去查官網上的文件。



#!/usr/bin/env python
"""

Demonstrate how to do two plots on the same axes with different left
right scales.


The trick is to use *2 different axes*.  Turn the axes rectangular
frame off on the 2nd axes to keep it from obscuring the first.
Manually set the tick locs and labels as desired.  You can use
separate matplotlib.ticker formatters and locators as desired since
the two axes are independent.

This is achieved in the following example by calling the Axes.twinx()
method, which performs this work. See the source of twinx() in
axes.py for an example of how to do it for different x scales. (Hint:
use the xaxis instance and call tick_bottom and tick_top in place of
tick_left and tick_right.)

The twinx and twiny methods are also exposed as pyplot functions.

"""

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)
t = np.arange(0.01, 10.0, 0.01)
s1 = np.exp(t)
ax1.plot(t, s1, 'b-')
ax1.set_xlabel('time (s)')
# Make the y-axis label and tick labels match the line color.
ax1.set_ylabel('exp', color='b')
for tl in ax1.get_yticklabels():
    tl.set_color('b')


ax2 = ax1.twinx()
s2 = np.sin(2*np.pi*t)
ax2.plot(t, s2, 'r.')
ax2.set_ylabel('sin', color='r')
for tl in ax2.get_yticklabels():
    tl.set_color('r')
plt.show()

  • 底下是一個長條圖的範例



#!/usr/bin/env python  
import numpy.numarray as na
from pylab import *

#draw plot
labels = ["sample1", "sample2", "sample3"]
size =   [659, 2659, 32384]

x1 = na.array(range(3))*0.9+0.5
x2 = na.array(range(3))*0.9+1.0
x3 = na.array(range(3))*0.9+2.0

#draw bar
width = 0.2
b1 = bar(x1, size, width=width, color = 'c')

#draw tick
yticks(range(0,33000,5000))
xticks(x1+0.1, labels)

#label Y axis
ylabel('Y axis', fontsize=12, fontweight='bold')

xlim(0, x3[1])
ylim(0,33000)
title("This is an example to draw the bar chart",fontsize=12, fontweight='bold')
gca().get_xaxis().tick_bottom()
gca().get_yaxis().tick_left()

savefig('bar_chart.png')
savefig('bar_chart.pdf')
show()

  • 複雜一點的圖形也可以輕易畫出來,以下是一個簡單的範例



#!/usr/bin/env python  
from pylab import *

tmp = 1048576 * 0.0053
xary = [i for i in range(8,512,8)]
yary = [((tmp + 1048576 / i * 0.45)/1000*88) for i in range(8,512,8)]

x2ary = [i for i in range(8,512,8)]
y2ary = [((1048576 / i * 0.0875)+(1048576 * 0.0003223)) for i in range(8,512,8)]
figure(num=None, figsize=(8, 5), dpi=80, facecolor='w', edgecolor='k')
ax1 = subplot(111)
p1 = ax1.plot(xary,yary,'ro')
ax1.set_xlabel('Title1',fontsize=16, fontweight='bold')
ax1.set_ylabel('ylabel1',fontsize=16, fontweight='bold', color='r')
ax2 = twinx()
p2 = ax2.plot(x2ary, y2ary, 'bv')
ax2.set_ylabel('ylabel2',fontsize=16, fontweight='bold', color='g')
title('Title2',fontsize=16, fontweight='bold')
lines = [p1, p2]
legend(lines, ("Test1", "Test2"), shadow=True, numpoints=1)
grid(True)
show()

約耳趣談軟體:來自專案管理的現場實錄



這本書已經是十年前的書,但絕對是一本值得一看再看的好書。約耳用很幽默的方式來告訴大家如何正確的開發軟體,內容不但有軟體開發還包涵了人才招募以及一些對微軟的看法。約耳本身就是一位開發經驗豐富的程式設計師,加上幽默的文筆。如果你是有點開發專案經驗的程式設計師,絕對會讓你看了就停不下來。其中作者對測試人員和人才招募的部份最讓我有感而發。因為這兩點是台灣大多數公司最不重視的幾個項目。 約耳提出了一些他的看法絕對會讓你不由自主的贊同他。

約耳寫得內容其實都有公佈在網路上,台灣也有人在翻譯
有興趣的朋友可以連到網站上去看
這邊我推薦幾個我覺得非常值得看得幾篇文章:

爪哇學校的危害 The Perils of JavaSchools

軟體人員面試教戰守則 - The Guerilla Guide to Interviewing

不用測試人員的五大(錯誤)藉口 - Top Five (Wrong) Reasons You Don't Have Testers

其他文章當然也很棒,總之推薦每個程式設計師都去看看這本書!

2011年11月8日 星期二

[Python]修改Excel中row背景顏色的範例程式


這個範例會建立一個Excel檔案,並把第一行的背景顏色改成黃色
此範例需安裝pywin32
ColorIndex可參考下圖,Sample code設定為36也就是黃色


#!/usr/bin/env python

from win32com.client import Dispatch

xlApp = Dispatch("Excel.Application") 
xlApp.Visible = 1

# Check if any workbook exists. 
if xlApp.Workbooks.Count == 0:
    # If not, create a new one.
    workbook = xlApp.Workbooks.Add()
else:
    # If yes, use the first one.
    workbook = xlApp.Workbooks[0]

# Check if any sheet exists.
if workbook.Sheets.Count == 0:
    # If not, add a sheet to current workbook.
    sheet = workbook.Sheets.Add()
else:
    # If yes, use the first sheet of current workbook.
    sheet = workbook.Sheets[0]
    
# Generate the multiplication table(1x9). 
for i in xrange(1,10):
        sheet.Cells(1, i).Value = i
        # Set the font color
        sheet.Cells(1, i).Font.Color = 0xFF0000
        
# Set the background color of row1        
sheet.Rows(1).Interior.ColorIndex = 36

sheet.Name = "Table"
workbook.SaveAs('test.xls')
xlApp.Quit()
Reference: http://msdn.microsoft.com/en-us/library/cc296089.aspx

[Python]range() and xrange()

在Python中,我們在使用迴圈的時候經常會這樣寫

for i in range(0, 1000):
    print i
for i in xrange(0, 1000):
    print i
到底range()和xrange()有什麽差呢? 其實上面這兩個例子跑出來結果是一模一樣
最主要差別是range()會產生實際的list,而xrange()則是產生一個number generator
>>> range(5)
[0, 1, 2, 3, 4]
>>> xrange(5)
xrange(5)
>>> list(xrange(5))
[0, 1, 2, 3, 4]
range因為會產生實際list,因此當用在迴圈長度很大的時候,會佔掉很大一塊記憶體

for x in range(1, 1000000):
(range會產生一個1~1000000的list)

for x in xrange(1, 1000000):
相反地,因為xrange是產生一個1~1000000的number generator並每次回傳一個值給迴圈,在這個例子會比range()來的節省記憶體

因此建議在大範圍的迴圈盡量使用xrange(),除非你真的要產生一個list

當然有些例外,range()會比xrange來的好
比如說,當迴圈每次都固定會執行一個範圍時(不會中途break),使用range()會比xrange()來的有效率,因為不用每次都生成一個number(當然,記憶體一定是range使用的比較多)
另外當你真的需要list的時候,就只能使用range()