簡單來說,我變心了。

Octopress 隨著文章數越多 rake generate 似乎有越來越慢的趨勢,稍微查一下發現雖然有 generate 加速的方法,但遇到 deploy 還是會慢,索性跳到比較快的 Hexo。

Hexo 也可以配合 Github page 使用。跟 Octopress 的不同的是 Hexo 把 post 跟 draft 分開,還不錯。

從 Octopress 轉到 Hexo 不難,先安裝好 Hexo,再將原本 _posts/ 底下的檔案搬過來便是。Hexo 不像 Octopress 將 source 開成另一個 branch 可以 push 到 repos 上,為了備份跟遠端傳輸 source 檔,我把整個 Hexo 資料夾放在 Dropbox 上。理論上電腦有裝 node.js 跟 Git 的環境就可以直接寫。

偶爾改爛 theme,放在 Dropbox 上就不知道自己改了什麼、改不回去,試驗開另一個 repos 放 source。

新增頁面

1
$ hexo new page <name>

在導覽列加新的頁面要修改 themes/<theme name>/_config.yml,在 menu 底下加,例如:

1
2
3
4
5
menu:
Home: /
Archives: /archives
Toy: /toy
About: /about

這個設定因 theme 而異,以上設定是 default theme landscape 的。

Custom Domain Name

source/ 底下增加一檔案 CNAME,內容為自訂 domain name,如 www.cjwind.idv.tw

Theme

改用 nut

修改 Deploy git repos

除了修改 _config.ymldeployrepo 的設定外,也要刪除 .deploy/,才會套用新的 repos 設定。

Ref

發現兩個問題:Tapir 不支援中文、換過 permalink 會怪怪的。

2014/4/28 updated


Octopress 預設的 search 功能是 Google search,一搜尋就會導到 Google 的頁面。不太喜歡這種方式,把 search 換成 Tapir,可以在自己站內找。

Tapir 的原理是它每 15 分鐘會掃一次網站的 RSS,再透過他們的 API 達到以 RSS 為 base 的搜尋功能。要注意的是,沒在 RSS 中的文章是不會被 search 到的。

修改方式

先到 Tapir 輸入 RSS feed 跟 mail,會得到一組 key,這裡只需要用到 public key。

Octopress Tapir plugin 下載所需檔案並放到對應資料夾。

  • source/search.html
  • source/javascripts/jquery_tapir.js
  • source/images/loading.gif

修改 _config.yml

  • 註解掉 simple_search
  • 加入 tapir_token: [your public key from Tapir]

修改 source/_includes/navigation.html,在 include custom/navigation.html 前面加入:

{% if site.tapir_token %}
{% endif %}

修改 source/atom.xml,拿掉 for post in site.posts limit: 20limit: 20,讓所有 post 都會出現在 RSS feed 。另一個可能的做法是複製 source/atom.xmlsource/atomForSearch.xmlrake generate 後將這個 XML 的 URL 丟給 Tapir 當作 search 的 base。

Ref

掛蛋啦哈哈哈哈哈哈哈哈…….Orz…..

早上八點半爬起來,弄一弄我只剩十分鐘清醒,所以一開始整個沒醒。看了 A 的題目,十幾二十分鐘後,中華電信來弄網路跟 MOD,弄完就十點了,我實在有點想跟他說 MOD 放著不用裝了,依照我們的習性大概也沒人會去開來看。網路弄完,醒了但也只剩 1.5 小時。

稍微想一下 A,只想到計算 0 跟 1 的個數可以判斷是不是 possible,但是計算次數的部分就還沒想到。後來去看 B,整個覺得我好久沒看這種東西,沒想清楚題目,自以為邊只有三種情況,寫了條件很多的 BFS,寫完 WA 到天邊去,反正掛蛋也沒有 penalty 問題…..(欸)

平常沒在練習,掛蛋也不是什麼很稀奇的事。下一場 1B 的時間對我來說太爛了(我是作息時間不太工程師的工程師),只好 1C 再戰。

