Tag

2013年12月25日 星期三

ADS_origin_converter v2

今天下午發佈ADS origin converter v2

新增下列功能:
一、原本是進入一個prompt讓使用者輸入檔名,使用者試用的經驗表示這實在是太弱了,在windows下最好的使用方式:把要轉換的檔案拖到exe檔上面。
測試之後發現,在windows上把檔案拖到exe檔上面,等同將被拖的檔案路徑當成argv參數傳入,因此程式改為輸入參數為要修改的檔名即可。

二、支援多變數檔案:
之前的版本只支援單變數的狀況,這次則加入多變數的狀況,ADS記錄多變數的狀況如下:
sweepvar1 ... sweepvar_n-1 sweepvarn ... data
var1_1 ... varn-1_1 varn_1 ... data_1_1
var1_1 ... varn-1_1 varn_2 ... data_1_2
var1_1 ... varn-1_1 varn_3 ... data_1_3
...
var1_1 ... varn-1_1 varn_m ... data_1_m

sweepvar1 ... sweepvar_n-1 sweepvarn ... data
var1_1 ... varn-1_2 varn_1 ... data_2_1
var1_1 ... varn-1_2 varn_2 ... data_2_2
var1_1 ... varn-1_2 varn_3 ... data_2_3
...
var1_1 ... varn-1_2 varn_m ... data_2_m
新版的會以前幾個變數產生tital name,例如在上述狀況,最主要的index是sweepvarn,不斷重複的則是data,上述的狀況會產生為:
sweepvarn tital1 tital2 …
varn_1 data_1_1 data_2_1 …
varn_2 data_1_2 data_2_2 …
varn_3 data_1_3 data_2_3 …
...
varn_m data_1_m data_2_m ...

產生的第一個tital會是:
sweepvarn 之後則是
sweepvar1=var1_1,sweepvar2=var2_1, …sweepvar_n-1=varn-1_1
好像不好看懂,總之就是tital會是第二-n個變數的數值。

目前有一個已知難防的bug是,顯示的變數名稱不能有空白在裡面,因為斷詞是以空白為基準(好像也沒有更好的斷詞方試),有空白的變數名稱會造成tital產生錯誤,目前無解。只能要使用者不用掃有空白的變數名稱,例如:
I_Proble[0, ::]

安裝方式: 在下方github頁面,選”Download As zip”,解壓後直接將檔案拖到ADSToOrigin.exe上面即可。

--

本程式公開所有程式源碼,請見github,請眾位大神鞭小力一點>_<
https://github.com/lc85301/ADSToOrigin

2013年12月19日 星期四

應用git stash 於多分枝之版本控制

本文是要說明git中stash指令的應用,基本需要先知道git 基本的add, commit,以及branch的功能。

使用git進行版本控制,branch是相當重要的功能,一般會建議要開發一個新的功能,就要先分出一個新的branch,開發好新的功能後再merge到master的版本內。
編按:雖然話是這麼說啦,可是筆者在實作時通常還是一個master branch一直commit下去XD。
當分枝一多的時候,就會出現一些問題,例如在一個分枝中修改到一半的內容,例如:「雷射彈幕」,這時有些點子想要切到另一個分枝中修改其他內容,但這個「雷射彈幕」的功能還沒達到可以commit的等級,就需要stash來暫存目前修改的內容。
--

下面是git stash的相關操作環境範例: 我們有個master branch跟開發中的feature branch,現在在feature branch中開發一個新的feature,加入並commit "featurefile"這個檔案
$ git checkout feature
$ git commit featurefile  <-注意一般是不這麼寫的,這裡是為了說明方便。
some modification on featurefile
$ git checkout master
這時候我們會得到一個:
error:
Your local changes to the following files would be overwritten by checkout: featurefile Please, commit your changes or stash them before you can switch branches.
Aborting
因為切到master branch會清掉已修改的內容,而git不會輕易讓你這麼做。

這時候就要先stash(暫存)它,stash有點像commit,不過沒有commit這麼正式,使用:
git stash (save)
git stash list
git stash pop
git stash drop
save: 存入一個暫存,可以不打,git stash預設
list: 列出目前有的stash
pop: 取出暫存
drop: 刪掉暫存

在這裡我們就直接git stash,這時候會看到所有還沒commit的修改都已經消失,用git stash list會看到:
stash@{0}: WIP on feature: ef9d050 feature initial commit
這裡重要的是“0”這個數字,這是stash的index;另外”feature initial commit”則是這個stash是這在哪個commit中分支出來的。
Git stash時還可以加上message來取代上面的ef9d050 feature initial commit這段
git stash save “this is temporary stash of master commit”
不過這在stash量很少的時候大概不太需要用到。

現在我們已經可以切回master的branch了。在master進行修改後,同樣不想commit的內容也可以用stash進行暫存,這時候git stash list會變成
stash@{0}: WIP on master: e194f69 master initial commit
 stash@{1}: WIP on feature: ef9d050 feature initial commit
分別標示了從master和featurecommit中暫存的內容。

--
要取出stash的內容,我們用git stash pop,這預設會取出stash index 0的內容,如果要取出其他stash的內容,就要用例如:
git stash pop stash@{1}
在後面打上stash完整名稱。
取出其他index的內容相當重要,像在例子中,如果我們先切回feature branch,再pop出在master branch中記錄的stash,這個效果和pull是類似的,若是有衝突的檔案就會要求merge,會很麻煩,個人是不建議在這種狀況下進行merge,畢竟當初就是不想記錄下來才用stash,現在要是merge就記錄進去了。

 如果要刪掉已經存入的暫存就用
git stash drop
刪去就行。

 祝大家git stash愉快

2013年12月15日 星期日

mex編譯環境設定

mex是matlab提供的編譯器,可以在matlab編譯外部的c/cpp(也許還有fortran =w=?)程式,可以用matlab的方式把資料塞給外部程式,回傳資料也可以用matlab收下來。
幹嘛沒事叫外部程式,用matlab寫不就好了?據同學強強林的說法是編外部的cpp code會跑得比較快,實際情形是如何其實作者也是啊哈哈不是很清楚。
最近因為修課的關係需要用到matlab mex,就順手編了一下,把過程記錄一下:

--

因為mex是用其他編譯器來編譯,因此要先設定系統的c/cpp編譯器
如果是Unix/MacOS的話,大概都已經裝了gcc/g++了,在matlab內打mex -setup,應該可以看到選項;windows的話請看參考資料一,這部分沒有研究。
這裡會遇到一個問題是,matlab未必支援最新版的gcc/g++,要看你的matlab版本
我是2012a版支援到gcc 4.4.6,偏偏我用archlinux,套件幾乎都會升到最新(4.8.2),這時候matlab就會回報用了太新版本的gcc。

解決方式是安裝舊版的gcc/g++ 如果是archlinux的話可以用AUR安裝,其他發行版應該有自己的解決方式。
因此先重編了4.4.6,桌電上50MB的檔案我編了快1hr …(結果筆電用-j8下去編跑得桌電快lol)

--

接著要設定gcc版本,在matlab安裝路徑(我的是/opt/MATLAB/R2012a)下有bin/mexopts.sh,把裡面的gcc/g++都換成舊版的

# C++keyName: GNU C++
# C++keyManufacturer: GNU
# C++keyLanguage: C++
# C++keyVersion:
CXX='g++' <-換掉這行g++ → g++-4.4
CXXFLAGS='-ansi -D_GNU_SOURCE'
CXXFLAGS="$CXXFLAGS -D_FILE_OFFSET_BITS=64"
CXXFLAGS="$CXXFLAGS -fPIC -pthread"
CXXLIBS="$RPATH $MLIBS -lm"
CXXOPTIMFLAGS='-O -DNDEBUG'
CXXDEBUGFLAGS='-g' 
我是archlinux就是換成gcc-4.4/g++-4.4,其他發行版我不是很確定舊版裝好是像這樣加個版號,還是要把本來的gcc替代掉
接著在matlab裡面輸入
$mex -setup 代入舊版的gcc/g++
之後mex就可以正常使用囉。

參考資料:
1. http://www.physik3.gwdg.de/tstool/HTML/node9.html
2. archlinux AUR gcc44
https://aur.archlinux.org/packages/gcc44/

2013年11月16日 星期六

使用振盪器改善投擲器鏈之鎖死問題

個人很常玩minecraft大概不用提,最近在建造分類工廠時,遇到「將物品向上傳送」的設計問題,因為一般的漏斗只能水平傳送或是向下傳送,如果不想要讓玩家自己把物品拿到高處,就要有自動化的機制才行。
幸好在1.5版之後,新加入大量紅石元件,讓許多過去無法達成的自動化得以實現,本文設計一個利用振盪器驅動投擲器鏈,進而改善過去投擲器鏈常遇到的鎖死問題,分述如下:

1. 過去向上運送法之介紹:
2. 改善投擲器鏈之設計:
3. 設計展示:
4. 參考資料:

1. 過去向上運送法之介紹:
過去常見的minecraft傳送物品向上有五種方法:向上水流運送、活塞運送、鐵路運送、投擲器鏈和玻璃傳送管。
向上水流最大的問題是運送效率不佳,速度最慢還有可能會卡住,同時需要相當大的建造面積。活塞運送也有相同的問題,向上提升一格就要再將物品移動到另一格,也容易掉物品[1]。
玻璃管傳送法見[2],是利用minecraft 的bug feature,物品被由下向上擠壓時會向上移動尋找空間,藉此運送物品,最上方再以漏斗承接運送的物品,事實上不用玻璃亦可達到相同的效果,使用玻璃純粹是可以看到在運送什麼;在長距離傳送上,玻璃傳送管效益最高,使用極少量的紅石電路即可,但物品跑到傳送器外,未免讓人心理發毛,一不小心物品可能會落到管外而遺失。
相較上述三種方式,鐵路運送和投擲器鏈不會將物品轉為實體,可靠性相對較高。
鐵路運送[3]相當有效率,要送高只要多蓋鐵軌即可,只有起迄點需要紅石電路設計,但使用方式是利用箱子一次運送一箱的物品,個人比較不喜歡。
投擲器鏈相對可實現連續、可靠的運送,在過去已有幾件相關設計[4]-[5],這些設計都使用比較器偵測投擲器內的物品,經過回送驅動投擲器向上傳送;這樣的設計有個最大的問題,當投擲器內的東西超過一個時,投擲器發射後裡面還有物品,比較器將不會再更新,使得投擲器錄陷入鎖死,需要以人工手動移除多餘的物品才能再次運作。
特別是一般自動化運送物品都會用漏斗將物品打入投擲器中,而漏斗的運作速率是每秒2.5個(4個redstone ticks),這速率高於驅動投擲器向上的速率;因此兩個設計中都在漏斗旁放上一個紅石作為控制,一但投擲器有東西就停止漏斗的運作,無奈只要這個機制出小差錯,還是要人工介入移除多餘物品。

