:::
顯示具有 程式寫作 標籤的文章。 顯示所有文章

編碼結果轉序列編碼工具 / Coding Result to Sequence Convertor

編碼結果轉序列編碼工具 / Coding Result to Sequence Convertor

image

這一篇是為編碼結果與序列分析工具之間的資料轉換工具。因為我們通常都是用Google試算表或是Excel類型的工具來做編碼,可是序列分析工具卻輸入需要一連串的文字,因此我製作一個轉換工具來介接兩者。


操作方法 / Usage Guide

  1. 在Google試算表(Sheet)或是Excel上選取要轉換的編碼結果。如下圖:
    image
  2. 貼在下面的「coding result」表單欄位中。
    image
  3. 按下「Convert」按鈕,轉換結果就會出現在「coding sequence」欄位中。
    image

(more...)

分號轉星號工具 / Convert Semicolon to Star

分號轉星號工具 / Convert Semicolon to Star

image

這一個幫學弟寫的簡易分析小程式。

功能:將「--」符號前最近的一個「;」替換成「*」。

(more...)

將CSV與XLSX轉換成Solr XML格式 / Convert CSV and XLSX to Solr XML format

將CSV與XLSX轉換成Solr XML格式 / Convert CSV and XLSX to Solr XML format


2014-12-12_010659
Apache Solr要匯入資料的格式預設是使用XML,但這跟我們習慣使用的Excel有很大的差別。因此我利用js-xlsx套件作了一個可以在線上將Excel的XLSX格式轉成Solr XML格式的工具,方便大家把Excel資料匯入Solr。您可以在這個網頁直接使用此工具,而更新的程式碼則是典藏在GitHub上。
This tool is used to convert Excel XLSX format file to Apache Solr’s data import XML format. Following is online tool and you can download whole JavaScript codes on GitHub.


如何製作Excel檔案? / Prepare Excel Data

2014-12-12_010632 - Copy
規則只有一項:Excel的第一列是欄位名稱,第二列之後才是資料。
本程式在轉換的時候,會過濾掉&之類的XML脫逸字元。如果轉換後的檔案匯入Solr時發生異常,請在下面的留言中回覆給我知道即可。



Source code from: JS-XLSX (XLSX/XLSB/XLSM) Live Demo

Configuration


Upload XLSX
  • Example XLSX data: example-data.xlsx
  • 如果無法下載,請直接複製XML檔案,貼上到Notepad++,另存成為data.xml即可。
Drop an CSV / XLSX / XLSM / XLSB / ODS file here to see sheet data
... or click here to select a file
Advanced Demo Options: Use Web Workers: (when available) Use Transferrables: (when available) Use readAsBinaryString: (when available)
(more...)

如何閱讀JavaScript/CSS壓縮程式碼?快使用程式碼格式化工具 / How to Maxify/Parsing/Format Minified Code

如何閱讀JavaScript/CSS壓縮程式碼?快使用程式碼格式化工具 / How to Maxify/Parsing/Format Minified Code

image

為了閱讀被壓縮(minify)的JavaScript與CSS程式碼,我們可以使用線上工具Code Formatter或是NetBeans的format指令來為程式碼進行排版。

You can use some tools to maxify/parse/format the minified JavaScript or CSS codes, for example, Online Code Formatter or NetBeans.


關於壓縮程式碼 / Minify Code

JavaScript與CSS程式碼的特性在於必須下載到使用者客戶端才能執行,因此降低程式碼的大小是很常見的方式。JavaScript跟CSS通常是以壓縮(minify)的形態發佈給大家使用。被壓縮的程式碼檔案名稱通常會加上「.min」,而原始碼通常會加上「.src」,舉例來說:

image

這是jQuery 1.11.1原始碼的樣子。檔案大小是276KB。

image

這是jQuery 1.11.1壓縮程式碼的樣子。檔案大小是93.5KB,幾乎是原始碼的1/3大小。

壓縮程式碼中會移除註解、刪除空白與換行、縮短變數名稱(例如變數用了var book,會縮短成var a)。我之前也介紹過使用YUI CompressorMinify壓縮程式碼的方法。而現在壓縮JavaScript跟CSS已經是主流用法,像是Fat-Free Framework中也直接內建了壓縮工具,非常方便。

為什麼要閱讀被壓縮的程式碼? / To Read Minified Code

雖然像是jQuery這種知名的函式庫會提供非壓縮的原始碼供大家閱讀研究,但是還是很多專案並沒有提供解壓縮的原始碼,而只有被壓縮的程式碼可以看。

我最近在研究如何撰寫CKeditor的plugin,可惜他的教學跟文件寫的並不是很好。後來我覺得比起研究文件,不如直接修改程式碼,說不定還比較快。

2014-09-05_164627

可惜的是,大部分CKeditor中plugin的程式碼都是壓縮後的結果,閱讀起來不太容易,我們需要一些解壓縮(maxify)工具來輔助我們閱讀這些程式碼。

