視野寬闊的機場、豪邁的烤肉、抗議的民團、坐在旁邊抓人的便衣(維安人員)、地景月免、精彩好聽的打擊樂表演、嗨翻的西班牙樂團+雲端魔幻搖滾秀。
帶孩子一次體驗(而且是第一次),What an amazing night!
2014年9月7日
2014年8月25日
2014年8月23日
2014年8月15日
Arduino - LED 7 段數字顯示器
LED 7 段數字顯示器數數控制。
材料
LED 共陰極7段顯示器 x 1
Resistor 330Ω x7
製作
< 參考「Arduino互動設 計入門2」- p7-5 ~ p7-7 >
port D0 (RX) 與上傳程式的USB共用之故, 我沒用上。
電路圖如下:
程式同上篇一樣使用 DDRx/PORTx 的技巧;如下:
各接腳定訂如下:
pin D0 :(不用)
pin D1 :底部橫線
pin D2 :左下直線
pin D3 :左上直線
pin D4 :中間橫線
pin D5 :頂部橫線
pin D6 :右上直線
pin D7 :右下直線
右下角dp點沒做控制;程式技巧使用到 mod 運算,使得索引 index 只由 0 ~ 9 不會超過 10。
完成!
材料
LED 共陰極7段顯示器 x 1
Resistor 330Ω x7
製作
< 參考「Arduino互動設 計入門2」- p7-5 ~ p7-7 >
port D0 (RX) 與上傳程式的USB共用之故, 我沒用上。
電路圖如下:
程式同上篇一樣使用 DDRx/PORTx 的技巧;如下:
const byte LED_SET = 0b11111110 const byte LEDs[10] = { 0b11110110, // 0 0b11000000, // 1 0b01101110, // 2 0b11101010, // 3 0b11011000, // 4 0b10111010, // 5 0b10111110, // 6 0b11100000, // 7 0b11111110, // 8 0b11111000 // 9 }; byte index = 0; void setup() { DDRD = LED_SET; } void loop() { index %= 10; PORTD = LEDs[index++]; delay(1000); }
各接腳定訂如下:
pin D0 :(不用)
pin D1 :底部橫線
pin D2 :左下直線
pin D3 :左上直線
pin D4 :中間橫線
pin D5 :頂部橫線
pin D6 :右上直線
pin D7 :右下直線
右下角dp點沒做控制;程式技巧使用到 mod 運算,使得索引 index 只由 0 ~ 9 不會超過 10。
完成!
2014年8月12日
Arduino 第二課 - 跑馬燈
繼自學第一課: LED switch 用開關控制 LED (或者其他元件)後, 接著進入較複雜的(程式)控制: 跑馬燈。
材料
LED x3 (以上)
Resistor 330Ω x3 (搭配LED數量)
製作
< 參考「Arduino互動設 計入門2」- p4-19 ~ p4-21 >
紅色線: 高電位/電源輸出
黑色線: 低電位/電源回流
分兩種接法: 左圖為源流(source current) 與 右圖潛流(sink current)
電路圖如下:
程式如下:
上述, 使用了廻圈(loop)與陣列(array)的寫法; 源流接法時, 將
潛流接法時, 將
另外, 可使用 DDRx (Data Direction Register)來控制 pin 的輸出入, 並使用 shift 的程式技巧來達成:
<以DDRD/PortD為例>
上述為潛流接法的寫作, 源流的寫法得花點時間想想。
ps.
上述二例寫法與「Arduino互動設 計入門2」- p4-28, p4-31有點不同
材料
LED x3 (以上)
Resistor 330Ω x3 (搭配LED數量)
製作
< 參考「Arduino互動設 計入門2」- p4-19 ~ p4-21 >
紅色線: 高電位/電源輸出
黑色線: 低電位/電源回流
分兩種接法: 左圖為源流(source current) 與 右圖潛流(sink current)
電路圖如下:
程式如下:
const byte LEDs[] = {4 ,7, 10}; const byte LEDs_SIZE = sizeof(LEDs); const byte INIT_VALUE = LOW; // LOW/HIGH when using source-/sink-current circuit byte count = 0; void setup() { for (byte i=0; i< LEDs_SIZE; i++) { pinMode(LEDs[i], OUTPUT); } } void loop() { for (byte i=0; i< LEDs_SIZE; i++) { digitalWrite(LEDs[i], INIT_VALUE); } count = count % 3; digitalWrite(LEDs[count], ! INIT_VALUE); count++; delay(200); }
上述, 使用了廻圈(loop)與陣列(array)的寫法; 源流接法時, 將
const byte INIT_VALUE = LOW;
潛流接法時, 將
const byte INIT_VALUE = HIGH;
另外, 可使用 DDRx (Data Direction Register)來控制 pin 的輸出入, 並使用 shift 的程式技巧來達成:
<以DDRD/PortD為例>
// for sink-current circuit const byte INIT_VALUE = 0b00001000; const byte LED_SHIFT = 2; byte count = 0; void setup() { DDRD = 0b10101000; // OFF for pull-down circuit } void loop() { count = count % 3; if (count == 0) { PORTD = INIT_VALUE; } else { PORTD <<= LED_SHIFT; } count++; delay(200); }
上述為潛流接法的寫作, 源流的寫法得花點時間想想。
ps.
上述二例寫法與「Arduino互動設 計入門2」- p4-28, p4-31有點不同
2014年8月10日
Arduino 第一課 - LED switch
去天瓏買書時, 老闆慫恿我買 Arduino 的書來看, [年紀這麼大了, 學還來得及嗎?] 我這樣子問, 他說:[玩玩嘛!]. 於是真得玩了起來.
會有這樣子的想法, 是多年前 Make: 正夯(現在已發行《Make》雜誌國際中文版), 印象所及是曾看一篇網頁說明了用紅外線指示筆+光碟機做出了一個雷射筆(槍), 不久後新聞報導了大陸的網購網站竟然開始賣這樣子危險的東西; 另外, 還有 GPS 尋寶遊戲的導航製作. 試想, 我自己是否依樣畫葫蘆呢?!
而 Arduino 對我所學非專科的人來說, 多半只是看看而已; 直到一年多前開始察覺已經出現很多網站刊出很多有趣的東西之後, 我才順著天瓏老闆的話, 試著玩玩, 看是否如同以前的中推會同事一般, 做出個藍芽搖控玩具呢?!
但自學的第一課是什麼呢? 買材料! 而買材料的第一步是找一間電子材料行隨意逛逛. 看了玲瑯滿目各式規格看不懂的電子料件, 足足花了三個小時才買到了一些要學習的基本材料; 當然, 這樣子的結果是有先做功課的; 不然, 第一時間, 大概會因為眼花潦亂, 嚇到後打退堂鼓的.
即然身為 software developer 是沒在怕的, 先自我催眠: 只不過是組裝電路後把程式寫入即可. 於是乎產出了第一個電路及程式: LED switch
材料
Switch x 1 (微動開關)
LED x1
Resistor 330Ω (for LED)
Resistor 10KΩ (for Switch)
製作
< 參考「Arduino互動設 計入門2」- p4-8, p4-12, p4-14 >
紅色線: 高電位/電源
黑色線: 低電位/接地
白色線: 輸出 or 輸入
要注意上拉(pull-up)電阻與下拉(pull-down)電阻的選用與接法不同:
圖左為下拉電阻接法, 右圖為上拉電阻接法; 電路圖如下:
程式如下:
程式以下拉電阻接法寫的, 若為上拉電阻接法, 只要將其中
改為
即可.
done!
ps.
「Arduino互動設 計入門2」- p4-16 的程式寫法會嚇到初學者的
會有這樣子的想法, 是多年前 Make: 正夯(現在已發行《Make》雜誌國際中文版), 印象所及是曾看一篇網頁說明了用紅外線指示筆+光碟機做出了一個雷射筆(槍), 不久後新聞報導了大陸的網購網站竟然開始賣這樣子危險的東西; 另外, 還有 GPS 尋寶遊戲的導航製作. 試想, 我自己是否依樣畫葫蘆呢?!
而 Arduino 對我所學非專科的人來說, 多半只是看看而已; 直到一年多前開始察覺已經出現很多網站刊出很多有趣的東西之後, 我才順著天瓏老闆的話, 試著玩玩, 看是否如同以前的中推會同事一般, 做出個藍芽搖控玩具呢?!
但自學的第一課是什麼呢? 買材料! 而買材料的第一步是找一間電子材料行隨意逛逛. 看了玲瑯滿目各式規格看不懂的電子料件, 足足花了三個小時才買到了一些要學習的基本材料; 當然, 這樣子的結果是有先做功課的; 不然, 第一時間, 大概會因為眼花潦亂, 嚇到後打退堂鼓的.
即然身為 software developer 是沒在怕的, 先自我催眠: 只不過是組裝電路後把程式寫入即可. 於是乎產出了第一個電路及程式: LED switch
材料
Switch x 1 (微動開關)
LED x1
Resistor 330Ω (for LED)
Resistor 10KΩ (for Switch)
製作
< 參考「Arduino互動設 計入門2」- p4-8, p4-12, p4-14 >
紅色線: 高電位/電源
黑色線: 低電位/接地
白色線: 輸出 or 輸入
要注意上拉(pull-up)電阻與下拉(pull-down)電阻的選用與接法不同:
圖左為下拉電阻接法, 右圖為上拉電阻接法; 電路圖如下:
程式如下:
const byte SWITCH = 10; const byte LED = 16; //boolean lastState; void setup() { // lastState = LOW; pinMode(SWITCH, INPUT); pinMode(LED, OUTPUT); pinMode(LED_2, OUTPUT); digitalWrite(LED_2, LOW); } void loop() { boolean click = false; boolean currentState = digitalRead(SWITCH); // pull-down circuit, use NOT when using pull-up circuit if (currentState != lastState) { delay(20); currentState = digitalRead(SWITCH); // pull-down circuit, use NOT when using pull-up circuit if (currentState != lastState) { click = true; lastState = currentState; } } if (click) { digitalWrite(LED, currentState ); } }
程式以下拉電阻接法寫的, 若為上拉電阻接法, 只要將其中
... = digitalRead(SWITCH);
改為
... = digitalRead(! SWITCH);
即可.
done!
ps.
「Arduino互動設 計入門2」- p4-16 的程式寫法會嚇到初學者的
2014年4月19日
Upgrade subversion 第二彈
自從 upgrade 至 Mavericks 後, 大多不太敢將開發工具也一起 upgrade, 必竟編譯環境並非像這些軟件更新的這麼快。
以個人的工作平台為例:
對於更新 JavaHL native lib 以整合 subversion eclipse plug-in v1.7.x,過去雖有經驗,但仍無法使用 Homebrew 順利安裝,發生的問題有二:
但,索性有過這樣子的經驗後,找到了解決的方法:
that's it.
以個人的工作平台為例:
Mavericks + GGTS v3.5.0(Eclipse v3.8.2) + Xcode v5.1 + JDK 1.7.0_51
對於更新 JavaHL native lib 以整合 subversion eclipse plug-in v1.7.x,過去雖有經驗,但仍無法使用 Homebrew 順利安裝,發生的問題有二:
- 安裝 subversion v1.7.10 時, 無法取得 serf
- 安裝 subversion17 (v1.7.14) 時, 無法載入 zlib
但,索性有過這樣子的經驗後,找到了解決的方法:
- 解開 subversion17 安裝時留下來的壓縮檔
- 手動進行編譯
- 產生 java.library.path 路徑內的 lib 連結
cd /tmp cp /Library/Caches/Homebrew/subversion17-1.7.14.tar.bz2 . open subversion17-1.7.14.tar.bz2 cd /tmp/subversion-1.7.14確認 java --version 為 1.7.0
make clean ./configure --prefix=/usr/local/Cellar/subversion17/1.7.14 --with-apr=/usr/bin --with-zlib=/usr/local --with-sqlite=/usr/local/opt/sqlite --with-serf=/usr/local/opt/serf --disable-mod-activation --disable-nls --without-apache-libexecdir --without-berkeley-db --enable-javahl --without-jikes修改 Makefile:
... JAVAC_FLAGS = -target 1.7 -source 1.7 ...再進行安裝:
make install-javahl make install cd /Library/Java/Extensions sudo ln -sf /usr/local/Cellar/subversion17/1.7.14/lib/libsvnjavahl-1.dylib sudo ln -sf /usr/local/Cellar/subversion17/1.7.14/lib/libsvnjavahl-1.jnilib打開 GGTS, 設定 [Team]/[SVN]/[SVN interface]:
that's it.
2014年4月7日
IPO
IT 領域中, input --> process --> output 是基本結構
社會層面上, "法(條)" 是 "法治化" 的結果;
就邏輯上而言, 法治化是 process , 法(條)是 output
那 input 是什麼呢?!
若從 IT 技術上來看, Garbage in 就會 garbage out
換句話說, 對於目前政經問題(服貿協議法治化/太陽花學運), 我們更該注意 input 到法治化過程中的內涵
社會層面上, "法(條)" 是 "法治化" 的結果;
就邏輯上而言, 法治化是 process , 法(條)是 output
那 input 是什麼呢?!
若從 IT 技術上來看, Garbage in 就會 garbage out
換句話說, 對於目前政經問題(服貿協議法治化/太陽花學運), 我們更該注意 input 到法治化過程中的內涵
2014年1月23日
BeanUtilsBean 的小小應用 2
在利用 BeanUtilsBean 的一點小技巧來解決部份 property 不做 copyProperties() 的需要之後。
如果處理 BigDecimal 的 property 賦值, 而其值為 null 時, 會出現...
Exception in thread "main" org.apache.commons.beanutils.ConversionException: No value specified
at org.apache.commons.beanutils.converters.BigDecimalConverter.convert(BigDecimalConverter.java:...)
...
解決問題前, 先從 BeanUtils 取得 BeanUtilsBean.getInstance() 來處理 copyProperties() 的 source 中看到:
實際是使用了預設的 BeanUtilsBean() constructor:
如果處理 BigDecimal 的 property 賦值, 而其值為 null 時, 會出現...
Exception in thread "main" org.apache.commons.beanutils.ConversionException: No value specified
at org.apache.commons.beanutils.converters.BigDecimalConverter.convert(BigDecimalConverter.java:...)
...
解決問題前, 先從 BeanUtils 取得 BeanUtilsBean.getInstance() 來處理 copyProperties() 的 source 中看到:
private static final ContextClassLoaderLocal beansByClassLoader = new ContextClassLoaderLocal() { protected Object initialValue() { return new BeanUtilsBean(); } };
實際是使用了預設的 BeanUtilsBean() constructor:
public BeanUtilsBean() { this(new ConvertUtilsBean(), new PropertyUtilsBean()); } public BeanUtilsBean(ConvertUtilsBean convertUtilsBean, PropertyUtilsBean propertyUtilsBean) { this.log = LogFactory.getLog(BeanUtils.class); this.convertUtilsBean = convertUtilsBean; this.propertyUtilsBean = propertyUtilsBean; }明顯的看到它使用了預設的 ConvertUtilsBean() constructor, 並在 deregister() method 中建構各類型的 converter 以便爾後的 properties 賦值處理:
public ConvertUtilsBean() { this.converters.setFast(false); deregister(); this.converters.setFast(true); } ... public void deregister() { ... register(BigDecimal.class, new BigDecimalConverter()); ... } ...但, 當中 BigDecimalConverter() constructor 是不預設賦值的:
public BigDecimalConverter() { this.defaultValue = null; this.useDefault = false; }另一 constructor 則是:
public BigDecimalConverter(Object defaultValue) { this.defaultValue = defaultValue; this.useDefault = true; }也就是說, 可以使用另一組 BigDecimalConverter() constructor 來避免上述的 exception 發生:
BeanUtilsBean defaultNullValueBeanUtils = new BeanUtilsBean(new ConvertUtilsBean() { @Override public void deregister() { super.deregister(); // 這裡還是預設了 null 為其值 register(new org.apache.commons.beanutils.converters.BigDecimalConverter(null), BigDecimal.class); ... } }, new PropertyUtilsBean()); ... defaultNullValueBeanUtils.copyProperties(dest, orig); ...done!
2014年1月17日
BeanUtilsBean 的小小應用
Apache Commons BeanUtils 發展有十多年, 累積了很多很棒的功能; 它在當時推動 JavaBean 風潮的時空背景下, 算是主要的推手之一。主要的精神在於讓 class 像 data type 一般, 借由 naming convention 慣例, 使用 attributes(或稱 properties) 的 setter/getter methods 來存取 information, 保有了物件導向理論中封裝特性的彈性與好處。雖說另有一派(人)不同意此一看法,但仍有其存在的必要。
最常見的是, 兩個物件有幾乎相仿的 setter/getter methods 情形下進行 copy;在很早的 COBOL、FoxBase ... 年代, 這些 language 在宣告上或語法上已有支援, 而 4GL 年代也有相同、類似的支援方式:
此時, programmer 一定會很感激 BeanUtils 的存在; 它的其中一個最基本的功能:
當有十幾、廿個 attributes 要賦值, 但僅少數幾個則否; 那要怎樣進行呢?
可從 BeanUtils 的 source code 看來, 它主要是由 BeanUtilsBean class 的 method 進行 copy 功能:
但, 如果沒有重用(re-use)的情形, 定義新的 class 實在會顯得 Java 語言的繁瑣; 索性, 可利用 anonymous inner class 寫法來做就好:
而其中 setExcludeNames() 回傳 this 的方法, 可以免除自定 class 及其新的 constructor 來紀錄 excludeNames 的麻煩。
最常見的是, 兩個物件有幾乎相仿的 setter/getter methods 情形下進行 copy;在很早的 COBOL、FoxBase ... 年代, 這些 language 在宣告上或語法上已有支援, 而 4GL 年代也有相同、類似的支援方式:
LET recordA. * = recordB.*唯獨當年剛從 internet 中展露頭角的 Java 還沒有"方便"的方式, 尤其是當兩個物件有幾十、甚至上百個 attributes 時, programmer 一定會恨死如:
... beanA.setAttr1(beanB.getAttr1()); beanA.setAttr2(beanB.getAttr2()); beanA.setAttr3(beanB.getAttr3()); ... beanA.setAttr99(beanB.getAttr99()); ...這種佔篇幅、又容易打(或複製)錯字而不易察覺的笨挫寫法。
此時, programmer 一定會很感激 BeanUtils 的存在; 它的其中一個最基本的功能:
BeanUtils.copyProperties(destBean, origBean);它會取得 origBean 中所有 public getXXX() 之類的 methods 回傳值, 找到 destBean 中相對應的 setXXX() methods, 接著叫(調)用並賦值給它。(當然, origBean 的 getter 回傳型別與對應 destBean 的 setter 參數型別要相容)
當有十幾、廿個 attributes 要賦值, 但僅少數幾個則否; 那要怎樣進行呢?
可從 BeanUtils 的 source code 看來, 它主要是由 BeanUtilsBean class 的 method 進行 copy 功能:
public void copyProperties(Object dest, Object orig) throws IllegalAccessException, InvocationTargetException { // ... copyProperty(dest, name, value); // ... }所以, 只要製訂這 class 新的 subclass, 並控制 copyProperty() 的處理, 如下所示:
@Override public void copyProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException { if (!excludeNames.contains(name)) { super.copyProperty(bean, name, value); } }而在其中, 只要先紀錄 excludeNames 即可。
但, 如果沒有重用(re-use)的情形, 定義新的 class 實在會顯得 Java 語言的繁瑣; 索性, 可利用 anonymous inner class 寫法來做就好:
// ... new BeanUtilsBean() { private List〈string〉 excludeNames = new ArrayList〈string〉(0); BeanUtilsBean setExcludeNames(String[] excludeNames) { if (excludeNames != null && excludeNames.length > 0) { this.excludeNames = Arrays.asList(excludeNames); } return this; } @Override public void copyProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException { if (!excludeNames.contains(name)) { super.copyProperty(bean, name, value); } } }.setExcludeNames(new String[] {"someAttr"}) .copyProperties(destBean, origBean); // ...如此直接叫(調)用即可。
而其中 setExcludeNames() 回傳 this 的方法, 可以免除自定 class 及其新的 constructor 來紀錄 excludeNames 的麻煩。
2014年1月12日
Grails Scaffolding
Grails 的 Scaffolding 功能自開天闢地以來就有了, 也是介紹入門時的介紹重點之一。
上篇 GORM custom id 另解 就是由 scaffolding plugin 產生出來後所進行的調整; 如果多數 controller 變更情形如同上篇, 那多半會考慮變更 template files, 在產生(generate-all)時就大致已調整完成, 而稍做修改即可。
變更修改前, 須先產生預設的 template files 在專案目錄 src/templates(/scaffolding) 下:
其實這小撇步早在多年前另一篇 GORM 物件於 update method 後立即顯示資料 也用過。
當時 Grails 的版本及 IDE 工具比較沒有整合的很好, 多半是 console 下打指令來進行開發 (而 IDE 則用來 debug)。目前的版本 v2.3 早已提供 interactive mode, 可利 TAB 鍵進行快速提示與執行; 另外 GGTS IDE 也提供了很好的整合, 以 generate-all 指令為例, 有兩種方式:
(1) 原先提供的 context menu :
(2) [New] function:
上篇 GORM custom id 另解 就是由 scaffolding plugin 產生出來後所進行的調整; 如果多數 controller 變更情形如同上篇, 那多半會考慮變更 template files, 在產生(generate-all)時就大致已調整完成, 而稍做修改即可。
變更修改前, 須先產生預設的 template files 在專案目錄 src/templates(/scaffolding) 下:
grails> install-templates接著再以 editor 直修改它, 存檔後會在下次產生另一組 controller/views 時生效。
其實這小撇步早在多年前另一篇 GORM 物件於 update method 後立即顯示資料 也用過。
當時 Grails 的版本及 IDE 工具比較沒有整合的很好, 多半是 console 下打指令來進行開發 (而 IDE 則用來 debug)。目前的版本 v2.3 早已提供 interactive mode, 可利 TAB 鍵進行快速提示與執行; 另外 GGTS IDE 也提供了很好的整合, 以 generate-all 指令為例, 有兩種方式:
(1) 原先提供的 context menu :
- 在 project 上按右鍵, 選擇 [Grails Tools]
- 選擇適合的功能 (多半以 [Open Grails Command Prompt])
- 當然, 最快的方式是按下快捷鍵 [Cmd]+[Opt]+[Shift]+G
(2) [New] function:
- 直接在 domain class 上按右鍵, 選 [New]
- 選擇 [Generate Controller and Views], 並輸入 domain class 即可
以上
訂閱:
文章 (Atom)