2. 改善投擲器鏈之設計:
為了改善這個問題,本設計使用主動振盪器來驅動投擲器向上,雖然需要多一點的面積,不過這個機制保證投擲器會運作到整條投擲器鏈都沒有東西為止,主要分為三個部分:偵測器,Or gate,振盪器:

偵測器:
左右兩邊交互放置比較器偵測投擲器鏈內的內容,由於比較器輸出強驅動訊號,因此只有圖中紅色block上會放置紅石,上一層的比較器可透過白色方塊傳遞給下層紅色block,如圖所示:

Or gate : 上一層的紅色block訊號,會經過兩次not,送給下一層的訊號;加入repeater的目的,是要防止自身紅色block的強訊號覆寫下一層not過的訊號,否則當整條鏈中只有紅色block該層投擲器有東西時,振盪器也不會驅動。

振盪器: 將訊號集中起來,驅動比較器制成的高頻振盪器,透過半板向上送給每一個投擲器,即完成本設計。

本設計缺點有,一、振盪器的傳送距離為15格,大約只能送12層的高度,可以在上層設置另一個振盪器來解決這個問題,但會佔掉一些樓板面積;或者不求速度的話,可以用比較慢一點的振盪器,就可以用「block-紅石火把」的組合將訊號向上傳送,如圖所示;不過若是超高層傳送,玻璃管傳送法會是比較有效率的做法。二、運作起來相當吵,這個是真的沒得解。


3. 設計展示: 在底部送入物品,都會送到頂部的箱子中,兩段式的版本也可以運作正常,前述的噪音問題在兩段式版上會更明顯,因為這裡用的是比較器振盪源,比較器只有1 ticks的延遲讓投擲器的運作快過漏斗的運作,一開啟就會聽到投擲器時停時開的嗒嗒聲,其實相當煩人。

4. 參考資料:
[1]. water
https://www.youtube.com/watch?v=z1rAiPsCj5Q
[2]. glass tube item lifter:
https://www.youtube.com/watch?v=DtcSljfkMIw
[3] railway item transport:
https://www.youtube.com/watch?v=PLtqJ5gsO9E
[4]. dropper chain:
https://www.youtube.com/watch?v=7OJUHyJfrQE
[5]. dropper chain:
https://www.youtube.com/watch?v=_xu7e97_Qdo

2013年11月3日 星期日

讀機器學習有感

這學期修了學校資工系開的機器學習一課,跟眾多資工系所的大神們一起上課,雖然內心有一些想要用機器學習來解的問題,不過目前還算是「不知道學這個有什麼確實用途」的狀態(啊…我臉書上的好友Ya教授一定會對這點很不爽O_O)。
這幾天複習一下進度,把課本的內容對照筆記再看過一遍,倒是得到一些感觸。

--

現在學習的有Perceptron Algorithm(感知學習演算法),和Linear regression Algorithm(線性迴歸),這兩個學習法從根本上有兩個不同:
Perceptron Learning是給定一大群資料和他們所屬的群體,找出那條分隔線,之後就可以利用這條分隔線作為機器判斷的基礎,這算是最最基本的機器學習演算法;要怎麼讓機器學到這條線呢?做法很簡單,針對每個點,要是現在的分隔線分錯了,就用這個點的資料去更新這條線,求到錯誤最少的那條線即可,很可惜的,要直接找出那條分隔線,已經被證明是一個NP-Hard的問題,所以我們用了一個替代的方法:一個點一個點的更新,然後記住那條表現最好的線,時間久了,這條線就是我們想要的解。

和Perceptron Learning 相對的,另一種是Linear regression: 這次我們不是要把資料分兩群,而是送來一大群資料和他們的評分,要找一個預測式,能讓預測結果和評分間的均方差(square error)為最小,和上一個問題不一樣,這次我們只要拿到資料建成矩陣,做點線性代數的運算就能直接算出解,完全不需要迭代。
不同的問題,卻讓解法天差地遠,Perceptron需要不斷迭代,找尋錯誤;Linear Regression卻像先知一樣,我說這個是答案,那這個就是答案。

像Linear Regression這樣又快又準的演算法,反而讓人覺得不像是「機器學習」,它沒有學嘛。
我們對「學習」這個詞的解釋,比較像Perceptron這樣,這筆資料我錯了,看看我錯在哪?錯了多少?把它修正回來,於是「學」會怎麼處理這筆資料;像Linear Regression這樣,那不是學習,那是工程計算,稱它為「機器學習演算法」,不免心理有些疙瘩。

--

可是話又說回來,我們的教育制度,不是一直著重公平的考試,不要真正能看學生學會什麼的申論題,不要能看學生推論過程的證明題,只留下有標準答案的選擇題。
結果學生被訓練成對選擇題有反應,給一串題幹說明,再給四個可能對、可能錯的答案,要在最短時間內選出正確的答案,於是學生不再是學習問為什麼,而是背頌式的「知道」答案,對照街上林立的補習班,這豈不和我們上面對「學習」的意義相反?

--

我們要機器像人一樣學習、卻要人像機器一樣學習,豈不本末倒置?想起來有夠荒唐。

2013年10月29日 星期二

git partial add

Git 是一款極為強大的工具,雖然說過於強大的功能有時會讓人感到卻步,我也是一項功能一項功能慢慢學,不會的時候就抓著會的同學問,好不容易才變得比較會一些。
最近新學會的功能是git的partial add功能,在這裡做個簡單的介紹:

使用partial add 的功能,可以讓我們每次只commit一部分的東西上去,假設我在某程式開發了讀取、寫入兩樣功能,比較好的做法是讀取部分和寫入部分可以分開commit。有一部分原因應該是這樣比較分得清楚,如果之後要從這個commit中取出修改內容,或是再修改時都更清楚一點,雖然說筆者到現在也沒有做過這樣的事,不過養成一個好習慣也是好事。

 --
要partial commit,第一步是先partial add:
假設今天我對一個main.c的檔案,新加上兩個function foo1, foo2,這時候使用git add -p main.c,git顯示出main.c裡面有差異的部分,這時候可選選項:

 y,n,q,a,d,/,s,e,?
 y/n: 加入/不加入這個區段
 q/a: 不加入/加入整個檔案
d: 不加入這個區段,跟之後所有的區段;我得承認不確定它跟q的差別... /: 尋找regular expression;啊老實說我也沒用過OAO
 j/k: 跳到後/前一個undecided 區段
 J/K: 跳到後/前一個區段
 s: 分開這個區段
 e: 手爆編輯這個區段
 一般來說,git會把相近的修改區間放到同一個區段裡面,下(s)plit指令,git會用原檔案中「未修改的部分」把修改區間切開,例如圖中fun1-fun3是同一個區間,下s的話fun1, fun2會被切成一個區間,fun3切成另一個區間,但s並不會切開fun1和fun2。
如果fun1, fun2要分開commit的話,就要用(e)dit,跳出編輯器介面。

新加入的修改會有'+'在行首,不加入的話刪掉即可,vim: dddddddddd。
刪除的則是'-'在行首,不加入的話把'-'替換成' ',這個用vim的ctrl+v很容易就可以做到。
筆者試過一次在這個狀態下去修改原始碼,git會叫說patch產生錯誤,大概是不能這麼做,只能把你加上去的內。容刪掉,或是刪掉的內容mark成' '來復原刪除。

 --

commit時,直接git commit 就可以把add過(正式名字應該是staged)的內容commit上去。
這時不要使用git commit main.c,這會將檔案內容全部staged然後commit 上去,有一次筆者先partial add後下了commit file,再下git status就發現這個檔案已經全部stage進去了,沒什麼修改可stage…。
另外一個要注意的是用partial add的話,在回復的時候一定要非常小心,例如在上例中我們add了fun1 這時候原始碼的狀況是:
main() → 上一個commit
fun1() → staged
fun2() → unstaged
注意到fun2是unstaged,如果你亂改到什麼想要回復,而下:
checkout -- main.c
回復到上一個狀態,fun2的原始碼(該說它從來沒被記錄下來)也會整個被消掉。

2013年10月8日 星期二

ADS Export to Origin converter

最近在準備一些學校報告用的投影片,在學長主持的小咪報告之後:
學長:「你這幾頁的圖,如果之後要放論文的話,就乾脆用Origin重畫」
好吧學長都這樣說了,就來畫畫Origin的圖wwww
不過秉持著用開源軟體的精神,還是找了一下,結果就在[1]的作敏學長的blog裡面找到qtiplot這個開源繪圖軟體,跟Origin的功能幾乎差不多。

1. 問題簡述:

這裡遇到一個有點機車的問題:
平常我們在ADS這套軟體畫好圖之後,如果用ADS再export成txt file,就會變成類似下面的格式:
 freq S(1,1)
1e9 -1E1
2e9 -1E1
3e9 -1E1
4e9 -1E1

freq S(2,1)
1e9 1E1
2e9 1E1
3e9 1E1
4e9 1E1
註:隨便選個數字表示一下。 但如果要用Origin匯入文字檔的話,理當是這個格式比較好:
freq S(1,1) S(2,1)
1e9 -1E1 1E1
2e9 -1E1 1E1
3e9 -1E1 1E1
4e9 -1E1 1E1
俗話說得好:科技始終始於惰性,與其用Excel打開檔案然後一欄一欄複製貼上,不如寫個script來解決 =b,另一方面還是要再次強調我的哲學:「work hard, after you know you are working smart」。

2. 解決方案:

最後還是用我們的老朋友python,實際譔寫時間約30分,超快der;會慢主要是在查zip的寫法;實際內容大概也只有zip比較有趣。
首先先把資料一行一行讀進來,寫入list裡面。讀檔結束就會有一堆list,分別存著freq裡所有的資料,然後是S(1,1), S(2,1),我在讀檔時就先把這些list存到一個大list裡。
假設我的大list為data,data 的長相大概像這樣:
data = [[S(1,1)],[S(2,1),....]]
於是我們可以先展開data list為所有list,然後透過python 強大的zip函式,直接iterate所有的list。
For line in zip(*data):
outfile.write(“%s\n” %(“\t”.join(line)))
很快速的就完成檔案格式化寫出的工作。

3. windows版本:

在改windows版本的部分,則是把本來要吃參數的script改成吃使用者輸入的內容。
照著[3]的幫助,首先先安裝python和py2exe,利用py2exe把python script轉成exe檔。
先寫一個setup.py:
from distutils.core import setup
import py2exe

setup(console=['ADSToOrigin.py'])
然後在cmd用
python setup.py py2exe
就會自動產生dist這個資料夾,裡面會包括ADSToOrigin.exe,打開就會開console,像linux一樣正常使用。

 4. 原始碼公開: 這個script已經公開在我的github上:
https://github.com/lc85301/ADSToOrigin
歡迎大家給feedback或來pull request。

 5. 參考資料:
1. http://zuomin.blogspot.tw/2010/05/linux-origin.html
作敏學長:qtiplot介紹。
2. ptt python 版3115篇:python list iterate介紹。
3. http://logix4u.net/component/content/article/27-tutorials/44-how-to-create-windows-executable-exe-from-python-script
py2exe tutorial
4. python official site: http://www.python.org/
5. py2exe official site: http://www.py2exe.org/