在此介紹兩種格式化被壓縮程式碼的方便工具:NetBeans的format指令跟線上工具


NetBeans的格式化指令 / “Format” in NetBeans

我使用的是NetBeansIDE 8.0。要格式化被壓縮的JavaScript程式碼的做法如下:

  1. 開啟JavaScript檔案
    2014-09-05_170730
  2. 開啟Source > Format 
    2014-09-05_170801
  3. 變成了漂亮的排版
    2014-09-05_170855

不過你可以注意到下面還是有一團程式碼沒有解壓縮到,這似乎是NetBeans的限制。此外,NetBeans也不能解壓縮CSS程式碼,使用範圍有限。

使用Code Formatter解壓縮 / Maxify Code on Online Code Formatter

這個工具名稱叫做「Format, Beautify, Maxify, Unpack or Deobfuscate JavaScript/jQuery/HTML/JSON/CSS Codes」,有點長,還是用網址上的Code Formatter來稱呼好了。

image

這工具用法很簡單。首先先把壓縮的程式碼貼在框框中,然後按下下面的按鈕「Click here to Format/Beautify/Maxify Your JavaScript/jQuery/JSON//HTML Codes」。

image

程式碼就以漂亮的版面排版好了,而且NetBeans沒解開的後面部分也排版的漂漂亮亮,這樣就能夠更輕易地閱讀程式碼了,真是令人開心呢。

希望這些工具能夠幫助程式開發者更容易閱讀程式碼。學程式的第一步就是模仿別人怎麼寫,加油!

(more...)

PHP File Host 檔案上傳專案 / PHP File Host Project

PHP File Host 檔案上傳專案 / PHP File Host Project

圖片1

最近我完成了一個用PHP做的檔案上傳專案「PHP File Host」,順便學習了PHP框架Fat-Free Framework、PHP資料庫函式庫RedBeanPHP、前端檔案上傳工具jQuery File Upload跟前端界面Bootstrap等技術。以下說明這個專案內容。

I wrote a PHP project “PHP File Host” for cross origin file uploading. In this project, I try some new technology include Fat-Free Framework, RedBeanPHP, Bootstrap and jQuery File Upload. Following is introduction of this project.


專案由來 / Project Introduction

原本我的KALS專案並不具備檔案上傳功能(其實一開始規劃時有啦,但是一直沒有實作),但最近開始有了這方面的需求。然而檔案上傳乍聽之下很簡單,但是在跨網域(Cross Origin)的情境中,卻不太容易實作。

另一方面,簡單的檔案上傳應用實作常常會有幾個問題:

  1. 實體檔案管理的問題:檔案存放在哪哩?伺服器空間足夠嗎?
  2. 檔案重複問題:如何有效率地降低檔案的使用空間?
  3. 檔案名稱問題:遇到不支援的檔案名稱編碼,存到伺服器的檔案系統時會造成亂碼的問題。

因此我想要做一個簡單的檔案上傳應用網站。這個只做一件事情:支援跨網域的檔案上傳、然後的到一個下載網址。這樣就夠了。這就是PHP File Host的由來。

專案內容 / Project

圖片2

我把最近對PHP File Host的報告彙整成為一個投影片,裡面有簡單的功能介紹:

特色 / Features

PHP File Host的特色在於:

  • 運作環境:以PHP架設,資料庫預設使用SQLite,但是不需要額外配置資料庫。
  • 跨網域檔案上傳:支援以JSONP上傳jQuery File Upload上傳
  • 避免儲存重複檔案:以MD5特徵碼來辨識檔案內容,避免儲存相同檔案。
  • 完整保留檔案名稱:以資料庫儲存檔案名稱,並由程式負責從header指定下載檔案名稱,因此不會下載到亂碼的檔名。

相關技術 / Technology

裡面主要用到幾種技術,在此我也聊一下使用這些技術的心得。

Fat-Free Framework (F3)

Fat-Free Framework (F3)是一個PHP框架。不過在講F3之前,我想先聊一下CodeIgniter。

在開發KALS時,我主要使用的PHP框架是CodeIgniter (CI)。CI大量參考Ruby on Rails的理念,大量遵守「約定優於配置」(convention over configuration)的準則。特別是對於routing功能來說,要連到指定網址就得在特定的檔案結構中撰寫相對應的PHP類別。

一開始我覺得這也不錯,大家的都能遵守約定的話,開發就能夠維持一致性。但事實上是為了這這個約定,CI限制了大量的靈活性。常常會發現要接手專案的新手要花很多時間來瞭解routing的邏輯,而且無法自由指定routing中的變數與類別也很令人覺得限制很大。最致命的就是不能支援JSONP的呼叫模式,難以跟jQuery.getJSON()搭配運用。

雖然KALS的CI被我大改之後變得可以支援JSONP,但我不覺得這是一種理想的做法。所以當我這次要開發這個專門支援跨網域檔案上傳的PHP File Host時,我就毅然決然換了另一個PHP框架。

