顯示具有 [ 雜七雜八 ] 標籤的文章。 顯示所有文章
顯示具有 [ 雜七雜八 ] 標籤的文章。 顯示所有文章

2014年3月24日 星期一

[文章收集] 免洗信箱、一次性拋棄式email整理

來源自 這裡 
Preface: 
現今很多線上服務都需要使用 email 註冊,不管是論壇、抽獎、填問卷、軟體下載等,為了要認證你的身份,避免被用程式洗帳號灌水,最簡單的方法就是把認證信寄到你的 email 信箱,然後不管是透過註冊碼或註冊連結,總之就是需要信箱裡認證信件的某些資訊來通過註冊. 

這種方式其實對服務提供者是很正常的想法,然而有了使用者的 email ,很多服務接著會寄送很多使用者不想看到的訊息,比較不負責的還沒有取消這些訊息的方法。更慘的是有些業者藉著作問卷、抽獎等方式得到大家的 email 資料,接著就順手把這些 email 拿去賣錢了,於是使用者開始收到許多廣告信、色情垃圾信等

免洗email: 
因為這樣,漸漸地大家也越來越保護自己的 email 信箱,有的人可能會專門去申請一個免費帳號專門用在不重要的註冊、抽獎等,但現在有個更好的解決方法!那就是完全不用註冊,免洗且用過即丟的拋棄式email! 免洗email的服務眾多,這邊列出幾個比較常見且好用的: 
1. http://10minutemail.com/
2. http://mailnesia.com/
3. http://www.fakeinbox.com/
4. http://tempemail.gentleprojects.com/
5. https://www.guerrillamail.com/zh-hant/
6. http://www.jetable.org/zh/index

首先第一個 http://10minutemail.com/ 算是免洗信箱中名聲最大的,也因為他大家平常也會把免洗信箱稱作「10分鐘信箱」,一連到這個網頁他就會自動幫你產生一個免洗信箱,只要複製 email 位址就可以直接拿去註冊了,此時要記得 browser 不要關,因為收信也是在同一頁面。另外如果覺得10分鐘太短也可以一直按延長時間. 

相較於 10minutemail 這個網站,接下來兩個免洗信箱功能就更實用一點,因為 10minutemail 是每次進入網站就隨機產生一個新的信箱,無法指定信箱名稱,無法在過期前換一個,也無法在過期後重新回到先前的信箱。 

第二個 http://mailnesia.com/ 一樣在進入網站後就隨機產生一個信箱,期間可以不斷按隨機產生名字來切換到新的信箱,也可以在輸入欄位填入自己想要的開頭,並按下右方的綠色箭號建立新的信箱。如果要回到先前的信箱也只要記住開頭,輸入後按綠色箭號就可以看到信了。這個信箱的好處是可以用先前的帳號,但壞處是每個人都可以進到相同的帳號去看裡面有哪些信件
 


再來的 http://www.fakeinbox.com/ 、 http://tempemail.gentleprojects.com/ ,功能也都和 http://mailnesia.com/ 都差不多,大家可以再自行試用看看。guerrillamail 本身就有多個域名的信箱可選,也可以自訂帳號,還不錯用

前幾個都是簡單的拋棄式信箱,過了時效後信件和信箱都會自動刪除,但如果我們想要將信件留存下來呢?這時候 http://www.jetable.org/zh/index 就是最好的選擇了!http://www.jetable.org/zh/index 一樣會產生一個免洗信箱,特別之處是他在時效內是將免洗信箱的信件轉寄到我們的真正信箱,不過時效過後接下來進來的的信件就不會轉過來囉。 

除了上述的免洗信箱外,透過 Gmail 分身術加上過濾器也可以達到類似的效果,詳情請見:Gmail 無限分身術:產生無限 email 帳號

2014年1月19日 星期日

[UI Automation] Sikuli 的入門使用

來源自 這裡 
Sikuli是什麼? 
用維基百科上的介紹來說,Sikuli 是一種可視化技術,它可以用來自動化的在一個圖形用戶界面(GUI)上進行操作和測試。而 Sikuli 腳本就是實現這一過程的一種腳本語言。它通過截圖來識別需要操作的圖形界面組件,再通 Jython 來完成操作動作從而實現自動化的操作(或者測試). 說得簡單一點,Sikuli 就是能通過截圖幫助我們自動操作電腦的一種便利的方式。如果想瞭解更多的Sikuli的意義,那就讀一讀 Sikuli 作者的 介紹 吧! 

那 Sikuli 是不是很難學呢?如果不追求精細的操控和精準的方式,那你只需要有一個操作電腦的心,再加上認識幾個英語單詞,就足夠了. 