地心引力Gravity(有電)

要我用一句話評這部電影,我會說:「這是一部比較接近太空的太空電影」

以太空為題材的電影很多:經典像是連歐巴馬都會弄混的Star Trek和Star Wars;加上怪生物的異形(啊…我內心一點也不把它們當太空電影);算上動畫的Gundam好了;比較真實一點像這部地心引力,2001太空漫遊、Apollo 13,還有一部一堆老頭子修衛星的電影,我忘了叫什麼名字了。

--

像Star Trek 和Star Wars這類的電影,是在拍太空中的地球故事,它們是靠太空的無垠,來發揮無限的想像力,地球上都是異性戀那外星人可不可以是同性戀,啊不對,能不能有犯錯就絕對死刑的民族?少了感情的種族會怎麼樣?如果我們可以隨意修改時間線?機器和肉體合成的集合體?具有無上神力的神族變成人類?
太空有無限的可能性、有無限的故事可以講。 至於真的太空長什麼樣子,其實不是很重要,它在拍地球的故事。

這裡我不想講異形,我除了它太空來的跟瀕臨絕種外一無概念。
至於Gundam雖然有太空、星艦也是無重力,但和真實的太空還是相去甚遠,巨大的鋼彈想動就動,完全無視真實的太空狀況;星艦的無重力胡搞一通,不真不假。

首先拍出真實太空的當屬2001太空漫遊,也成了很多太空片致敬的對象,例如飛到外太空的時候瞬間變成靜音的效果,在新版的Star Trek裡用了不少。

說完這麼多太空片,說回我們的主題Gravity?
這部片跟之前很多評論說的一樣,這完全不是大眾片:
你期待有什麼高潮?沒有=_=
俊男美女?沒有=_=,每個人都包在厚厚的太空衣下,女主角也不正
整片很安靜、很平靜,靜到令人不安……。

正如開頭字幕所說:太空沒有聲音介質、沒有空氣,沒有重力和地面,我們覺得行動很簡單,那是因為我們有地面和重力;這也是為什麼上面會說鋼彈都是亂搞,很多地方主角們移動莫名的自由,想動就動,想停就停,這個無重力只是效果,例如男主角可以飛撲到女主角身上接吻,不是內容。

這片講的是真正的太空,從上而下,你可以看見夜間尼羅河沿岸的燈火、中美洲細長的陸地、北極舞動的極光,宛在夢中。

但當女主角和太空梭脫離,只能無助的飄盪,分不清上下左右,止不住旋轉;就算想抓住國際太空站時停下自己也十分困難。
絕望的無助。
男主角(喬治克隆尼)為了不讓兩人一起飄走,切斷兩人間的連繫索,在太空中這無異自殺,就看見男主角愈飄愈遠、愈飄愈遠…然後不知何時通訊中斷。
孤寂的死亡。
在國際太空站上,當女主角試圖分離降落艙,破片群正在一塊塊擊碎國際太空站。先是一小塊破片飛過,破片漸多,有的打中太陽能電池板,然後大破片擊中主艙,炸出更多破片,化成一堆破片群;一個太空站就這樣無聲的消滅了。
無聲的破滅。
全片充滿著肅殺的氣息,靜到讓你透不過氣。

太空的美麗故然讓人屏息,太空的危險讓人敬畏。 想要體會一下,可以看看這部片,我自評是7分,贏在前所未見的創新;輸在過短、有些單線化的劇情。
但就先前有些負電的評論,我還是要說:如果你進電影院是要享受聲光效果、享受大場面的話,請不要進電影院,這部不對你的胃口。

2013年9月24日 星期二

寫了一個管理帳號的script

差不多去年這個時候,小弟魯蛇剛接任所上的linux工作站網路管理員。
本來以為是個輕鬆的職位,畢竟先代某陳姓大網管超~級~強~,工作站維護得這麼好,佈線設備也都沒什麼問題,我們應該也只要做點基本維護就好,結果工作其實還頗多(OAO)。
要幫所上的人申請新帳號;幾台伺服器還裝著mandriva 2009,久未更新,很多套件可能都過期了,需要用主流的CentOS或Debian來取代;有的工作站連yum都沒有,只能抓rpm,那時候試著要裝yum,結果遇到瘋狂的相依關係,最後只好放棄;最後還有工作用的軟體跟license server需要維護。

最近為了減輕一些工作,就寫了一個自動加入帳號的script,理論上用bash script應該就做得到,不過考量到其中有許多文字處理,數字比對的部分,最後還是用python的譔寫,雖然說nis主機也是debian 5的老主機,必須用python2.5來譔寫有一點troll,不過還是比用shell快一點。

ps:其實linux工作站使用人數比較少,理論上用vim手動加搞不好比較快,不過當作python練習XDD。

一、帳號記錄文件:

伺服器使用的帳號記錄是nis,內容跟/etc/passwd沒什麼兩樣,類似這樣: account:passwd:uid:gid:comment:homedirectory:shell
這沒什麼好講的,大部分的內容都是預設,比較不一樣的是我們uid, gid設定:為了管理方便,我們的gid是以1k為單位分給一位教授,對應可使用的1000個uid,例如某葉教授(咦)的gid為10000,那uid就從10000-10999,下一位教授就從gid, uid為11000開始。
註:這樣每個教授可以收1000位學生,就算每學期收個20個,也要收50年才行,應該頗夠用吧XD

二、程式規劃:

規畫程式的功能如下。
功能一,加入使用者:
1. 詢問使用者帳號名稱(account)
2. 列出目前可用的gid列表,要求管理者選擇。
3. 查詢目前表列的uid,取得下一個uid值。
4. 請管理者輸入comment。
5. 列出homedirectory資料夾選項。
6. 詢問使用者密碼。
功能二,刪除使用者:
這個比較簡單,把account comment掉就是了。
第二部分,實際操作:
1. 備份檔案,複製一份檔案,儲存為原檔名.日期。
2. 將要加入的內容寫入passwd檔中。
3. 呼叫ypinit -m更新資料庫。
4. 呼叫ypasswd修改密碼檔,這部分用pexpect達成。
5. 產生一份需要建立新資料夾的資料夾位置,到nfs使用。

三、實作:

上述功能看來有點多,其實寫起來滿快的,幾個小時吧。主要是python功能過於OP,大部分慢下來的地方都是我腦殘忘記該怎麼寫,或是為了使用python 2.5以致需要去查語法。
程式大部分是使用python 的list來硬幹,儲存需要寫入的字串,將需要增加的或刪除的資料新增到list之中。

大概沒什麼好講的,唯一值得一提的就是發現python 整合了expect的功能:pexpect,原本呼叫yppasswd的部分想要用expect來寫,但發現用pexpect比較方便,也可以把改密碼的工作交給python去執行,比分出一個expect script還要方便。
跟上一篇的expect講的差不多,pexpect同樣支援spawn, expect, send等基本語法
例如程式中需要設定新加入使用者的密碼:
for key,val in passwddict.iteritems():
    print("change passwd of user %s" % key)
    rootpass = “rootpassword”
    child = pexpect.spawn("yppasswd %s" % key)
    child.expect('password:')
    child.sendline(rootpass)
    child.expect('password:')
    child.sendline(val)
    child.expect('password:')
    child.sendline(val)
    child.expect(pexpect.EOF, timeout=None)
從存好的dictionary裡面取出一對帳號跟密碼,然後去設定passwd,同樣的缺點也是root密碼會曝光,權限要小心設。

PS:剛剛發現暑假過太頹廢,從八月中到現在都沒寫新文,看到同學們都在當助教惹,自己也要努力點才行。

2013年9月20日 星期五

使用Expect進行大量修改密碼

Expect 最近稍微研究了一下expect這個工具,簡單來說,它可以作為使用者對shell的代言人,本來需要大量使用者回應的工作,可以交由expect來處理,主要的資料是參考資料2,瀏覽書還是吸收技術最快的方法。
最簡單的工作,就是由expect來幫我們輸入密碼,例如我們要改帳號,都需要輸入舊密碼和兩次新密碼,如果有1000個帳號要修改時,等於要輸入3000次密碼,如果兩次新密碼打錯的話還會吃屎重來,真是讓人感到絕望…。
再更簡單一點就是管工作站時,要向其他電腦下命令,如果有10台電腦要執行一樣的命令,而且要用su執行?
結果書上還出現用expect來控制gdb的除錯程序,好像有一點猛…

--

expect最基本的指令大概是: spawn, expect, send,有了這三個就能做不少事情惹。 例如我想從工作站上載東西下來:
#!/usr/bin/expect

set password “mypassword”

spawn scp account@workstation:/etc/hosts . 
match_max 1000
expect "*?assword: "
send "$password\r"
expect eof 
首先我們設定password變數,利用spawn叫shell執行scp指令,當scp要求輸入密碼時,由expect承接,scp輸出內容是account@workstation 's password: ,用*整個接下來;用send把內容傳給shell,就完成一個自動下載檔案的程式了。
唯一要注意的大概只有那個\r回車鍵,沒打那個就相當於打完password後沒按enter,你會看到程式停在螢幕上對你微笑,等你按enter。

上面只是個簡單的例子,回應很單純,不過稍微擴展一下,我們就可以完成一個自動改nis密碼的script
#!/usr/bin/expect

set rootpwd "wwww"
set newpwd [lindex $argv 1]

spawn yppasswd [lindex $argv 0]
expect "*?root password:"
send "$rootpwd\r"
expect "*?new password:"
send "$newpwd\r"
expect "*?new password:"
send "$newpwd\r"
expect eof

使用./script account newpasswd,即可自動修改密碼,只要事先把account跟newpasswd打好,一瞬間密碼就改完了,有幾千人都不用怕。雖一的缺點大概是要把root password明文寫在script裡面,這個script一定要保護好,用root擁有然後權限設成700吧。

參考資料:
1. expect man page
2. http://it-ebooks.info/book/2189/

2013年8月8日 星期四

使用gnu make編譯Qt 專案

最近白天跑EM,夜深寫QT。

當然這完全沒什麼,其他同學至少兩年前就寫過了LOL。

只能說Qt 真是相當強大的工具,最基本的signal & slot的概念,如果對GTK的callback熟悉的話,很快就能上手。
一般在寫Qt時,最常用的還是用qmake來產生Makefile,畢竟qmake寫得還不賴,打一次就會產生好Makefile,接著make即可;不過有時個人習慣還是偏好用gnu-make,可以自己編寫Makefile,做一些細部的調整,用qmake的話只要重新產生一次Makefile,這些細部調整就要重新再修改一次。
這篇就是說明一下,要如何使用gnu-make來處理Qt專案。

--

基本上Qt的運作原理,是對原有的C++進行擴展,然後透過Qt提供的解析程式,產生額外的原始碼檔,少了這些額外的原始碼,在編譯的時候會產生一堆可怕的錯誤資訊,要用gnu-make編譯Qt專案,其實只要呼叫這些解析程式來產生原始碼即可;總共會用到的程式有三個:moc, rcc, uic;分別作用是:產生meta object(故名Meta-Object Compiler)、處理resource(resource compiler)檔、產生介面檔(User Interface Compiler)。