我花了一點時間嘗試不同的PHP框架,不過後來找到了F3。這個專案特色是檔案看起來不會太複雜,特別是與龐大的CodeIgniter相比。

image

F3一些零星的功能不多,但是主要功能卻比CI好用很多。

F3的routing是由設定檔控制,寫法跟Node.js的express框架很像。這符合我們一般使用的概念:從URI追溯檔案位置。而不是像CI那樣,得先瞭解約定才能知道檔案的位置。使用配置設定來規範routing這點看起來像是違反了「約定優於配置」,但是從另一個角度來看,這也是讓「使用者」(利用URI使用系統)跟「開發者」(使用伺服器上的檔案配置)脫鉤的一種好方法。CI那種routing規範實在是太過糾結,用起來綁手綁腳的。

而F3的routing也支援分辨GET (查詢)、POST (新增)、PUT (更新)、DELETE (刪除)等REST API會使用的四種方法。不過要注意到,若針對同一URI使用GET跟POST等多種方法,最後變數只會取得使用GET這個而已。這是比較令人困擾的地方,我得再研究看看。

此外,我喜歡F3用擴增HTML標籤的方式來建立樣板,輸出的樣板能夠直接指定MIME Type為JavaScript這點也很不錯,這對JSONP支援良好,也可以輕易使用現在流行的Markdown程式語言。相較之下,CI的樣板只能說是原始人。不過F3預設限制「同源使用」(same-origin),為此得額外宣告以下header才行讓其他網站跨網域開啟F3專案:

header('X-Frame-Options: ');

CI提供了大量零星的函式(helper),讓我們能夠簡單地處理很多小東西。F3並沒有這麼多helper,但是它把很多常用的系統與環境資訊都寫在框架的系統變數裡面。習慣之後也還算好用,但我比較喜歡helper的函式形式。

在資料庫的使用上,F3的資料庫也跟CodeIgniter的Active Record一樣,都是使用ORM (Object-Relation Mapping)的方式操作資料庫。而F3多了一些NoSQL資料庫的支援,像是MongoDBJig

雖然這些ORM用起來不錯,但是我這次更想使用另一種資料庫函式庫更感興趣,那就是RedBeanPHP。

RedBeanPHP

RedBeanPHP是一個PHP資料庫函式庫,使用時只要導入它一個PHP主要檔案即可。

他在使用上跟很多ORM函式庫一樣,可以把資料表當作一個類別,裡面的一列當作是一個物件來使用。但是最大的差別在於,RedBeanPHP是不需要預先設定資料表(schemaless)的架構。

舉例來說,今天我們有一種類別叫做Book,那我們就用RedBeanPHP建立一個類別叫做「Book」的物件,然後設定其中的屬性「title」跟「author」後儲存,這樣子資料庫中就會自動幫我們把相關的table與field都設定好,連field的資料形態都會與物件屬性的形態直接相對應。

未來如果這個Book想要增加第三種屬性「price」,那就在程式中加入「price」,儲存,這樣子資料表就會多一個price的欄位。

這樣子的好處在於,我們不需要在配置程式碼之餘還要煩惱如何配置資料庫。RedBeanPHP預設採用SQLite,但也可以支援主流的關聯式資料庫,如PostgreSQL跟MySQL。

我使用RedBeanPHP在PHP File Host中儲存檔案資料,操作起來非常容易上手,而且令人驚訝地好用。

有人抱怨RedBeanPHP的資料庫查詢速度過慢,這點可能要謹慎評估。但PHP File Host少量應用看來是沒有這個問題。

Bootstrap

這次我也一併改進了前端的界面。跟以往一樣,比起重頭開始設計網頁界面,我比較偏好從既有的網頁範本開始修改。難得這次機會,我也就從知名的客戶端技術Bootstrap的範本Landing Page開始改起。

使用Bootstrap的目的包括:

  • 支援RWD (Responsive Web Design):不論電腦、平板、手機等不同螢幕大小的裝置,網頁都應該自動最佳化調整版面。這點可以靠Bootstrap的Grid system來調整。
  • 一致且美觀的元件:Bootstrap的選單、按鈕、讀取條非常好看。我還蠻喜歡它的Default、Primary、Success、Info、Warning、Danger、Link的通用分類與對應顏色。
    image
  • 豐富的圖示:不光是Bootstrap本身提供了大量的圖示(Glyphicons),Landing Page範本還用了更多元的Font Awesome圖示,基本功能操作真的是不需要額外在準備其他圖片了。

圖片1

最後完成的結果在Am I Responsive?上看起來就是這樣,開頭的圖片會按照視窗畫面去做調整,頂端選單列也會在小螢幕中自動縮成一個按鈕,成果很不錯。

雖然我老是做一些伺服器端的專案,但是作為網頁相關的程式設計師,前端界面技術自然也不能生疏。PHP File Host雖然只是一個小小的網站,但是做起來還是令我挺開心的。

jQuery File Upload