把多個 .gpx 檔案接成一個檔的小工具,目前只支援從 Endomondo 抓來的 gpx 檔,不確定這是不是 gpx 的固定格式。UI 很醜我真的知道,拜託不要要求工程師的美感。

使用方式:Add 新增要合併的 gpx 檔案,Del 刪掉。Up 跟 Down 排列 gpx 檔案的順序,結果檔中的內容會以檔案列表的順序排列。

記錄一下寫這小玩具學到的東西:

  • Parse XML by C++ with Pugixml
  • Setup Qt develop environment with Qt Creator in Windows
  • Usage of release in Github
  • Deploy Qt application in Windows

這篇是看 Qt4 Container 相關網頁的筆記,包含三種 Sequential Container:QVector、QList、QLinkedList。PS:Qt 已經出到 5。(2014/4/21)

Read more »

libcurl 是處理收送網路 request、response 的 library,可用來收送 HTTP 的 request 及 response。

libcurl 收到 response 時會 call callback function,由 callback function 處理收到的資料。callback function 可自行撰寫,其 prototype 如下:

1
size_t func(void *ptr, size_t size, size_t nmemb, void *userdata)
  • ptr 指向收到的資料
  • nmemb 為收到資料的大小
  • userdata 可自己定義,我拿它當 return value。

libcurl 的 callback function 分成處理 header 跟 data,用 curl_easy_setopt() 指定處理的 callback function。如果沒有指定 callback function,預設上 data 會被印出來,header 則不處理。

Usage

1. Initialize

1
2
3
#include <curl/curl.h>

CURL* curl = curl_easy_init();

2. Set HTTP header data

設 HTTP header,如指定 Content-type:

1
2
3
struct curl_slist* headers;
memset(header, 0, sizeof(headers));
headers = curl_slist_append(headers, "Content-type: application/json");

call curl_slist_append() 會不斷加資訊到 headers 這個資料結構中。

3. Set options

1
2
3
4
5
6
7
8
9
10
curl_easy_setopt(curl, CURLOPT_POST, 1);                // 以 POST 傳送資料
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // 指定 header
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // 指定 url
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata); // 指定 data,將 postdata 當作 POST data 傳給 server

curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, parseHeader); // 指定處理 HTTP header 的 callback function 為 parseHeader
curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &rescode); // 指定 parseHeader 的 userdata

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, getResponse); // 指定處理 data 的 callback function 為 getResponse
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); // 指定 getResponse 的 userdata

4. 傳送 request

1
curl_easy_perform(curl);

以 blocking 的方式傳送 request。

5. clean up

1
2
curl_slist_free_all(headers);	// 清掉 headers 裡的東西
curl_easy_cleanup(curl);
Read more »

官方網站:http://phpexcel.codeplex.com/

用來讀取、產生 Excel 的 PHP class。

下載回來後解壓縮 Classes,在要使用的 PHP 檔案中 include。

產生 Excel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// include PHPExcel 相關檔案
include("includes/PHPExcel.php");
include("includes/PHPExcel/Writer/Excel2007.php"); // Excel 2007 格式
include("includes/PHPExcel/IOFactory.php"); // 放置圖片

error_reporting(E_ALL);

$objPHPExcel = new PHPExcel();
$objPHPExcel->setActiveSheetIndex(0);

// 指定儲存格的內容,中文要用 iconv() 轉換,不然會顯示不出來
$objPHPExcel->getActiveSheet()->setCellValue('A1', iconv("big5", "utf-8", "測試"));

// 也可以用指定 column 跟 row 的方式設定內容,column 是從 0 開始編號,row 是從 1 開始編號
$objPHPExcel->getActiveSheet()->setCellValueByColumnAndRow(0, 1, iconv('big5', 'utf-8', '哈囉'));

// 自動設定欄寬
$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setAutoSize(true);

// 在 Excel 中放圖片
$objDrawing = new PHPExcel_Worksheet_Drawing();
$objDrawing->setName('cat'); // 圖片名稱
$objDrawing->setDescription('cat'); // 圖片描述
$objDrawing->setPath('cat.jpg'); // 圖片檔案路徑,支援JPG及PNG格式
$objDrawing->setWidth(1000); // 圖片寬
$objDrawing->setCoordinates("A2"); // 圖片放置的儲存格位置
$objDrawing->setOffsetX(30); // X偏移量
$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());