一般Makefile裡面會有這些東西,用來把所有的source轉換成object file。
SOURCE_FILE = main.cpp 
OBJECT_FILE += $(addsuffix .o, $(basename $(SOURCE_FILE)))

為了Qt,我們加上下列的變數定義:
#==================================================
# Qt special function
#==================================================
QT_LIBS = -lQtCore -lQtGui -lQtOpenGL
QT_PATH = /usr/lib/qt4/bin
QT_MOCFILE = mainwindow.h
QT_RCCFILE = resource.qrc
QT_UICFILE = first.ui
QT_MOCSOURCE = $(addprefix moc_, $(addsuffix .cpp, $(basename $(QT_MOCFILE))))
QT_RCCSOURCE = $(addprefix qrc_, $(addsuffix .cpp, $(basename $(QT_RCCFILE))))
QT_UICSOURCE = $(addprefix ui_, $(addsuffix .h, $(basename $(QT_UICFILE))))

這一整個區塊與QT有關,所有參數都加上QT為標示。
QT_PATH設定Qt的執行檔位置,如果安裝在其他地方、或要用其他版本就要自己換地方。
QT_*FILE是先定義,moc, rcc, uic分別要處理的檔案,moc會處理所有.h檔,產生含meta object的cpp檔;rcc會處理qrc file,產生相對應的cpp檔;uic則會處理ui,產生可包入的header file。
透過makefile的suffix, prefix,轉成我們需要轉出的檔案名稱,個人的習慣是在這些檔名前加上關鍵字moc_, qrc_, ui_。

--

接著是利用implicit rules來compile所有的物件檔:
TARGET = program
BIN_DIR = bin
LIBRARY_DIR = library
SOURCE_FILE = main.cpp $(QT_MOCSOURCE) $(QT_RCCSOURCE)
OBJECT_FILE += $(addsuffix .o, $(basename $(SOURCE_FILE)))

由於moc和rcc會產生新的cpp檔,因此需要將它們列入;然後就可以用implicit rules執行:

%.o:%.c
  $(CC) -c lt; -o $@ $(CFLAGS) $(INCLUDE)
  @$(MOVE) $@ $(LIBRARY_DIR)

%.o:%.cpp
  $(CXX) -c lt; -o $@ $(CXXFLAGS) $(INCLUDE)
  @$(MOVE) $@ $(LIBRARY_DIR)

moc_%.cpp: %.h 
  $(QT_PATH)moc $(DEFINES) $(INCLUDE) lt; -o $@

qrc_%.cpp: %.qrc
  $(QT_PATH)rcc lt; -o $@

ui_%.h: %.ui
  $(QT_PATH)uic lt; -o $@
前兩項是將c/cpp-編成 .o檔,當遇到QT_MOCSOURCE, QT_RCCSOURCE的檔案,就會由moc, rcc產生。
另外在編譯主程式的相依性中,原本我們只要它編譯所有的OBJECT_FILE,現在還要加上由uic產生的header file:
$(TARGET): $(OBJECT_FILE) $(QT_UICSOURCE)
  cd $(LIBRARY_DIR); \
  $(LINKER) -o $@ $(OBJECT_FILE) $(LIBS); \
  cd ..
  mv $(LIBRARY_DIR)/$@ $(BIN_DIR)
如此一來,就會觸發uic產生出header file。

--

透過以上的設定,即可完成Qt專案的編譯,不過最後還是要說,雖然我這裡是這麼寫,但其實真的用的時候還是用qmake來產生Makefile =w=,套句AZ大神的話「它寫得這麼好幹嘛不用?你白痴嗎。」

結論:這篇網誌是一篇垃圾,寫Qt請愛用qmake。 lol

參考資料:
1. C++ GUI Programming with Qt 4
2. http://woboq.com/blog/how-qt-signals-slots-work.html

2013年8月1日 星期四

你會拒絕政府的好意嗎?

最近許多事情佔據了新聞版面:國軍虐死案、大埔拆屋案,然後是一些媒體刻意掩蓋的台北違法抓人事件,這些都是政府在迫害人民的案例。

--

這其中大埔拆屋案是最有趣的。
儘管劉政鴻牠拆了一堆人的房子,儘管苗栗債務激增,人均負債升到全國第二;關於他只是要炒地補縣庫的證據如此明確,可是他的支持度還是這麼高,甚至天下雜詩民調的滿意度還有68.9%,遠見雜誌的首長大評比,他還是五顆星的縣長。

這是不是怪怪的?
事實上看看遠見雜誌所寫的內文,政鴻縣長的政績,很多都是用錢堆出來的,也導致苗栗縣債台高築。
引用內文:「2008年11月,首次舉辦大型藝文活動,就邀來世界三大男高音卡列拉斯獻唱,免費讓民眾參加音樂饗宴;12月4日至6日三場愛爾蘭《大河之舞》讓民眾目不暇給。2009年3月更加碼舉辦苗栗國際音樂節,邀請情歌王子布萊恩麥肯奈特、鋼琴玩家邁可森與世界三大男高音多明哥演出。」

請到三大男高音而且是免費的活動,這樣要花掉多少錢?(按:我查到是0.021G)還要加上行銷之類的預算,例如在遠見雜誌的廣告,之類。
還別說每年年底的一定要有的跨年晚會跟煙火,你去晚會有付過錢嗎?請歌手的錢是誰出的?

好聽的這叫「執政優勢」,其實就是買票。
我們總認為選舉買票要走到你門前,把裝著錢的信封送你,然後說投某某垃圾;但政府的好意不來這套,它是更隱晦的買票型式,他用活動讓你覺得:這個政府真好,這位首長有在做事,下次也投他吧。明著買票大家會拒絕、會厭惡;暗行的買票,大家會很高興的收下來,連拒絕都不會;最重要的,你會覺得買票者是真有能力,你真的被買了。

那政府的錢從哪來?靠著舉債而來,靠著拆人民的房子炒地皮而來;大家享受免費藝文活動時,就要有人被迫家破人亡;政府宣稱活動產生了多少商機,看清楚,那是政府吸乾一些人的血,用那些血寫出來的。
但…這很弔詭,為了更有效的管理社會,我們創造了政府這個架構,政府不可能不做事,否則就不需要政府了;但政府又不能過度的做事,那樣的好意已經成了壞事;該如何在適當的政策與過度的好意的無限近似漸層上,劃出一條一刀兩斷的界線?我沒有答案。


2014巴西舉辦world cup,人民在網路上呼籲:「非巴西人們,別來world cup」;下一次,當各縣市政府舉辦跨年晚會、發射跨年煙火,將那一小部分被害人民的財產燒盡,化做天上那一瞬的閃光時,你會說:「別去」嗎?

--

參考資料:
  1. 北美智權報:縣市誰先破產?
    http://www.naipo.com/Portals/1/web_tw/Knowledge_Center/Editorial/publish-33.htm
  2. 遠見雜誌:5星滿意度苗栗縣長 劉政鴻:
    http://www.gvm.com.tw/Boardcontent_16177.html
  3. 維基:天下雜誌滿意度調查:
    http://zh.wikipedia.org/wiki/%E5%A4%A9%E4%B8%8B%E9%9B%9C%E8%AA%8C%E7%B8%A3%E5%B8%82%E9%95%B7%E6%96%BD%E6%94%BF%E6%BB%BF%E6%84%8F%E5%BA%A6%E8%AA%BF%E6%9F%A5
  4. Protest against world cup:
    http://metro.co.uk/2013/06/16/brazilians-protest-against-staging-of-dangerous-world-cup-3843409/

2013年7月25日 星期四

Office-Word系列:3.善用交互參照


最近,實驗室的學長們都在寫論文。在譔寫論文時,常需要引入大量的圖片、表格、方程式等,在內文中還需要使用「shown in Fig. 3.10」、「eq 2.10」,這類插入物件與文字間的相互連結。
而當插入新的物件時,如果還需要一頁一頁手動修改內文的文字內容,在大文件上將是相當麻煩的事情,甚至是接近不可能的任務,秉持「work hard, after you know you are working smart」的精神,這種方法是絕對不能接受的。
這裡要介紹的交互參照,可以讓word自行進行文字-物件的連結,加速論文的修改過程。

--

如上所述,交互參照在管理文字與物件間的連結,點開word中的「插入」-「交互參照」或「參考資料」-「交互參照」,可看見可以連結的物件包括:編號項目、標題、書籤、註腳、附註、方程式、表格、圖片八項,以下以圖片進行交互參照使用說明,這個步驟適用於圖片、表格與方程式的參照上。

1.第一步當然是先插入圖片。
2.建立起圖片標號,在「參考資料」-「插入標號」為圖片建立一個標號,標號其實是指標籤與編號,包括下列幾個部分:「標籤.編號.內文」,例如
「Fig.1 Touhou is the best」
這個標籤是最重要的,交互參照認的就是這個標籤,如果你覺得Fig這個標籤不好,也可以在插入標號的選單內自行建立新的標籤。 

3.現在在你想要插入交互參照的地方,點選「交互參照」;參照類型會列出這份文件裡的所有標籤種類,我們上面的標籤是Fig就選Fig;在下面選擇你想要連結的圖片;「插入參照類型的」則視你要插入什麼文字,如果只要插入「Fig.1」就選「標籤與數字」,如果只要Fig那就是「標籤」。
確定之後就會看到文字出現「Fig 1」。

4.會自己加文字完全沒什麼,重要的是,現在我們可以在圖表一之前加入新的圖片,同樣加上圖表標號;此時只要全選文件,右鍵選「更新功能變數」,即可更新所有的交互參照。如下圖所示,內文會自動變成「fig 2」,圖片下方的標號也會自動更新。

有一點要注意的是,一但完成了交互參照,這張圖片便不能輕易刪除,否則參照的文字會變成「找不到參照來源」,這個目前小弟我也只會手動刪除……。

5.建立圖表目錄,針對圖片、表格、方程式,word可以自動生成圖表式目錄,跟製作一般目錄一樣簡單,只要選取「參考資料」->「建立圖表目錄」,下面的標籤選擇你想要製作的標籤即可。

結論:
使用交互參照進行物件與文字間的管理,也許平時寫文件時不太需要用到,但對付文件內容的修改時,善用交互參照就顯得相當有威力。

2013年7月21日 星期日

防止.bashrc輸出內容造成sftp無法使用

目前小弟我負責維護幾台工作站,之前幾台工作站的FTP都無法使用,一定要從另一台工作站傳送,反正利用網路硬碟的功能,其他的工作站還是能拿到檔案。
前幾天工作站因為不明原因死了,非得讓無法用FTP的工作站連FTP;debug才發現原因:

在.bashrc中,放入了許多通知用的訊息,echo內容會讓sftp的收到錯誤訊息直接中止傳輸。
.bashrc的第一行有一行判斷式:
if [ $prompt ]; then echo "blahblahblah" fi
前面if用來擋掉非互動的連線,不過這好像沒什麼用…查一下正確的方法是用:
if [ "$SSH_TTY" ]
這個可以確認使用者用ssh登入,而不是sftp連線。