我這次也加入了jQuery File Upload來改善檔案上傳的介面。這個套件可以用簡單的方式來設定檔案上傳的功能,讓我們輕易加入以下功能:

  • 點選按鈕、選擇檔案、馬上上傳
  • 上傳進度條
  • 拖曳至指定區域上傳
  • 剪貼上傳

我很喜歡這些方便的操作,傳統點選檔案按鈕的方式實在是太過麻煩。

另一方面,我本來還蠻煩惱怎麼用jQuery File Upload來進行跨網域傳送檔案,卻意外發現jQuery File Upload使用了HTML5元件postMessage來傳輸檔案的方式,比我以前提出的JSONP跨網域檔案上傳還要好用很多,真讓我驚豔。

不過最後我要在其他專案使用jQuery File Upload設定上傳功能時,卻發現它使用的是jQuery 1.11,與KALS專案的jQuery 1.4有很大的差別。加上jQuery File Upload也要使用jQuery UI等工具,導致它與其他功能互相衝突,最後我還是放棄在KALS專案使用jQuery File Upload而使用原本的JSONP跨網域檔案上傳方式。

向DSpace致敬 / Salute to DSpace

最後也提一下PHP File Host內部檔案儲存的方式,這部分我大量地參考了DSpace保存檔案的方式。

DSpace依照檔案的MD5特徵碼作為檔案名稱與實體位置的設定,因此每個檔案都長得像是「01f7b24e629cc23e369983994d0b8fbe」。檔案的名稱、MIME Type等相關資訊則是寫在資料庫中,連同上傳者、上傳時間等操作記錄也一併分開儲存。

這樣做可以改善檔案重複儲存、避免檔案名稱編碼不支援等問題,但是檔案管理 (特別是刪除)跟下載就成為另一個技術上的重點。目前PHP File Host還沒有做的刪除功能,就只是一直擺放資料,然後以供人下載而已。

利用Base56面碼縮短網址 / Shorten URL by Base56 Encoding

喔對了,為了避免網址過長,我還特別用了Base56將數字ID以「0123456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ_-.~」等網址允許的字元進行編碼。即使檔案的編號很大,網址長度仍然不會很誇張地漲大。這種做法我也挺喜歡的。

這些大致上就是PHP File Host使用到的技術。


結語:過時的技術? / Conclusion: Outdated Technology?

剛好最近也看到一篇分析報導:「AngelList 分析:越好的公司越喜歡用 Python,越差的公司越愛用 PHP」。該分析將公司分成Okay、Good、Great三級,然後看公司使用的程式語言。

其中伺服器端PHP排行第三、客戶端Bootstrap排行第五(但是RoR我不認為是客戶端技術)、資料庫SQLite榜上無名。雖然直接看圖表起來也沒啥不好,但我現在才學這些技術,的確是比很多人慢了許多。

之後有機會的話,我想要研究伺服器端的Node.js,然後在單一頁面應用上繼續精進AngularJS (之前寫了一個批次開啟網頁的小應用,蠻好上手的)。久違地學習新的技術,真的很令人開心呢。

(more...)

Git取代分支檔案的方法 / Replace Branch Files In Git

布丁布丁吃布丁

Git取代分支檔案的方法 / Replace Branch Files In Git

2014-08-09_221445

我通常使用TotoiseGIT工具利用Git與團隊協同開發。當我想要把自己的分支清空,全部改用別人的檔案時,可以使用以下的方法來取代自己的分支。

This article describes how to use TotoiseGIT to replace a branch’s files to another branch.


分支說明 / Branch Description

在本文的例子中會使用兩個分支(Branch)。

  • Branch A:我目前所在的分支,以本地端的pudding分支為例。我不再需要該分支的所有檔案,我希望換成Branch B的檔案。
  • Branch B:目標分支,以遠端伺服器上的master為例。我希望把Branch B的檔案拿到Branch A使用。

我的方法很笨,就只是單純的替換檔案而已。以下說明做法。

Step 1. 遞交Branch A / Commit Branch A

2014-08-09_234423

由於接下來做的事情會變動到Branch A的檔案,不論任何修改,使用Git都應該養成隨時遞交(Commit)的習慣。因此在此我們也先遞交Branch A。如果沒有任何檔案有修改的話,也可以勾選左下角的「只有訊息」(Message only),並撰寫遞交的訊息(Message)即可。

Step 2. 獲取Branch B的資訊 / Fetch Branch B

我們要在TotoiseGIT中獲取Branch B的資訊。

2014-08-09_232313

做法是開啟Git同步(Git Sync)。

2014-08-09_232658

選擇要同步的Branch B。你可以按下「…」按鈕,開啟分支瀏覽器 (Browse reference),在「/remotes/kals/master」找到我們要的Branch B。按下OK確定。

2014-08-09_233004

點選「獲取」(Fetch)。

2014-08-09_233120

如果出現藍色的「Success」訊息,表示獲取成功。

Step 3. 切換成Branch B / Checkout Branch B