先從安裝Sikuli開始吧: 
是不是要先檢查一下你的操作系統?不,當然不用,但是也有一樣需要確認,那就是你的電腦上是否安裝了Java呢?不知道如何檢測自己電腦上是否安裝了Java嗎?不要著急,只需要打開 Java官方的檢測網頁,然後根據頁面的指引就能得知自己是否安裝了Java,如果沒有,也將有相應的指引,幫助你安裝好Java. 

然後,得益於 Sikuli 作者的不懈努力,不論是什麼什麼操作系統,只要安裝有 Java,就可以容易的從官方網站上下載通用安裝包來完成安裝了

一點一點的學習Sikuli: 
1. 認識一下Sikuli的IDE 
要打開運行Sikuli的運行環境還有編輯環境,我們需要雙擊安裝完成後Sikuli文件夾裡名稱為“runIDE” (Integrated Development Environment) 的文件。打開之後,Sikuli 的 IDE大概就是這樣(下圖為windows中的式樣,Mac中同此差不多,只是圖標更為精緻): 
 

而我們需要關心的也只有三個地方:可以錄入文字的編輯區域,還有運行按鈕和截圖按鈕. 

2. 從點擊按鈕開始 
我們學習電腦的時候,最先學到的或許就是如何通過點擊按鈕來實現對應的功能了。而對於Sikuli而言,點擊操作同樣是重要的,畢竟GUI中按鈕是實現操作的重要組成. 在Sikuli裡,要實現這個操作也十分簡單,因為你只需要記住 “Click” 這個單詞。沒錯,就是英語的“點擊”一詞。它的代碼也極盡簡單: 
Click(…)

而上面這句代碼中的 “…” ,並不是什麼特別的語言,或者什麼複雜的代碼,而是代表了一個截圖。比如希望Sikuli點擊一下Mac OS左上角的蘋果標示,那麼,這樣的一句代碼就可以達到目的: 
Click()

簡單也很便利! 因為這就是 Sikuli 力求達到的一種直觀的自動化操作的方式了

其它的點擊方式也與此類似,比如右鍵點擊就是:`RightClick(…)`,而雙擊就是:`DoubleClick(…)`。 

3. 尋找按鈕或者圖案 
Sikuli 的本意就是讓某一個計算機程序代替人來做操作,而識別按鈕,或者某一個圖案,也就是一個很重要的部分了。雖然這一點的意義重大,但是,對於在Sikuli上的操作卻可以很容易的實現! 這時候,你只需要認識這樣的一個英文單詞——Find。沒錯,想要在屏幕上找到某一個按鈕或者圖案,只需要使用: 
Find(…)

就可以了。當然,這個函數括號裡的目標依然是某一個東西的截圖。我們可以寫這樣的一個簡單的小命令: 
x=find()
click(x)

那這個例子實現的又是怎樣的操作呢?這個命令其實還是等同於`Click()`,只是這個例子裡,我們關注的是 Sikuli 模仿人行為的過程。一個人來點擊某一個按鈕的過程是:找到按鈕,然後點擊。而通過“find-click”方式完成的 Sikuli 腳本也同樣實現的就是人的操作過程! 如果若們要一個一個找到所有相同的按鈕要怎麼辦?不用擔心,不用寫很多遍`find(…)`的,只需要使用: 
findAll(…)

就可以了。findAll()可以一次性把所有相同按鈕,或者圖案一次性都找到。這樣找到的按鈕就會形成一個集合,這個集合的形成應該很好理解,繼續就是要如何來逐一操作這個按鈕集合裡的按鈕呢?這就涉及到 Sikuli 的程序控制問題了。這也是,接下來要講到的內容. 

4. Sikuli 腳本的程序控制 
那什麼是程序控制呢?那也就是在涉及到重複做某一個操作,或者在判斷某一個條件之後再決定是否要進行某一個操作,以及類似的情況的時候,我們所談論的就是程序控制了. 在 Sikuli 裡面,這個表示條件運行某一個行為的語句就夠也和上面這個例子類似(`#`後是程序註釋內容): 
if … : … #do something

還有另一類程序控制的內容,那就是循環語句了。也就是,需要重複做某一個動作的程序語言命令。在一般的計算機語言裡,一般有兩種方式來完成這樣的重複。一個就是for循環語句,一個是while循環語句. 我們先來分別看看 for循環語句 和 while循環語句 在Sikuli裡的寫法吧: 
* for 循環語句: for i in set: … #do something 
* while 循環語句: while … #condition : … #do something 