修改這行判斷式後就可以正常使用sftp了。
--
其實到最後還是不知道原因是什麼:

本來唯一可以使用的工作站,它的ssh版本是
OpenSSH_5.5p1, OpenSSL 1.0.0a 1 Jun 2010
其他兩台不能用的則是:
OpenSSH_5.1p1 Debian-5, OpenSSL 0.9.8o 01 Jun 2010
OpenSSH_3.9p1, OpenSSL 0.9.7a Feb 19 2003
不知道是不是1.0允許echo輸出文字的關係?這部分目前未明。

2013年7月8日 星期一

使用python執行EM模擬及寄信通知

runem這個小程式,主要是因為,通常我RF的電磁模擬要花上很多的時間,丟上工作站的話都要跑很久,如果是在windows下透過putty連結工作站,要是putty突然當掉,導致跑到一半的模擬中止掉就頭大了。

面對這個狀況有幾個解決方案,例如使用專面負責離線工作的程式,像是screen;但因為幾台工作站的作業系統太過老舊,上面甚至連screen都沒有;另一個解決方案是用atd,也就是linux內建的服務,在某個時間進行某個指令,這個解決方式很好,只是at 的語法比較麻煩,強迫每個使用者去記也沒什麼道理,身為網管要提供使用者方便,決定把at包成一個shell,使用者只要使用這個指令即可。

--

其實這個只要用shell script寫幾行即可,不過考量到一些特別的功能,還是用python來寫。 核心功能其實就一個,透過python 的subprocess把em 的指令透過atd送進去(ref 3):
cmd = "echo 'em -v {0}'".format(filename) 
cmd2 = "at now +0 minutes" 
p1 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) 
p2 = subprocess.Popen(cmd2, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=p1.stdout)

監控程序:

啟動atd之後,必須要監控該執行程序,看看它是不是結束了,這裡我使用強者我同學AZ的python 解決方案: pnotify(ref 2)
當然,這個監控的程式也要用atd的方式來執行。

第一步是先找出atd呼叫出來的em -v的process,再來的function就是抄襲AZ的,簡單來說是先檢查/proc,看看該pid是否開啟,然後每隔一段時間就用kill 0的方式檢查該程序存在與否。
找出pid的部分,用的方法就笨一點,直接叫外部的ps,抓出有em的部分、濾出該使用者的資訊、排除grep自身,再用pid排個序,抓最大(最新)的pid即可,這個方法在pid用完一圈後會出錯,不過將就用一下,之後再看看有沒有更好的解,有的話麻煩強者們提示一下m(_ _)m:
pid_list = [] 
cmd = "sleep 1; ps -elf" 
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) 
stdout = p.stdout.read().decode("utf-8").split('\n') 
for line in stdout: 
    if ("em -v" in line) and (username in line) and ("grep" not in line): 
        pid_list.append(line.split()[3])

就可以抓出pid了。 再來再用atd開啟一個pnotify的監控工作即可。

email:

為了方便使用者,使用的是python + SMTP module,這部分的程式碼只能用明碼寫出帳號密碼,不過這在權限上設定為只有我能看即可;主要code如下:
 # open smtp session 
session = smtplib.SMTP('smtp.gmail.com', 587) 
session.ehlo 
session.starttls() 
session.ehlo 
session.login(account, password) 

# prepare the send message 
msg = MIMEText("Your EM simulation: {0} is over".format(filename)) 
msg['Subject'] = "the test title" 
msg['From'] = sender 
msg['To'] = receiver 


# send the message 
session.sendmail(sender, [receiver], msg.as_string()) 
session.quit()

透過google的smtp進行文件的轉送,其實這沒什麼,大部分都是抄的lol(ref 1)

成果:

現在工作站可以透過 runem file1.son 的方式執行一個超大em模擬,em模擬結束時候,可以透過電子郵件,通知進行模擬的使用者。
本程式透過python譔寫,相當快速,總開發時間約3-4天。
原始碼已上傳到github上:
https://github.com/lc85301/runem

附章:

趁著這次佈署runem的時候,順便佈署了另一個小script: clearcdslck
其實沒什麼,只是一個shell包含一行指令:
find . -name *.cdslck -exec rm -fv {} \;

方便使用者清除因不當結束產生的.cdslck檔。

參考資料:

1. about python mail using google SMTP
http://segfault.in/2010/12/sending-gmail-from-python/
2. about pnotify.py
http://blog.azhuang.me/2011/07/script-for-notifying-process.html#more
3. about python subprocess
http://docs.python.org/2/library/subprocess.html

致謝:

本文感謝AZ Huang同學的pnotify.py以及在SMTP使用上的指導,另外感謝同實驗室的曾奕恩大師幫忙測試本程式。

2013年6月16日 星期日

硬體設計與軟體設計的不同思維

自己開始認真寫blog到現在約一年,總瀏覽人數大概6k,最多人看的,還是verilog的相關文章,顯然大家對這個莫名奇妙的語言都充滿了疑惑與不解。

最近正在寫一個verilog的作業,主要是要用verilog檢查8*8的candycrush有幾個步數是可以移動的,大概花了兩個小時,雖然寫出來的硬體很糟;但一方面發現自己verilog沒忘,另一方面也用這個例子,談談硬體設計與軟體設計差異之處。
這個問題,用軟體來寫實在滿簡單的,把陣列讀進來之後,只要用幾個for loop,把可能的狀況跑一次就是了,對一位有經驗的程式設計式來說,也許不用幾分鐘就能寫完。

但硬體設計來說,狀況就不一樣了。

--

我認為硬體設計的思維,必須從clock,前幾篇文所提到三大塊設計方式的角度下去想,這個模式和軟體有點差距,也造成很多從軟體轉到硬體設計人,有時就轉不過來,想不透為何硬體要這樣寫。
以這個candycrush為例,就我知道,有些人的判斷式是這樣寫的:
integer i;
...
case(state)
DOWN:begin
   for(i=0;i<40;i=i+1) begin
      count_num = ( (map[i]==map[i+1]&&map[i+3]==map[i] || map[i]==map[i+2]&&map[i+3]==map[i]) && i%8<6 )? count_num+1:count_num;
   end
end
簡單來說,在state為DOWN的時候,判斷 i這格糖果,和右邊一格、三格或是兩格、三格是否一樣(按:這個部分應該是原作者打錯,state應該是RIGHT),是的話就讓count_num加一。
看起來很合理,以軟體角度來說,不就是i=0,1...39,每次就檢查上面的判斷式?

這就是思維不同的地方,硬體設計你寫什麼,它都是同時進行的,combination circuit無時無刻把接到的資料進行邏輯運算並輸出;你如果希望某個行為和時間有關,希望它依序進行的東西,絕對都跟clock和sequencial circuit有關。
原作者可能是沒查過for loop在verilog內的意義為何,但for loop這個語法是combination circuit的一部分,實際上for loop在verilog內會被平行的展開,編譯器會自動把for loop內的code全部依for loop 變數展開,上面的寫法實際上大約等價於:

( (map[0]==map[1]&&map[3]==map[0] || map[0]==map[2]&&map[3]==map[0]) && 0%8<6 )? count_num+1:count_num; 
( (map[1]==map[2]&&map[4]==map[1] || map[1]==map[3]&&map[4]==map[1]) && 1%8<6 )? count_num+1:count_num;
下略38行。
於是當state進到DOWN時,count_num被平行輸入40個combination circuit中,每一個都有不同的判斷條件,有些加一,有些維持原值,然後要寫回到count_num裡,這下就天下大亂了(按,據說這個code最後無法合成到gate level)。
如果用我在三大塊中的例子:
Combinational circuit就像馬路,負責讓車(信號)流動,改變車道(運算)
Sequential circuit則像紅綠燈,負責管理信號什麼時候可以通行,到下一個combinational circuit。

這裡for loop的寫法,就像你要一位駕駛,每過一個紅綠燈就喝一種飲料,總共要喝40種;結果你把40支紅綠燈插在同一個路口,駕駛就得喝大雜燴了。

--

原作者的意思,應該是for loop展開的每一行,依序判斷,寫出結果到count_num中。
依序->和時間有關->請用sequential 電路和clock。
真正合理的寫法,是用另一個變數phase,在state DOWN從0加到39,這些動作才會依時間維度展開,而不是直接平行展開。
關鍵的幾行code大概是:
//count_num
if(state == DOWN) begin
( (map[phase]==map[phase+2]&&map[phase+3]==map[phase] || map[phase]==map[phase+1]&&map[phase+3]==map[phase]) && phase%8<6 )? count_num+1:count_num;
end
//phase
phase_next = (phase==39)? 0 : phase+1;
//state
state_next = (state==DOWN && phase==39): UP: DOWN;
隨隨便便打了這些,好像還是沒說到我想講的概念;簡單來說,硬體裡和時間有關的概念,一定都要歸到sequential的部分去;硬體設計是完全的一個口令一個動作,想像for loop裡的變數 i,在每一次clock來的時候加一,i不同時電路才有不同的行為,希望這樣的想法能對各位辛苦的電路人有幫助。

2013年5月25日 星期六

使用差動雙投擲計時器應用於時鐘製作之研製

minecraft是一款我認為設計得相當好的遊戲,透過簡單方塊的堆積,讓你組出任何你想要的內容;而紅石又是其中最有變化的物件,可以模擬出許多數位電路的行為,老實說基本的邏輯設計課程應該可以用minecraft當作輔助教材(XD)。

minecraft升級到1.5之後,多了很多新的紅石元件,其中包括可以測定日光強度的日光sensor,讓我們有機會在minecraft當中,實現時鐘的功能。
之前已經有相當多相關的設計,包括直接用sensor輸出信號接在redstone lamp(1),及用長線分離出各時段的信號(2)等。
因為sensor輸出信號在白天呈現山形,第一種時鐘,共有上午和下午時會呈現相同的時間、計時非線性、晚上也只能顯示為晚上而非確切時間等問題;第二種則需要相當大的空間和電路,在一般server不用creative mode難以實現。
這裡我們就要設計的是,能夠線性計時,利用daylight sensor來校正,同時體積儘量小的設計。

最終設計的minecraft時鐘共有兩個主要部分,分別為:差動雙投擲計時器、雙比較器實現計數器(counter).本文將分為以下幾個部分:
1. minecraft 時間及sensor介紹:
2. 差動雙投擲計時器之設計:
3. 雙比較器實現計數器之設計:
4. 設計展示:
5. 相關設計:

1. minecraft 時間及sensor介紹:

minecraft一天有現實的20分鐘,共分為24000個基本時間單位ticks,ticks設為0時相當於每日早上6點。sensor的部分,固定每天22500ticks到13500ticks會發出信號,其他時間則不發射,信號強度依日光強度有所不同。
詳細資料請參考:(3)minecraft wiki daylight sensor。