我們要利用TotoiseGIT的Checkout功能,把Branch A切換到Branch B去。

2014-08-09_222217 - Copy

在該Git專案的目錄底下按右鍵,選擇Switch/Checkout。

2014-08-09_231128

選擇Branch為遠端的master分支:remotes/kals/master。然後勾選建立新分支(Create New Branch)、強制切換(Force),追蹤(Track)選項保持預設。然後按下OK。

2014-08-09_231443

接著切換檔案,如果出現藍色的「Success」訊息,表示成功。

2014-08-09_233332

雖然看起來檔案沒有什麼明顯的差別,但是現在的確切換成了分支Branch B。按右鍵可以看到「Git Commit -> "master"」,表示現在的分支的確是Branch B。

Step 4. 複製Branch B的檔案到另一個資料夾 / Copy Branch B’s Files To Another Folder

2014-08-09_233723

接下來我建立一個資料夾叫做「kals-temp」,然後把原本資料夾「kals」裡面的檔案複製到「kals-temp」去。這樣我就可以先保留了Branch B的資料。

Step 5. 切換回Branch A / Checkout Branch A

2014-08-09_233945

接著我再回到「kals」資料夾,然後以類似Step 3的方法切換回Branch A,也就是本機端的pudding分支。記得勾選「強制」(Force)。

Step 6. 刪除Branch A的檔案 / Delete Branch A’s Files

2014-08-09_234410

然後我們不需要Branch A的檔案了,全選檔案之後,把它們統統刪除吧。

Step 7. 移動Branch B的檔案回到專案的資料夾 / Move Branch B’s Files Back To Project Folder

2014-08-09_234956

接著再把存放Branch B的「kals-temp」資料夾中的資料移動到專案目錄「kals」資料夾中。

image

現在Branch A裡面的檔案就會是Branch B的檔案了。

Step 8. 遞交Branch A / Commit Branch A

2014-08-09_235344 

完成取代之後,再一次遞交Branch A。由於現在這個Branch A的檔案是Branch B的檔案,因此跟Step 1遞交的檔案有很大的差異。下面的檔案變動(Changes made)會列出相當多的改變。總之先保存這次的變動,遞交吧。

這樣子我們就完成拿Branch B的檔案替換到Branch A分支裡面去了的任務了。


小結:尚未摸透Git / Conclusion: Complex Git

事實上,上述這個做法看起來很愚蠢。雖然我也寫了一個簡單的Git介紹,但老實說我對於Git仍不是這麼的熟悉。分支之間檔案交換的方法還有很多種,這篇是我找到最可行的一種方式。

2014-08-10_000547

一般的做法都是教你使用「比較跟前面版本的差異」(Diff with previous version)。可是這種做法中,Branch A中有、Branch B中沒有的檔案,依然還會存在在替換後的Branch A中。特別是當Branch B的檔案名稱修改時,就會造成Branch A替換後出現了兩個不同名稱檔案、但是檔案內容卻一樣的問題。

2014-08-10_001020

不過我後來在想,是不是應該要用Rebase這個工具來取代分支檔案呢?這點我就要繼續再研究看看了。希望熟悉Git的朋友能給我一些建議吧。

(more...)

適合程式碼的等寬字型 M+ 1m / The Monospaced Font for Programming: M+ 1m

布丁布丁吃布丁

適合程式碼的等寬字型 M+ 1m / The Monospaced Font for Programming: M+ 1m

image_thumb

日前在Linuxeden上看到了關於「最佳编程字体:M+」的介紹,不過原本M+ FONTS網站中並沒有提供Windows的安裝方法,後來我是在FONT SQUIRREL找到可安裝的「M+ 1m」字形檔案。其中我覺得「M+ 1m medium」看起來最順眼,在此跟大家分享。

Based on Tom MacWright's recommend , I try to use M+ font for programming. The monospaced fonts in M+ fonts is “M+ 1m”. You can download M+ 1m from Font Squirrel.


等寬字型與程式寫作 / Monospaced Font and Programming

寫程式的時候大多是在跟英文奮戰,而其中字型扮演著非常重要的角色。英文字型不僅要清晰、容易辨識,更重要的是要讓每一個字都維持在相同的寬度。

舉例來說,傳統文件上常用的Times New Roman是一種比例字型(Proportional Font),套用到XML檔案的結果:

image_thumb2

這篇要介紹的M+ 1m則是等寬字型(Monospaced Font),套用到XML會長得像這樣子:

image_thumb3

你可以發現到這兩種字型有很大的差別。Times New Roman看起來必要美觀、自然,但是因為字卻像是纏在一起一樣,不太容易閱讀;M+ 1m看起來則是清楚許多,因為每個字跟每個字之間都保持寬度,所以也很容易對照上下不同行之間的程式碼。

跟比例字型常用與一般正規單字不同,程式碼的英文字通常會以特殊定義的字句與符號組成,因此閱讀程式碼的時候並不是像一般文章是以單字在閱讀,而是要一個一個字的閱讀。這也就是為什麼程式碼的字型不應該採用Times New Roman這種比例字型,而應該採用像是M+ 1m這種等寬字型。