從上面的這個結構中,我們很容易瞭解到這樣一件事情:for循環語句是先確定需要循環操作的某一個集合,然後再進行重複操作;而while循環語句則是先考慮某一個條件成立與否來,再決定是否結束重複的操作. 那麼,現在就可以解決上面那個點擊找到的所有相同按鈕的操作了,可以用這樣的代碼來實現: 
for x in findAll(): click(x)

為了做出對比,我們再來分別看一下while循環語句的例子吧. 我們可以舉這樣的一個例子:用Sikuli來實現一下,如果我的某一個 Skype 好友下線了,就提醒我的功能。首先,我們不能確定需要查看好友下沒下限需要多少次,或者是他會在線多久,所以也就不能確定重複次數的集合了,換句話說就是,這個問題,不能使用for循環語句來完成目標。而恰切,這個循環中有一個判斷的條件,也就是關注這個好友的在線狀態是結束於好友下線的瞬間,於是,我們就可以用 while循環語句 來解決這個問題了: 
while exists(): wait(5)
popup(u”vgod下線了”)

這個代碼中,除了while循環語句,還有三個新的功能函數,`exists(…)`函數表示判斷目標截圖是不是存在,放到我們的例子裡就是用來檢查好友 vgod 的skype圖標是否處於在線狀態; `wait(…)`函數表示等待,括號裡填上需要等待的秒數就好; 而最後的`popup(…)`函數就是用於彈出一個帶文字的提示框. 

5. 打開特定的程序 
在模仿我們操作行為上更進一步,就是:打開某個程序,然後在這個程序上進行操作。就比如打開Safari,然後進入Top Sites。對應打開程序這個操作的Sikuli函數依然十分貼近英文: 
App.open(…)

那麼,我們就可以這樣來完成這個例子: 
App.open(“Safari”)
click()

當然這是在Safari還沒打開的情況下,如果Safari打開了,但是,窗口被最小化了,我們又要如何操作呢?同樣簡單,使用 App.focus(…) 就可以了。只需要上面的例子裡的第一行修改成: 
App.focus()

類似的,關閉程序,就是:App.close(…),這個函數的使用方法也是類似的. 

6. 操作鍵盤 
直到上面,我們一直都在關注的都是鼠標操作,現在是我們需要開始關注一下鍵盤操作的時候了. 我們從一開始到現在,已經足夠多的了解到點擊鼠標在 Sikuli 裡是Click(…),而敲擊鍵盤在 Sikuli 裡其實也是差不多的,就是使用: 
type(…)

我們可以做這樣一個例子,就是在Spotlight中搜索一個單詞: 
click()
type(“Sikuli”)

對於普通的文字輸入,只需要把需要的文字用雙引號括起來在寫到 “type(…)” 的括號裡就可以了。如果是中文的話,就在雙引號前加上一個字母“u”: 
type(u”朱麗葉”)

那麼對於特殊字符又要如何處理呢?比如,Mac OS上的 CMD,又或者是 Windows 上的win鍵,這兩個極特殊的鍵,在 Sikuli 裡面都使用 KEY_META 來代表,使用的方法就是直接把它寫入括號內,如:type(KEY_META),注意喲,對於特殊按鍵是不用使用雙引號括起來的