2. 差動雙投擲計時器之設計:

過去minecraft上常難以實現長時間的delayer,可行的辦法包括用rail+detect rail、dispensor+蜘蛛網、鐵路+流水回收(4)等、活塞循環(5)等;但一般rail+detect rail需要相當大的面積來達成長delay,一般大小下delay只有約10-20秒,且重登入時不容易reset;dispensor+蜘蛛網、鐵路+流水回收則不夠精確,delay時間的可調長度與可調精度不佳;活塞循環相較之下較為可行,但拉到四角的紅石信號容易造成信號線相當複雜,一般體積也較大。 

本文提出之差動雙投擲計時器,除了能精確計時外,還具有容易reset、停止、可調長度相當廣及所佔體積相當小等好處,主要的參考來源為「SCAMP全自動造山機」(6)。 

雙投擲器將兩個投擲器相對,驅動一個投鄭器即會將內容物送至另一個投擲器內,透過1.5版新增的比較器,偵測投擲器是否內含物品,驅動比較器製成的振盪器(圖左),即可自動將一投擲器(下稱發射端)的物品送到另一側(下稱預備端),調整投擲器內的物品數量和振盪器的頻率,可以調整輸出變化的時間,由於comparator的delay不明,粗估送完的時間方式為,投擲器內的物品數量*(Osc. Delay),實測上兩個repeater調最長,17個物品送完的時間是30秒。
理論上可以在另一邊複製相同的振盪電路,將一側電路的輸出鎖住另一方向的repeater,達到來回振盪的功能,但如下圖,repeater要鎖住的方向不同,這樣的設計會讓電路變得相當大;同時兩邊都是相同的振盪頻率,實用上不容易做到校正的功能。


新架構加入另一套雙投擲計時器,兩計時器互鎖,當A方鎖住B方時(A方的Q值為1),A方輸出和B方預備端是否含物品的信號通過AND閘,驅動高速振盪器,將物品送回發射端。



運作包含五個相位:
1. A方發射端將物品送入預備端,B方預備端高速送物品回發射端。
2. B方預備端送完,高頻振盪器停止。
3. A方發射端送完,B方發射端解鎖,使A方輸出鎖住,並啟動A方預備端高頻振盪器。
4. A方預備端送完,高頻振盪器停止。
5. B方發射端送完,A方發射端解鎖,使B方輸出鎖住,並啟動B方預備端高頻振盪器,回到相位一。

最後則是控制信號的部分,可以透過強制將A/B方鎖住信號設在1來達成開關計時器的功能;但要注意的是,repeater的鎖住是鎖在 0或1,如果鎖在1的話,會使雙投擲器進入來回投擲的不穩定狀態;因此我們要在控制信號的輸入處,加入一個由輸出控制的鎖,以避免上述狀況的發生,詳細如下圖所示。
完成之雙投擲計時器所佔面積為10*8*3,相當compact,理論上的最長delay時間估計為2032秒左右




3. 雙比較器實現計數器之設計:

由於上述差動雙投擲計時器的輸出端,只能隨時間輸出長週期的1/0信號,因此輸出端先接入一個上升/下降緣檢測電路(edge detector),產生短脈衝;再接入計數器計算短脈衝的數量,以達成隨不同時間輸出不同信號的能力。

這裡狀態機的設定參考(7)的設計,功能考量,我們只取其中的down counter跟重設的能力,同樣由雙比較器維持信號強度,每一個脈衝進來,經比較器產生強度一的信號,使狀態強度減小一,達到狀態記錄。
實作上計數器記錄的是計時器發出多少次信號;在這裡我們用來記錄經過多少時間,在日間感測器開始運作之後,到日落的時間為15000ticks=12.5分,晚上感測器則是9000ticks=7.5分,分別需要記錄12, 7個狀態。

為了reset計數器,我們需要特定強度的信號,當然也可以用強度15的信號reset,但這樣會加大計數器的體積;這部分使用箱子+comparator產生,並利用另一個信號為15的信號相減,來產生所需的強度。
以日間計數器需設到強度12的信號,箱子要放345-460個物品。
以日間計數器需設到強度7的信號,箱子要放921-1036個物品。(雞蛋的話請除4)
這個用骨粉來放最容易了。



4. 設計展示:

最終時鐘設計如下圖所示:

中央的日光偵測器為核心,左右各為一套雙投擲計時器,分別在日、夜時工作(左日右夜,不想看到紅石電路請自己拉到地底=w=);計時器Q+輸出經edge detector進到計數器-1端,Q-經edge detector到對方計數器reset端;上方為夜間計數器,七個狀態;下方為日間計數器,12個狀態;有一些些調整是在鎖住sensor信號跟接到計數器的部分,都是為了讓體積更小。

稍微提一下,因為在雙投擲計時器,鎖住控制信號的那一方(Q-),在計時器被鎖住時,其輸出為0,如圖中左邊上半的狀態,因此在停止工作的瞬間,會有一個negative edge pulse,利用negative edge detector偵側這個信號幫另一方重設。
開始計時的時候,Q-端會先變1,然後30秒後換Q+端變1,再30秒Q+變0;因此從Q+端接到計數器減一端的detector同樣是negative edge detector。

這大概是整體時鐘的設計了,每個一紅石燈的信號可以自行拉線到想顯示的方式上;就我所知,這是目前能線性計時,同時體積最小的設計。

5. 參考資料:

(1)Basic Minecraft Clock Using 13w01a "Daylight Sensors"
http://www.youtube.com/watch?v=2x-l0owQGF0
(2)WORKING 12-HOUR CLOCK IN MINECRAFT
http://www.youtube.com/watch?v=1-ylYISMAck
(3)daylight sensor
www.minecraftwiki.net/wiki/Daylight_Sensor
(4)Minecraft clocks (6min)
http://www.youtube.com/watch?v=Rz1Qxbh3_XI
(5)Minecraft : Piston clock for long delay
http://www.youtube.com/watch?v=M19UQ5Y_wzQ
(6)The SCAMP: How it Works, and How to Use It
http://www.youtube.com/watch?v=vBpPKVwIwP4
(7)Decimal Counter with Comparators [Tutorial] Minecraft 1.5
http://www.youtube.com/watch?v=J7mRNZXshCQ

2013年5月17日 星期五

(有電)星際爭霸戰-闇黑無界Star Trek XII

以下有電,不想被電請慎入。





上星期五上映的ST12,身為老trekkier當然不能錯過,而且同樣JJ abrams導的ST11是部還不錯的作品,立馬星期六就去看了。
我對這部電影的評價其實普普,遠遜於ST11的表現。

ST11至少有個另一條時間線影響現在這條,Nero復仇、Spock融入人類社會、Kirk成長為艦長的主線劇情在,但ST12就沒什麼主線,Khan幹嘛沒事大發神經不怎麼提,頂多從禁閉室一小段對話裡看到一些原因。
我本來期待Khan可以從大反派漂白為正派的機會,畢竟大多數人沒有接觸過原初系列,大部分進場的人連Khan是誰都不知道吧,可能有些人看過ST2,至少知道他是個反派,但我的經驗這種人已經非常少,更別提看過TOS裡Khan被流放的過程。

沒想到他一拿到無畏級星艦,很高興的想要試試新武器,又變成大反派了…老實說上一集都玩過修改時間線的梗,這裡就沒什麼發揮,頂多讓老Spock出來充充場面,但他講的話有影響劇情,或是幫助打敗Khan嗎?也沒有,他只說Khan很危險。
我反而會期待老Spock指出Khan極端危險,然後小Spock為這個時間線的Khan辯護,劇情更刺激,也可以思考壞人到底為什麼要當壞人…,然而ST12沒有這樣做,這部Khan堪稱ST電影最帥反派,卻有種沒靈魂為反而反的感覺,滿可惜的。

動作場面太多,讓人目不暇給,卻也少了讓人思考的橋段。
例如ST11在Spock被換下來後,總要在傳送室有個沉思的片段,讓人體會他心裡的矛盾,或者在小林丸事件後,讓Krik和Spock在聽證會上,沒有誇張的音效,只有兩人觀念的衝突;但ST12幾乎是從頭就一直是大場面,一點思考的時間都沒有,拆個魚雷都要搞得那麼緊張,沒必要啊。
當然反過來說,這部也沒什麼觀念要讓觀眾去體會…
這部的預告片,一直反覆強調派克對Kirk說的那番話:「你所做的每個決定都會影響到你及所有人的性命」可是電影裡看不出來,只有Spock跟Kirk反覆爭論個人性命與整體規則的差別;直到Kirk最後轉頭說:「I'm sorry」,可是我看不出他錯在哪?他並沒有恣意行事、也不像開頭那樣胡搞瞎搞,廣告想表達的在電影裡完全看不到,也許當ST11的廣告說詞還好一些。

最後則是電影裡面不合理之處有點多,這部分有些跟我是老trekkier有關。
例如就我知道,star trek原初設定是類似當年歐洲大航海的規模,曲速從一顆星到另一顆星費時要幾天不等,橫越聯邦甚至要以月來算;無論是ST11或ST12,為了求劇情的速度感,這個時間要不是短了很多(ST11, 地球->瓦肯),就是短得有點誇張,ST12, Qo'noS->地球甚至只花了幾分鐘的感覺。
那ST6企業號花了大半天橫越Klingon帝國是橫越心酸的嗎?中立區根本就不用設計了,莫名奇妙就飛到別人星球了,開著飛船拆別人家,先生我記得聯邦對Klingon一直都是劣勢,直到Qo'noS衛星爆炸雙方才和解啊,怎麼這集klingon變得超弱的感覺。

整部電影裡Klingon的角色不明,Qo'noS的劇情也不是很必要,頂多是出來讓Khan出來電一下Klingon,也許是要強調Khan過人的能力?但對新看的人來說,他們也不知道Klingon在戰鬥上的天生優勢,只會覺得是Khan在開無雙。

另外還有個表現手法的問題,雖然說真實情況大概相差不遠…
從ST11之後,我覺得開始強調爆炸炸穿艦體的動態畫面,有可能是成本之類的考量,在前10部裡比較少這樣的畫面,特別是Abrams好像又特別喜歡拍人從艦體被吸到太空中的畫面,這次更扯,甚至被吸到曲速空間的畫面都出現了…,而且還是有些重點式的體調,看多了就會覺得有點不舒服。

整體看下來,我覺得ST12特效做足了,卻沒什麼內涵;看一部爽片可以,但以我的立場我會說:這不是ST……。

2013年5月1日 星期三

Office-Word系列:2.段落設定

我還記得林教授在這個section上有一句我印象深刻的告戒:「文件內,不應該出現兩個連續的空白,不應該出現兩個連續的換行符號Enter」
這是為什麼,因為Enter代表的是「換一個段落」,我們本來預期分段落的時候應該有一些格式的設定,連續兩個Enter,等於是中間插了一個沒有內容的段落,在排版上會有一些很棘手的問題。
例如:通常我們在段落的尾巴接下一個段落的標題時,都會加上一個空行,如下所示:
我是上一個段落的結尾。