而原本推薦網頁選用M+的理由在於M+每一個字都壓縮到很小的寬度。同樣寬度的螢幕中,使用M+可以顯示更多的文字。

以下是另一種等寬字體「Simplified Arabic Fixed」的顯示結果,這種字體的寬度比較大,讀起來比較可以喘口氣,但是可顯示的文字也就比較少了。

image_thumb6


M+ 1m字型下載與安裝 / Download and Install M+ 1m Fonts

介紹M+字型的網頁中提供了所有M+系列字型檔案(ttf, True Type)的ZIP壓縮檔,下載網址是:

不過其中僅有M+ 1m系列才是我們要的等寬字型,你也可以在Font Squirrel找到並下載M+ 1m:

下載並解壓縮ZIP檔案(可以使用7z解壓縮)之後,可以看到許多.ttf的字型檔案。Windows安裝ttf字型檔案的方法請看微軟的說明

M+ 1m中還有許多不同寬度的字型可供選擇,依照瘦到胖共有5種字型,個別是「M+ 1m thin」、「M+ 1m light」、「M+ 1m regular」、「M+ 1m medium」、「M+ 1m bold」,差別請看下圖:

image_thumb5

其中我個人覺得「mplus-1m-medium.ttf」看起來比較順眼、辨識度充足,目前我先用這個字型來寫程式看看。

M+ 1m中文支援不佳 / M+ 1m Doesn’t Support All Chinese

但是M+ 1m主要適用於英文、日文跟部分漢字上,套用在中文字上面會有很多缺漏的地方,如下圖中的「檔」、「缺點」、「沒」。

image_thumb7

因此M+ 1m到底好用與否,我還要用一段時間再來評估看看。

(more...)

搜尋引擎中的使用者行為與注意力建模 / Modeling User Behavior and Attention in Search

搜尋引擎中的使用者行為與注意力建模 / Modeling User Behavior and Attention in Search

image

這是一篇課堂中的博士論文閱讀筆記。作者在微軟Bing搜尋引擎上,以鼠標(cursor)跟眼動(eye tracking)來蒐集使用者的資訊,並建立以鼠標預測眼動的演算法以及相關應用研究。

This is a course reading note. This dissertation uses mouse cursor and eye tracking to collect user behavior in Bing web search engine, and using cursor movement to infer users’ visual attention.


書目 / Bibliography

Huang, J. (2013). Modeling User Behavior and Attention in Search (Ph.D. Dissertation). University of Washington. Retrieved from https://digital.lib.washington.edu/xmlui/handle/1773/24188

摘要 / Abstract

  • 在網際網路檢索中,查詢語句跟滑鼠點擊記錄是很容易保存,可是卻很難藉由點擊記錄來偵測使用者的行為。
  • 搜尋引擎從點擊資料取得的訊息有所侷限,所以從相關環境、鼠標(cursor)移動的探勘、滑鼠停留(hovering)以及捲動行為(scrolling)等資訊越來越重要。
  • 這篇博士論文(dissertation)發明了一種遠端蒐集大量使用者的鼠標移動互動資訊,用以幫助研究者了解人們基本的行為,並且改進搜尋引擎。
  • 重要的是,鼠標活動探勘可以藉由最新技術(state-of-the-art)來評分與排序搜尋結果,並且模擬使用者注視所在位置而不需使用眼動儀(eye-tracking)。
  • 鼠標移動的敘述性分析顯示使用者在搜尋時是如何移動他們的鼠標,我們可以從中了解當使用者放棄搜尋時的一些相關的訊息與可供解釋的理由。
  • 使用者模型可以用來推論頁面上的視覺注意力的移動,用以辨識哪些內容是使用者在看的,並可用來計算搜尋結果的相關度與吸引力給使用者。
  • 這種隱性回饋(implicit feedback)讓搜尋引擎可以了解排版與內容呈現上的資訊是否合宜,或藉此用來改善搜尋結果。
  • 這篇博士論文會依序描述以下幾篇論文的內容:
    「網路環境下使用者滑鼠鼠標互動資訊高效率擷取法」(users’ mouse cursor interactions
    can be collected effciently on the Web)、「了解使用者搜尋行為」(used to understand users’ search behaviors)、「對網路搜尋引擎設計的用處」(can be useful in the design of Web search engines)。

筆記下載 / Note Download

image

最重要的是這個用滑鼠鼠標移動路徑推論眼動路徑的演算法,我們就稍微聊一下這個演算法好了。這演算法是用滑鼠鼠標的X軸,加上幾個參數的調整之後,去預測眼動位置的X軸。同樣的也可以用鼠標Y軸去預測眼動Y軸。各參數的意義如下:

  • gx:預測眼動X軸的位置
  • cx:鼠標原有的X軸位置
  • td:網頁內停留的時間,d是指dwell
  • tm:鼠標停止到移動的時間
  • fx:根據下一個鼠標位置來進行調整(也就是眼睛會更快移動到鼠標預定移動的位置的意思)