// 儲存 Excel 檔,這裡會存成 .xlsx 格式
$objWriter = new PHPExcel_Writer_Excel2007($objPHPExcel);
$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); // Excel 檔案路徑

讀取 Excel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
include('includes/PHPExcel/IOFactory.php');

// read excel
$filename = "test.xlsx";
$objPHPExcel = PHPExcel_IOFactory::createReader('Excel5'); // 與舊版相容
$objPHPExcel = PHPExcel_IOFactory::load($filename);
$objWorksheet = $objPHPExcel->getSheet(0); // 讀取第一個工作表
$data = array();

// 用 iterator 依序讀取 rows, columns, 並將資料存到 $data
foreach ( $objWorksheet->getRowIterator() as $rowidx => $row ) {
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false); // 讀入整行, 若為空回傳 null
foreach ( $cellIterator as $cellidx => $cell ) {
$data[$rowidx][$cellidx] = $cell->getValue();
}
}

列出設計一新 class 時需要注意的問題跟與其相關的東西:

  • 真的需要一個新 class 嗎?(我覺得這最重要)

    使用既有 class 是否能達成需求?

  • 如何產生及銷毀新 class 的 object?

    與 constructor、destructor、new、new[]、delete、delete[] 有關

  • 物件的 initialization 跟 assignment 有何區別?

    與 constructor、assignment operator 的行為有關

  • 如果以 pass by value 的方式傳遞新 class 的 object 時是什麼意思?

    與 copy constructor 有關

  • 新 class 的合法值為何?

    需維護的條件、member function(如 constructor、assignment operator、setter)所做的錯誤檢查、exception、exception specification

  • 新 class 是否繼承某個繼承架構?

    base class 的 non-virtual 及 virtual function

    virtual distructor

  • 新 class 需要那些轉型?

    轉型 function

  • 那些 operator、function 對此 class 來說是合法的?

    牽涉到要宣告那些 function?是否為 member?

  • 不想使用哪些 compiler 會自動生成的 function(如 constructor)?

    如果不使用,將它宣告成 private。

  • 誰可以使用新 class 的 memeber?

    public、protected、private、friend

  • 新 class 的 undeclared interface 是?

  • 這個 class 需要多 general?

    class template

Ref

  • 《Effective C++》item 19

供 C++ 使用的 MySQL library。

Installation

in Fedora

1
$ sudo yum install mysql mysql-devel mysql++-devel

in Ubuntu

1
$ sudo apt-get install libmysql++-dev

How to use

include file and namespace

1
2
3
#include <mysql++.h>

using namespace mysqlpp;

compile

1
g++ -o <obj file> <source file> -I/usr/include/mysql++ -I/usr/include/mysql -lmysqlpp -lmysqlclient
Read more »

昨天晚上在慵懶的狀態下寫今年 Google Code Jam 資格賽。

A 跟 B 很簡單,A 就照著算一下,B 簡單 Greedy,看到過 C 的比例比較低先跳過,看 D 覺得要想一下,可是已經在想睡覺……丟了一次很爛的 algo 上去果然 WA,放棄收工了,只要 B 的 large input 有對也是會過,阿要是沒對就 GG 了!XD

遙想我每次玩 Code Jam 都只有過資格賽……Orz……看今年會不會有鬥志一點,至少兩次時間可以參加的 Round 1 都去玩一下。

貼這種 code 出來好像在丟人現眼

簡單針對 code 檢討一下好了,algo 沒什麼好檢討的,因為寫的兩題太簡單。

  1. 跟 C++ IO 不熟,才會出現很明顯的 copy。還為了 output 七位小數而混雜 printf(),因為我不會調 C++ 的 output format。比賽的時候懶得查直接用最熟的比較快
  2. 變數名稱亂取,不過算了比賽程式不要計較太多 XD