我是下一段落的標題:


通常大家會這麼做:
我是上一個段落的結尾。
「這裡會插入一個Enter,產生空行」

我是下一段落的標題:

如果上一個段落多打了幾行,讓結尾停在一頁的最後時,會怎麼樣?下一頁會多出一行空白
要一頁一頁去檢查嗎?這樣一百頁的文件就要改很久,而且你每改一次內容,就要再檢查一篇。但很囧的,甚至連我們系上所謂「論文範本」也是這樣寫的。這就是段落:總管了文字行與行、段與段之間的關係出場的時候了。
在這個部分,設定都是跟著段落走的,但個人強烈建議,為了文件格式統一,最好以樣式為單位去設定;在設定樣式「1. 在樣式庫的樣式上按右鍵,選擇修改,改成你要的樣式即可。」時,選左下角的「格式」-「段落」去設定。

第一部分:縮排與行距:

縮排是文字和頁面左、右邊界的距離,行距…就是行距嘛
縮排中,比較特殊的是指定方式「第一排」或「凸排」,讓每個段落的第一排會自動空一定長度,這個也是滿常用的功能,拜託不要自己手動輸入空白。

剛剛提過每段接到下一個標題的問題,解決方式是在行距的設定,有兩種方法:
1. 是設定標題的段落:例如把「標題一」的段落,設定「與前段距離」為一個行距,這樣不需要輸入一個enter,也可以多空出一個空間。
2. 是設定內文的段落:設定「與後段距離」為一個行距,然後勾選「相同格式時不加上間距」
兩種方法都會避免上述當前段落剛好在這頁尾部結尾的問題,大家可以自己試試看;當中的差別是,第二種方法對所有標題都會生效,就文件的彈性來說,第一種方法比較好一點。

第二部分:分行與分頁設定:

這裡面我覺得比較常用的幾個功能
1. 「widow orphan control」,中譯是「遺留字串控制」。
遺留字串指的就是:某段落最後一行文字落到下一頁獨自一行,或是某段落第一行落在上一頁最後一行;這兩種在文件裡都是不允許的,只要打開遺留字串控制,word就會自動幫你調整(不截圖,自己試),下一頁出現遺留字串的時候,自動幫你加一行過去。
同樣的,請不要自己調整,那不working smart.
2. 「與下段同頁」、「段落中不分頁」,這個大概不太需要解釋,是設定標題的時候用的,這樣就不會出現,獨留標題在某頁最後,或是標題第二行跑到下一頁的狀況了。

第三部分:中文印刷樣式:

這裡的功能好像就不太常去設定了,有碰到再說。

--

以上大概就是段落的概念介紹了,如果你只是要換個行,請用Shift+Enter,這代表換行而不換段落,在排版上有著截然不同的意思,大家一齊向「文件內,不應該出現兩個連續的空白,不應該出現兩個連續的換行符號Enter」為目標努力吧。

Office-Word系列:1.樣式庫與階層

前言:
Office word是我認為M$數一數二成功的產品之一,透過所視即所得的介面,讓人更能快速的編輯文件,市佔率至少超過90%;但是,如果是編個幾頁的文件,也許可以直接打一打即可,但要是要打個幾十到幾百頁的文件的話,就必須善用一些word本來的功能,確保無論如何修改,整份文件都能符合正確的格式。
個人其實也有在用LaTeX編一些文件,無論在排版的變化、格式化文件的引入、字型呈現、數學式的表現等,LaTeX許多功能是word完全無排匹敵的,這系列文章並不是試圖用word挑戰LaTeX的地位,只是介紹一些word常被忽略的功能,讓word在長文件上發揮它該有的效力。
會寫這篇文章,是因為約一年前,聽了台灣科技大學管理學院的林教授所開的Office相關課程,學了不少office的技巧;後來在研究所,看著學長們寫論文,發現會有效率使用word功能人不多,就把它寫下來,希望讓大家認識一下word許多強大之處;本文感謝林教授、及學長論文範本的指導。

事實上林教授所教的還有許許多多的小技巧、快捷鍵,但那實在太過瑣碎,我認為還是學概念比較重要,本文預期會分成下列幾個概念:
第一節:使用樣式庫
第二節:階層的概念
第三節:弄懂段落在幹嘛
第四節:管理好參考資料
由於word還有許多好用的功能,受限於作者太懶篇幅,先整理出這幾個比較重要的概念。

--

第一節:使用樣式庫

我不知道大家打文章的習慣是什麼,但有可能是有什麼打什麼,有標題就建標題、有小標題就打小標,反正不過就是調調字體、調個大小,了不起加個編號或項目符號。
如果你編的是有100頁的文件,然後老闆說話了:「今天起床,我覺得你小標題的16號字不好看,請改成16.5號字」,如果是手動改當然也OK,但這樣不smart。
因此,編文件的時候請用未來更有效率的模式:樣式庫。

樣式庫位在word視窗的右上角,預設就有很多樣式可以用(雖然我猜大家通常都忽略它…)
我個人是覺得,文件內每一個部分,都應該是用樣式庫的格式設定,而不是手動修改的格式設定;這樣一來,每當你覺得文件哪個地方需要修改,只要修改樣式庫的格式設定,整篇文件的相同格式都會跟著變化,完全不同手動一行行修改。
我們現在就用一個「標題」,來看該怎麼好好使用樣式庫,首先是選到你要的變為標題的字,再選擇樣式庫內的標題字型,預設的標題字型很大,不符合你的樣式需求,這時候有兩種作法:
1. 在樣式庫的樣式上按右鍵,選擇修改,改成你要的樣式即可。 
2. 先修改好你要的樣式,反白後選擇「右鍵-樣式-更新標題樣式xxxxx」
如此一來就完成了格式的設定。

樣式庫提供了許多的樣式,右下角的展開按下去可以看到全部的樣式,基本上打一份文件絕對OK。
如果想要修改某個樣式,同樣也在樣式庫中修改,或者修改後,再右鍵選更新即可。
如果想要加上新的樣式,也只需要右鍵後選擇「另存為新的樣式」。
套用樣式庫大概是word長文件最基本的概念,之後所講的所有概念,都需要樣式庫才有最大效力,所以從今天開始,絕對不要再一行一行自己改了格式了。

第二節:階層的概念:

用過大綱模式(檢視-大綱模式)看文章嗎?
大綱模式其實是把文章內所有格式、圖片之類都去掉,只留下文字,你會發現所有的標題之類都不見了,只有文字;這就是大綱模式;據說是因為早期電腦還不夠強的時候,所視即所得的成本太高,因此編輯內文和格式是分開的,到最後再把大綱和格式結合在一起,成為完整的文件。
不過現在大綱模式好像都什麼都看得到了。

不過我覺得大綱模式最重要的還是裡面階層的設定:word預設有九個階層加上內文(雖然我壓根不覺得有人用得到這麼多層啦)讓各位使用;例如樣式庫就有「標題一」到「標題九」可以設定,其實很直覺,愈大的項目階層就愈高,通常字體也愈大XD。
大綱模式讓大家可以很快的確定文章的架構有沒有錯,只看階層一來確認大標題都有打上去,調整文件各部分的階層等,是個快速瀏覽文件的方式。

2013年4月17日 星期三

用makefile來編譯安裝android apps

因為一些關係,最近正在寫Android上的Apps
寫Android,大部分人可能都會用Eclipse來寫,Eclipse主要是整合了很多功能,用起來滿方便的,不過個人還是偏好用terminal+vim來寫code。
雖然這樣會比較不那麼自動一點,但也不是沒有解,在終端機下,如果有什麼要自動化的話,就要用makefile啦。

以下就是自己寫個簡單的makefile,在projectname和packagename裡面分別填入build.xml裡的<project name=””/>,跟AndroidManifest.xml裡面的<manifest package=””/>,這樣就可以用:
make debug
make install
make uninstall
來完成編譯、安裝和解除安裝的工作。
.PHONY : clean install uninstall
#=========================================
# MACRO DEFINE
#=========================================

ADB = adb
DEL_FILE = rm -f
DEL_DIR = rm -rf
MKDIR = mkdir -p
MOVE = mv -u
BIN_DIR = bin
projectname = MyFirstApp
packagename = example.opengles.hellotriangle

#================================
# Build function
#================================
debug:
    ant debug
install:
    adb install ${BIN_DIR}/${projectname}-debug.apk
uninstall:
    adb uninstall ${packagename}
clean:
    adb uninstall ${packagename}
    ${DEL_DIR} ${BIN_DIR} 

2013年3月29日 星期五

使用vimdiff來解決git merge conflict

使用vimdiff來解決git merge conflict 最近同時家裡用筆電跟辦公室用桌電,在兩個地方使用git/github來管理程式作業,這兩個東西加起來根本神物,本來要用隨身碟同步的東西,現在可以用git直接完成。
關於git的基本介紹我就不解釋了,網路上隨便一找就有一堆資源,例如右邊友站連結,作者比我強30dB的JJL blog,裡面有git的基本使用方式;作者當初則是看參考資料一的progit來學git。

作者遇到的問題是:有時候檔案在github上的檔案已經更新,本地的檔案也有修改過,這時候若想要git pull的話會產生conflict,這時候就需要把本地的檔案刪掉重新clone使用merge來解決衝突,偏偏作者手殘常常把檔案merge成連<<<, >>>都保留下來的檔案,相當麻煩;這次好好的研究一下怎麼用vimdiff作為merge的工具,在這裡記錄一下。

首先呢,我們可以先設定vimdiff為git default的mergetool
git config --global merge.tool vimdiff
為什麼?沒辦法,用vim就是潮(誤)

那麼來merge吧,輸入
git mergetool
這時候應該會打開vimdiff,然後產生左上角、中上、右上、下四個視窗,說明如下:
左上:local:顯示本機的檔案內容,現在這個git資料夾的版本
右上:remote:顯示遠端,你要merge的分枝
中上:base:顯示上面兩個分枝的基部的內容
下:merged:顯示merge的內容,也是是包含了那堆<<<<<<, >>>>>> 的版本,我們的目標就是把下面這個修到我們希望的版本。
截圖:













到了這裡就開始解衝突啦,事實上不單是git,平時如果有兩個很像的檔案要合併,也可以用vimdiff開啟來解,使用的指令是這些:
[c:跳到上一個衝突點
]c:跳到下一個衝突點
:diffget,從某個視窗取得內容
:diffput,把內容丟去某個視窗
可以用:help do, :help dp查怎麼用,不過兩個指令的基本格式是:
:[range]dp|do bufspec

如果是雙方比較,那就沒什麼好說的,do/dp的對象就是另一個視窗的內容,這時候只要在衝突點在一般模式下用dp,do即可。但如果是現在這種3方比較時,就沒辦法這麼方便,而是要直接輸入:diffget/put bufspec來操作(可以打diffg, diffpu來少打幾個字,不過有差嗎=w=)
以上圖為例,我們游標停在下面的衝突點上,要使用remote的視窗內容。
這裡bufspec(用哪個視窗的內容)有兩種指定方式:
1. 先用:buffes,確認remote那個視窗編號,我是4號,因此用 :diffget 4
2. 用關鍵字,這個超強,用 :diffget REMOTE (因為git自動命名暫時檔名為 XXXX.REMOTE.yyy, XXXX.BASE.yyy, XXXX.LOCAL.yyy)即可。
如此就會套用remote的內容了,經過幾次套用之後,畫面可能會變得有點亂,這時候可以用 :diffupdate來重新產生diff的格式。