不過我不是很懂為什麼只是加上log()取對數之後的td跟tm,這樣鼠標修正之後預測的眼動位置,不是只會持續往右偏而已嗎?

儘管對於演算法設計上還是覺得困惑,不過作者取這些參數作為參考的過程非常嚴謹,很值得一看喔!

(more...)

JavaScript的字串壓縮函式庫:lz-string

JavaScript的字串壓縮函式庫:lz-string

image

在JavaScript應用程式開發中,我們時常使用AJAX傳送字串資料給伺服器或儲存在本機瀏覽器。當資料量過大時,可以考慮使用JavaScript字串壓縮函式庫lz-string來大幅度降低字串資料的體積。

In JavaScript application, we usually send string data to server by AJAX or store string in local web storage. If string data size is over the storage size limit, we could use a JavaScript string compress library “lz-string” to reduce stored string size.


適用情境 / Problem Context

壓縮字串資料量 / Compress String Size

最近我在研究改進KALS系統效率的方法。KALS在使用JavaScript計算瀏覽器上的標註位置時會耗費大量時間,如果能將運算結果以快取的形式儲存起來,那麼下次直接載入快取將可以節省大量的時間。

可是問題是瀏覽器端的儲存空間不大,cookie只有4KLocal Web Stroage(HTML5的新特性)只有5MB、Chrome Plugin不考慮。PHP的session一次最多可以存取128MB,但是要跟伺服器存取就很沒效率。

這時候就很適合使用lz-string壓縮字串,將資料量大幅縮小之後再儲存了。雖然就長期來看,如果運算結果變多了話,即使壓縮之後還是會有超過儲存上限的時候,不過那就是另外的議題了。

資料加密 / Encryption

image

另一種適用情況是加密資料。對網頁開發者或是初級駭客來說,有很多方式可以看到儲存在Cookie、Session、Local Strorage的資料,還有擷取與遠端伺服器溝通的資料(當然,這也包含了密碼)。藉由分析這些資料,我們可以輕易地了解遠端系統的資料架構。接下來就可以無視客戶端的操作介面與驗證程序,直接傳送我們想要的資料給伺服器。

以前在Facebook上的一款遊戲WarStorm就是採用明碼以XML跟伺服器傳送資料,讓許多玩家介入製作取代原本遊戲介面的機器人,降低手動遊玩所耗費的時間。這件事情讓我印象深刻,也對我後來進行程式設計的安全性上多了份考量。WarStorm後來將XML的資料全部加密,阻止玩家製作的機器人參與遊戲,不過卻造成遊玩人數大量流失,過不久就關閉了整個遊戲了。

話說回來,資料加密的方式其實還蠻多種的。除了單純到稱不上加密的escape()、encodeURI()、encodeURIComponent()自然不說,加密時常見的是md5演算法,而這個lz-stirng儘管效率較差,但是卻兼顧了壓縮與加密兩種特性。

總之,使用lz-string字串壓縮函式庫可以帶來的好處有兩個:

  1. 壓縮資料量
  2. 加密資料

缺點是需要耗費額外的運算時間,但這個缺點在可以節省資料傳輸與儲存等好處相較之下就顯得不是這麼重要了。

LZW演算法 / LZW Algorithm

lz-stirng使用的壓縮演算法是基於LZW。根據Wikipedia對LZW的介紹如下:

LZWLempel-Ziv-Welch)是Abraham LempelJacob ZivTerry Welch提出的一種無損數據壓縮演算法。它在1984年由Terry Welch改良Abraham LempelJacob Ziv在1978年發表的LZ78的版本而來。這種演算法的設計著重在實現的速度,由於它並沒有對數據做任何分析,所以並不一定是最好的演算法(參考LZMALZ77)。

lz-string再根據JavaScript的使用情境作最佳化,最後完成了這個函式庫。在運作效率上,lz-string跟LZMA作了一些比較,在資料長短不同的測試案例下,壓縮率與運算時間皆有勝有負。不過我不是很在意這些細節就是,能用就好了XD

使用lz-string / lz-string Usage

使用方式很簡單:1. 引用lz-string;2. 使用compress壓縮資料;3. 使用decompress解壓縮資料,以下是引用lz-string的使用介紹

  1. 下載lz-string的JavaScript檔案。作者的主要存放處是GitHub。我備份了一份最新版本的lz-string-1.3.3-min.js到Box.net
  2. 在網頁中引用lz-string。注意以下紅字的部份,請寫入lz-string的正確網址
    <script language="javascript" src="lz-string.js"></script>
  3. 接下來就能夠在JavaScript中使用lz-string韓式庫。主要用法是壓縮compress跟解壓縮decompress兩種:
    var string = "This is my compression test.";
    alert("Size of sample is: " + string.length);
    var compressed = LZString.compress(string);
    alert("Size of compressed sample is: " + compressed.length);
    string = LZString.decompress(compressed);
    alert("Sample is: " + string);