對於 CTRL、ALT 之類的特殊鍵,也可以按照類似的模式使用,也就是“KEY_”加上對應的全大寫鍵名。不過,這個表示方法並不適用於全部特殊鍵。對於 “F1” 至 “F12” 和 “ESC” 鍵而言,需要使用 “Key.” 加上鍵名來表示. 當我們需要同時按下兩個按鍵來完成某一個操作的時候,又要如何在 Sikuli 裡實現呢?雖然還是使用 “type(…)”,但是也只是簡單的稍作增加,比如我們要使用快捷鍵刷新 Safar i的當前頁面. (更多說明可以參考 Key Constants
type(KEY_META,”R”)

7. 一個用於搶購的實例 
當我們已經明白並且記住了以上那些東西之後,就可以考慮做一些稍微複雜的事情了。選擇一個什麼樣子的實例比較有趣呢?我首先想到的,就是這類“手快有手慢沒”的網絡搶購的例子了! 

想想看吧,我們需要Sikuli不停的監視網頁,如果網頁不能實時自刷新、自更新,那麼,還要不斷刷新網頁,直到搶購的時機來到,當開始請購的時候,需要點擊搶購的按鈕,需要修改購買的數量,如果有需要還要填寫自己的地址和信用卡信息等等,一直到確認所有信息,並完成最後的訂單確認. 我們就以下面這個網頁的搶購為例吧! 
 

我們需要等到搶購的按鈕 "" 出現,為此我們假設網頁不能自更新,於是,在Mac OS裡面我們可以用這樣一段代碼實現: 
App.focus(“Safari”)
while not exists():
type(KEY_META,”R”)
click()

然後,在新的頁面上,修改需要搶購的個數(假設買三件),再確認購買進入訂單頁面。當然,也還是有可能需要我們滾動一下頁面來找到需要修改的位置。用 Sikuli 來實現的代碼也就是: 
while not exists():
  type(key.DOWN)
x=find().right().find()
for i in range(3):
  click(x)
click()

在這一段代碼中,兩個新的函數,一個是“right()”,這是用來表示搜索方向的函數;還有一個是“range(…)”,這是用來生成數列的函數,數列長度填入函數的括號內,這是一個 Python 裡的函數. 當我們進入訂單頁面之後,需要檢查是否已經填好地址,如果沒有填好地址,就把地址填上,再確認訂單,我們這次搶購就算完成了。相應的 Sikuli 代碼可以這樣寫出來: 
if exists():
  click()
  type(u”中國哏都”)
  click()
click()

現在,我們就可以把程序完整整理出來了,需要注意的是,Sikuli 在解讀代碼過程中使用的是Python/Jython的解讀模式,也是通過縮進來判斷那些程序是一起運行的。上面的程序中 while循環語句 等程序控制語句我都使用了這樣的方式來分行分別寫下運行條件和運行內容. 

8. 各種Sikuli的小提示 
1. 如果需要截圖的按鈕在比較深的菜單裡,那麼就需要手動啓動 Sikuli 的截圖快捷鍵。這個截圖快捷鍵是:Command+Shift+2 
2. 可以多是用幾個 “wait(…)” 函數來讓 Sikuli 暫停幾秒鐘,尤其是再打開網頁、刷新網頁的時候,因為未加載好的網頁可能讓識別出錯。 
3. Sikuli 自帶函數可操作的對象,大多數都可以使用截圖。雖然使用截圖會導致運行效率略有降低,但是使用截圖才是真正 Sikuli 的核心,所以不要為了速度本末倒置
4. 鼠標的拖拽操作對於 Sikuli 其實也是十分簡單的,只需要記住去使用 “dragDrop(…)” 函數就可以。 
5. Sikuli 是建立在截圖的基礎上的,也就導致,不同機器、不同分辨率、不同操作環境的電腦不能通用一個Sikuli腳本
6. if 條件運行語句的完整結構是: “if …: con1 else: con2”,含義就是如果滿足某一個條件,就運行 con1 的語句,否則,就運行 con2。 
7. 如果有時間,最好完整讀一讀 Sikuli 完整的函數介紹,因為我只是介紹了最為基本的內容,那不是 Sikuli 的全部! 

參考文獻:: 
Sikuli的發佈在2010年,到現在已經有三年的歷史了。但是 Sikuli 的發展並不快,其實它從一發佈就已經足夠完善了。有人說,Sikuli 很像按鍵精靈,嗯,確實是這樣,尤其是初學的時候。但是,當我們需要更複雜的操作的時候,當我們需要更為精緻的操作的時候,我們就會發現 Sikuli 的不同了. 
1. Sikuli (from Wikipedia) 
2. Sikuli Script 
3. Sikuli帶來的意義與無限潛力 
4. 會截圖就會自動化測試 
5. Sikuli常用函數與簡單事件操作. 
6. IDE (from Wikipedia) 
7. Sikuli——創新的圖形化編程技術 
8. Tutorials — Sikuli X 1.0 documentation 
9. Python (from Wikipedia) 
10. Jython入門教程

2012年10月3日 星期三

[ Algorithm ] 8 puzzle problem with Historical and Heuristic solution


前言 :
因為上完 AI 後, 對 8 puzzle 的問題念念不忘, 就在想怎麼解這個問題. 在下面的 "補充說明" 的 8 puzzle game 使用 A* search 的解法, 另外還有使用 "manhattan approach" 的方法. 但這邊我使用了更直覺的方法, 使用 heuristic 與 historical 的組合, 找出可能的路徑.

方法說明 :
首先第一步便是 puzzle 的 representation 的問題, 這邊我使用 number sequence 來代表, 當兩個 sequence 相等, 我便可以認定這兩個 puzzles 是相同的, 至於如何對應 puzzle 到 number sequence, 可以參考下面圖示:


第一所謂的 historical 就是我從答案往回推 n 步, 並找出所有可能的 path 可以到達的組合. 因此當我在解問題時當目前的 puzzle 的 sequence 有 hit 到這些 historical 走到的 puzzle 的 sequence, 我們便可以依據 historical 告訴我們怎麼走回去到答案(Goal).

第二所謂的 heuristic, 就是如何從 Initial State 走到 historical 看過的解法或 State, 這邊我使用 Breadth-First Search 去找所有從目前的 State 可以走得到的 State, 一直到找到 historical 看過的 sequence 為止, 如此我們便可以確認這個 algorithm 或是 Search 是 Complete 的!

上述的流程可以參考下面的 Flow:


代碼說明 :
根據上面的說明, 底下針對實作的部分進行使用的說明. 第一步便是產生 Historical answer path. 可以參考類別 c3.puzzle8.GenPS 的 main 函數:
  1. public static void main(String[] args) {  
  2.     Puzzle p = new Puzzle(123456780);  // 決定表準答案的長相  
  3.     // 1 | 2 | 3  
  4.     // 3 | 5 | 6  
  5.     // 7 | 8 | 0  
  6.     System.out.printf("\t[Test] Puzzle:\n%s\n", p);  // 顯示 Puzzle 長相  
  7.       
  8.     Set pSet = new TreeSet();         
  9.     for(int i=1; i<=13; i++)  
  10.     {  
  11.         pSet.clear();  
  12.         GenPS(i, p, pSet);  // 所以第 i步走的到的 sequence 都會記錄到 pSet 中.  
  13.         output(i, pSet);    // 將 第 i步的 sequences 輸出到檔案.  
  14.         System.out.printf("===============%d===============\n", i);  
  15.         p.restore();  
  16.     }  
  17. }  
執行後會產生一對 "?Step.txt" 檔案, 那個問號說明是第 ? 步可以走到的 sequence path. 如果是前一步 "1Step.txt" 內容會像:
#123456780->123450786
123450786
#123456780->123456708
123456708

也就是說只走一步, 可能的 Puzzle sequence 只有 "123450786" 與 "123456708".

接著便是如何在代碼定義 Puzzle 與執行, 代碼可以參考類別 c3.puzzle.Puzzle 的 main 函數:
  1. public static void main(String args[])  
  2. {  
  3.     // 7 | 2 | 4  
  4.     // 5 | 0 | 6  
  5.     // 8 | 3 | 1  
  6.     //Puzzle p = new Puzzle(7,2,4,5,0,6,8,3,1);  
  7.     Puzzle p = new Puzzle("132406578");  
  8.     p.answerSeq = "123456780"// 決定  Goal 或是  Answer 的 sequence.  
  9.     p.answer(100);  // 最多只跑 100 步.  
  10.   
  11. }  
執行結果如下:
[Test] Load in 823880 history steps... # 共載入 823880 historical sequence paths
1 3 2
4 0 6
5 7 8
132406578

[Test] Suggest path='21' with cost=14! # 使用 BFS 找到最接近的 Historical Sequence
1 0 2
4 3 6
5 7 8

0 1 2
4 3 6
5 7 8

4 1 2
0 3 6
5 7 8
...(略)...

1 2 3
4 5 6
7 8 0

Done(14)! # 共花了 14 步.

問題說明 :
這個方法還是有幾個缺點, 一是如果你的 Goal/Answer 變動時, 你就要從跑一次 Historical 的結果; 再來是在使用 heuristic 去找 historical path 時基本上是暴力解法 ><".
另外我們可以堆算 puzzle 所有可能的 sequence 會是 9!. 也就是說如果在產生 Historical 的 paths 時, 到某 n 步時所有 paths 的總數等於 9!, 我們便可以大膽說最多只要走 n 步, 一定可以回到 Goal. 這時候的問題便是秒殺了 ^^".
最後整個專案代碼可以到 這裡 下載.

補充說明 :
What is 8 puzzle?
The 8 puzzle is a simple game which consists of eigth sliding tiles, numbered by digits from 1 to 8, placed in a 3x3 squared board of nine cells. One of the cells is always empty, and any adjacent (horizontally and vertically) tile can be moved into the empty cell. The objective of the game is to start from an initial configuration and end up in a configuration which the tiles are placed in ascending number order...

8 puzzle game
The 8-puzzle - also known as the sliding-block puzzle or tile-puzzle - is one of the most popular instruments in the artificial intelligence (AI) studies. It belongs to AI exercises commonly referred as toy-problems...

Java source code for 8 puzzle solution using manhattan approach
The following java example shows how to solve a 8 puzzle problem by using manhattan approach...
This message was edited 20 times. Last update was at 04/10/2012 10:46:31

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...