用上面的步驟,就可以快速的完成解衝突的工作,做完之後,在下面的合併檔存個檔離開吧。

參考資料:
1. progit download:
2. vim wiki about git vimdiff:
3. vim help:
Type in vim :help diff

2013年3月17日 星期日

面對核四,我的意見

反對核四大遊行登場,將反對核四的行動帶上另一波高峰,隨著愈來愈多的名人、學者加入連署,反對聲浪也愈來愈高。網路上已經有很多關於核電的文章,在此就不需要再重覆了,只想在這裡表達一下我的意見。

最近看到一些文章,認為這個政府必須提供配套方案,而不是將責任丟到反核民眾身上;我完全同意,但另一方面,我並不認為「人民沒有義務去理解事情背後的充分知識,解決方案在政府,但政府應該幫忙人民,人民也應該自己去了解,解決方案所帶來的後果。」
比如說現在政府要穩定台灣供電,提出的解決方案是核能四廠,後果包括可能的風險及低放射性核廢料的問題,因此政府可能會不斷測試核電廠的安全性和在蘭嶼建造處置場,這是穩定電能解決方案會帶來的後果,所謂解決方案,無非就是在現有的技術限制、成本、效益內達到妥協。
今天大家反核能,要求關閉所有核能電廠,無論是新設火力機組以致電價大漲,這是政府回應廢除核能四廠,為了降低用電需求而提出的解決方案;聽起來是在恐嚇,可是這也是現實,如果有又安全又便宜的廢電方式我會不要嗎?可是台灣天生能源不足,如果人民不體認這點,抗議完回去繼續過著浪費電的生活,政府漲電價又抗議,批台電肥貓,罵死所有至今努力維持台灣不斷電的員工,這樣你要政府怎麼做?
所有方案背後都有妥協和限制,如果要大家正視方案背後的限制和技術的極限,這也算是恐嚇,大概所有的解決方案都不必提了,只要矇著眼聽著自己人的高談闊論,然後鬥死所有正視現實的人。
舉個例,下面資料一新聞報導,因為手機訊號極弱,接電話必須走到街上,然後直批中華電信服務品質;可是,當初就是因為該鄉鎮反對在家門前設定基地台,電信公司設不下去,害怕基地台帶來致癌的風險。這是電信公司的錯?還是民眾自己不清楚後果?因為射頻的極限就是在那,你不能兩手一攤,叫電信業者做出不用基地台的手機,因為技術上做不到,電信業者說:「再拆基地台訊號就會低到不能使用」,這是恐嚇,還是叫你睜眼正視現實?
其實隨煤、油、天然氣價格的變化,台電早就處在虧錢狀態,由政府出錢維持如此低的電價,使用更多的再生能源,情況只會更糟;我可以認同民眾反核的理念,但我不認為民眾可以什麼都不用理解,抗議完就拍拍屁股沒我的事,因為即便是集體,在盲目下決策也不一定就是正確的。

最後最後,我只想說: 為什麼我們需要核能、火力?因為它的能源密度夠大,網路上轉載很多再生能源的「替代方案」,一眼就看得出是在胡扯,在屏東種點太陽能就可以超過一座核能電廠?幫忙消耗太陽能板廠的產能過剩還差不多;又或者,直接說用電量跟備用容量率相減,然後說台灣沒有缺電問題;這些只會讓我覺得你沒先了解過問題,或者你根本懶得正視技術的現實,我不管你反核擁核,拜託不要再轉這種一看就非事實的文章了。

相關資料
1.千戶手機沒訊號 放塑膠袋掛騎樓等電話
http://www.youtube.com/watch?v=58k2T9IgXfA
題外話,啊現在電信公司提出新的解決方案,幫你們裝了強波器,這下你倒不怕電磁波了?只有一樓收得到就說明它的電磁波是有多集中。

2013年2月27日 星期三

ADS小電路模擬設定

個人用ADS喜歡把電路的小塊小塊變成一個個模組(component),比如說device建成一個模組,matching network建成一個模組,dc bias 的bypass電路建成一個模組。
這樣做的好處有:
1. 主電路不會太複雜,各個元件的關係十分清楚。
2. 要換掉元件十分容易,例如要把matching network從理想元件換成EM的S2P檔,只要改模組裡的接線即可。
3. 要對模組內的元件做微調時,可以清楚知道在微調哪個部分的元件,這在元件數多時很好用。
另一方面,這樣做也有幾個問題:
1. 大電路的模擬無法求得電流等資訊,即無法計算功耗,因此需要將dc線拉出來,造成電路稍加複雜。
2. 大電路的模擬設定會和小電路的相衝突,進行模擬時要將小電路的模擬關掉。

第2點煩人之處在於,大電路模擬和小電路模組行為的確認,幾乎都是要做的,例如DC bias 一定要加上bypass電路來隔離電源的雜訊,會先對bypass電路進行設計,進行S parameter模擬,確認頻帶內設計OK,再將bypass代入大電路中,這時候麻煩來了,ADS並不允許多重的模擬設定和模擬終端(term),此時要先將小電路的模擬設定和終端給取消掉,否則會產生重複的模擬設定;如果後來需要再次確認bypass的設計,就要再打開小電路的模擬設定和終端。
看device S2P也是,先在模組內模擬,確認device行為正常之後,要在大電路模擬,就需要進到read S2P的電路設計,把其中的模擬關掉;如果要換device,也要重開。
這樣每次來回的開關小電路的模擬設定,一是麻煩,二是徒然浪費時間,最後還容易做錯,實在不太聰明。

寒假個人自學了DesignPattern,前幾天突然從Design Pattern類似的概念,想到第二個問題的一個解法。 只要把bypass的implementation(電路架構)做成一個電路設計,bypass的模擬設定(interface)則做成另一個設計,這個模擬設定和大電路都各自包含bypass的implementation,要修改bypass,就到bypass模擬設定裡去tune,而大電路仍能正常模擬。
這樣一來,無論我要做大電路模擬或是調整小電路,都不需要再去開關小電路的模擬設定跟終端,可以簡省工作的時間,提升設計效率,看來沒事看看DP等其他領域的東西,也會有些收獲。

工作站passwd整理

最近開始涉入系上的Linux 工作站管理,這個工作最重要的就是耍廢維持工作站的穩定,及提供系上同學放心的用Linux進行模擬等工作。
每個學期定時的,會有新的同學加入,這時候就要幫大家設立新的帳號,很幸好會用Linux工作站的人不多,第一個原因是做電路的人佔比本來就比較少一點,第二個原因是大家自己的電腦好像都比工作站還要強,畢竟實驗室裡有一位光華商場的供貨中盤商,什麼i7-3770, E3記憶體插到32G的,哪天出現E5的電腦我都不驚訝了。

好像有點離題,總之是要幫大家建立帳號嘛w。
當然因為使用者不多,手動加也是OK,但老話一句:Working hard, after you know you are working smart,管帳號要怎麼smart管?
因為我們的server大約有400多位使用者,依照各不同的教授或管理員帳號分為26個群組。
其實可以很簡單的用script的方式,adduser, chown, chgrp, mkdir等,大量新增使用者,不算太難。
但因為我希望在passwd裡面,不同群組的使用者資料能連在一起,這樣有新人加入才能快速找到這位教授有多少學生,給予新生連號的UID編號。
後來發現這個有個簡單的解法,利用bash的sort即可輕鬆解決。
Sort -t: -k3 -n passwd
依序表示:用 : 為分割字,取第3個分段(GID)為key;key是一個數字,不是字串;這有點類似python sort指定key的味道,沒那麼威猛,但短小精幹,處理事情綽綽有餘,瞬間就完成passwd的排序。

2013年1月29日 星期二

Design Pattern

最近小弱弱版主在看設計模式(design pattern)相關的書,寫一下我對它的感想。

我認為design pattern中相當重要的是繼承和polymorphism的概念:
繼承讓我們能定義一個基礎的型別,然後依據不同類型的物件,都繼承自這個基礎型別
Polymorphism則允許我們利用基礎型別的pointer,依據執行時指向的物件來取用它的資料。

從design pattern來看,Polymorphism有兩個最重要的功能:
1. 也就是上面提過的,是在執行期決定要執行哪個function,只要用父代的pointer去access繼承產生的子代,就可以視生成哪個物件來取用它的function,這也是一般教polymorphism時會提到最基本的用處,相信設計師都很清楚了。
2. 第二個功能延伸自第一個,利用polymorphism給予我們執行期時的彈性,延伸出來的是,在設計、修改時保有彈性(也就是Design Pattern),把每個不相干的部分給分開,讓我們不必要每次要新增功能、新增新的物件時,都要進到Implementation的層次做修改,浪費許多時間在尋找該加上新功能的地方;另外也能減少增加新東西時,因為相依關係而要重新編譯的部分。
事實上我認為第二個功能的重要性遠高於第一項,設計的彈性增進工作效率,才能將Object oriented的火力全面發揮出來。

說個自己想,沒什麼用的例子:
比如說我們要寫個選角色的程式好了,每個角色都有一個主要的招式master spark之類
所以說,最簡單的寫法就先設定一個基礎的角色:class character,內含一個main_spell()
然後各個角色繼承這個character.h,定義自己的main_spell()裡面要幹什麼,這時候所有角色的介面就一致了,可以用一個character的pointer來操作每一個角色的功能。
但這樣做其實不夠好,如果今天我們希望有些角色的main_spell不要動作怎麼辦?然後每個人招式又都不一樣?
我們可以打開每個角色的原始碼,然後重載(overload, 這個翻譯=w=)main_spell()
可是如果我們要加上10個角色呢?
所以Design Pattern就會要求,不止character,連main_spell也要是一個base class,不同的招式則是繼承它後修改,character則包含一個main_spell的pointer,用polymorphism的方式取得不同招式;如此一來,可以很方便的加上新的main_spell,只要新增main_spell的class即可,在character的介面卻完全不需要更動, 在維護跟更新上會更有效率。

這個composition over inheritance應該算是最基本的design pattern的概念了,Design Pattern所教的,就是過去神級的設計師,針對許多設計上的問題提出適當的解決方案(雖然感覺就是愈會變動的地方就會加上更多虛擬層,或是愈切愈細),據說在STL裡面用上許多Design Pattern,如果小弱弱板主學有心得再上來獻醜。

參考資料:
1. Head First Design Pattern:
http://shop.oreilly.com/product/9780596007126.do
會用google的可以在後面加上pdf
2. http://sourcemaking.com/design_patterns
包山包海的Java/C++ source code
Related Posts Plugin for WordPress, Blogger...