有興趣的人可以先玩玩看lz-string的線上展示頁面

lz-string是針對localStorage最佳化,對於傳送資料給遠端伺服器來說就不是這麼合適。這時候要改用compressToBase64()與decompressFromBase64()。不過作者也提示了這兩種方法實際上並沒有進行壓縮,只是編碼而已。使用上可能還需要多多注意一下。


下一步 / Next

我嘗試在系統中使用lz-string壓縮資料,並驚嘆於lz-string的壓縮成果,所以才想要寫一篇來介紹一下這好用的壓縮資料庫。

在目前為止,我使用lz-string主要都是用於將資料儲存在localStorage。但是當資料量大到連lz-string壓縮之後都無法儲存的話,我就得轉個方向來思考了。下一步我可能會嘗試將快取資料儲存在伺服器端,並以lz-string壓縮資料以節省網路傳輸量。如果有什麼進度再來跟大家分享。

(more...)

解決WordPress User-Avatar外掛無法連結的問題 / Solution for WordPress’s Plugin User-Avatar Error

解決WordPress User-Avatar外掛無法連結的問題 / Solution for WordPress’s Plugin User-Avatar Error

image

最近我將WordPress掛載NFS之後,WordPress的外掛User Avatar就無法順利運作。原因是因為timthumb縮圖程式無法寫入暫存檔案,修改程式碼之就能解決問題。

Recently, I try to integrate NFS with WordPress’s upload directory, and then the plugin User-Avatar got broken. This problem is due to thumb program “user-avatar-pic.php” could not write lock files. I modified this program to solve it.


問題敘述:縮圖程式錯誤訊息 / Problem Description: TimThumb Error

WordPress與外掛User-Avatar / WordPress’s Pluging User-Avatar

screenshot-1

我目前使用的WordPress與外掛User-Avatar版本資訊如下:

User Avatar是允許讓使用者自行上傳大頭照的外掛,簡單好用。

uploads資料夾掛載到NFS / Mount “uploads” Directory to NFS

最近我將WordPress存放附件檔案的資料夾uploads改掛載到NFS底下。具體來說是資料夾路徑是:

[WordPress]/wp-content/uploads

image

圖片無法讀取 / Could Not Load Image

掛載之後,附件大多都能正常下載,可是卻發現圖片無法讀取的問題。

2014-03-12_000853

上圖紅框的部份可以看到,應該出現作者大頭像的地方卻沒有顯示了,非常奇怪。

image

直接打開網址之後,就發生了錯誤訊息:

A TimThumb error has occured

The following error(s) occured:
  • Could not get a lock for writing.

Query String : src=http://********/wp-content/uploads/avatars/46/1371804156-bpfull.jpg&w=75&id=46&random=1392976007
TimThumb version : 2.8.10

問題剖析 / Problem Analysis

簡單來說,是程式碼中有些段落發生了無法順利寫入的問題。發生錯誤的程式碼是外掛User-Avatar的user-avatar-pic.php,檔案路徑如下:

[WordPress]/wp-content/plugins/user-avatar/user-avatar-pic.php

根據錯誤訊息「Could not get a lock for writing.」,我們可以找到發生錯誤的程式碼,以及回溯到前面開啟檔案的相關程式:

$lockFile = $this->cachefile . '.lock';
$fh = fopen($lockFile, 'w');
if(! $fh){
    return $this->error("Could not open the lockfile for writing an image.");
}
if(flock($fh, LOCK_EX)){
    @unlink($this->cachefile); //rename generally overwrites, but doing this in case of platform specific quirks. File might not exist yet.
    rename($tempfile4, $this->cachefile);
    flock($fh, LOCK_UN);
    fclose($fh);
    @unlink($lockFile);
} else {
    fclose($fh);
    @unlink($lockFile);
    @unlink($tempfile4);
    return $this->error("Could not get a lock for writing.");
}

注意紅字的第一行。這一行是指定寫入檔案的路徑,顯然地目前這個路徑設定是不可寫入的。要確保暫存檔能夠正常寫入,一般來說都是寫在暫存目錄底下。PHP取得暫存目錄並在之中產生暫存檔案的作法是用tempnam(sys_get_temp_dir(), 'FOO'),因此程式碼應該替換掉第一行變成:

//$lockFile = $this->cachefile . '.lock';
$lockFile = tempnam(sys_get_temp_dir(), 'timthumb') . '.lock';

這樣子就能夠讓網頁正常顯示了。

2014-03-12_003035


解決方案:替換user-avatar-pic.php / Solution: Replace file “user-avatar-pic.php”

以下講述簡單的作法:

  1. 下載user-avatar-pic.php (我已經上傳到GitHub)
  2. 替換掉原本檔案,路徑是「[WordPress]/wp-content/plugins/user-avatar/user-avatar-pic.php

這樣就完成了。

(more...)