2013/02/26

Silent Block -- Firefox 過濾 URL 的擴充套件

介紹一個 Firefox 的擴充套件 -- Silent Block,可以用來過濾你指定的 URL。這個套件很好用 (過濾能力又強又有彈性),但不容易用。因為你要自訂 regular expression 來定義 URL, 而且要自己用 editor 寫。此套件網址如下:
https://addons.mozilla.org/en-US/firefox/addon/silentblock/
簡單舉一個使用情境:你經常需要連到網頁 A,此頁面又會顯示一些大又無用的圖案,造成頁面顯示緩慢。這時,你就可以用 Silent Block 不聲不響的濾掉這些圖檔。

使用此擴充套件你必須在自己的 profile 目錄編輯一個 contentblock-regex.txt 檔案。檔案內容就是一條條想要擋下的 URL。套件的官方網址如下 (間單扼要,跟套件的實作風格一樣):
http://www.schuzak.jp/fx/silentblock.html

頁面最底下有一個設定範例。沒用過 regular expression 的人,看過之後肯定馬上放棄。有興趣挑戰的人,可以參考 Mozilla 的文件:
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions#Writing_a_Regular_Expression_Pattern

2013/02/13

Epson Stylus Office TX610FW @ Ubuntu

在 Ubuntu 要列印到 Epson Stylus Office TX610FW?沒問題,方法如下:
  1. http://www.openprinting.org/driver/epson-stylus-office-tx610fw-series 下載 Epson 提供的 package,我試過 1.0.0 (DEB for LSB 3.2) 這一個。注意!請正確選擇 32bit 或 64bit 版本,而且必須先安裝 lsb 套件。
  2. 安裝指令 sudo dpkg -i epson-inkjet-printer-stylus-office-tx610fw-series_1.0.0-1lsb3.2_amd64.deb
  3. 安裝好之後,打開 Epson 印表機電源。然後執行印表機設定程式 (非 Unity:系統>管理>列印;Unity:點左上的 Ubuntu logo,輸入 printer 搜尋就會出現)
  4. 在印表機程式畫面點「加入」,再點「網路印表機」。一開始只會出現各種 protocol 的選項,稍等一兩分鐘之後,就會出現 Epson Stylus Office TX610FW 選項。點這個選項,再按「下一步」便會出現印表機的名稱設定,直接「套用」就完成了。
在 Ubuntu 上有一個好處:任何支援列印的程式,你都可以用「列印到檔案」的方式來產生 PDF 文件。我經常使用這項功能,但自從安裝 TX610FW 相關套件之後就有一個小麻煩:每次開啟列印的時候都要等很久。因為系統要讀 TX610FW 印表機的狀態,而我只有想列印的時候才會開這台印表機,所以只能等系統 timeout 放棄之後,我才能去選列印到檔案。

這問題有一個簡單的解法,就是新增一台假的本地印表機來當作預設印表機:
  1. 執行印表機設定程式,點選「加入」
  2. 序列埠 #1 > Generic > text-only printer > 輸入你想要的名稱
  3. 選這台剛新增的印表機,印表機 > 設為預設值
這樣下次開啟列印的時候就不會有等待的時間,你可以馬上選擇列印到檔案或 TX610FW。

2013/02/02

不用條件指令,找出兩數中的較大者

這是一個動腦用的程式設計題目,網路上有不少問答。我發現有不少人誤解「不用條件指令 (without conditional operator)」,這部份要用 assembly 的觀點來看比較清楚。簡單說,指令執行時不能有 branch 的動作,但 compare 是允許的。

錯的答案:
larger = max(a, b);
回答的人可能在搞笑。若 max() 符合要求,這個問題就是要問怎麼作到的。
larger = (a + b + abs(a - b)) / 2;
這個答案看起來有點學問,但本質跟前一個答案一樣,要依賴 abs() 的實作方法。另外,(a-b) 也有 overflow 的問題。
larger = (a > b) ? a : b;
這個不用解釋吧?這只是 if else 的變形,一樣是條件指令。
larger = a;
(void)((a < b) && (larger = b));
這個答案利用 short-circuit and 來決定是否令 larger = b,骨子裡一樣需要條件指令。
#include
unsigned d = b - a;
m = -(d >> (sizeof(int) * CHAR_BIT - 1));
larger = (a & m) | (b & ~m);
這個答案很用心,考慮到可攜性。但用到 b - a,就會有 overflow 的問題。

對的答案:
m = -(a > b);
larger = (a & m) | (b & ~m);
這個方法跟前一個接近,但不會有 overflow 的問題,看起來也清爽多了。小瑕疵是有前提:此計算機系統必須採用二的補數 (2's complement) 來表示有號數。但這個假設,目前「幾乎」都會成立。
larger = ((a ^ b) & -(a > b)) ^ b;
這個方法是前一個的再簡化版本,不是一眼可以懂,但乾淨俐落。同樣也有相同的前提。
larger = (a > b) * a + (a <= b) * b;
這個方法不需任何前提,但我不喜歡那兩個乘法。不知有誰可以改掉?
int p[] = { a, b };
larger = p[a < b];
這個方法除了需複製變數之外,其他都很完美。

組合兩個 bitmap 的方法

寫程式的時候,我們經常需要將兩個 bitmap 組合起來。譬如,取 A 的前三 bit 和 B 的後五 bit 組成一個新的 bitmap。通常我們會這麼寫:
M= 0xE0;
C = (A & M) | (B & ~M);
整理舊書時,看到以前唸大學時的筆記有另一個有趣的方法:
M = 0xE0;
C = ((A ^ B) & M) ^ B;
第二個方法沒那麼直覺,但可以省下一個 ~ 運算。