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

Octopress 的後端就是自己的電腦,有多台電腦時需要在其他電腦再建立 Octopress 的撰寫環境,並且拿 Github 上面的 repos 下來繼續寫。

安裝環境

基本環境:Git for WindowsRubyInstaller 1.9.3Ruby Development kit。如果用到 code highlight,要裝 Python 2,否則 rake generate 會生出空白頁。安裝完 Ruby 跟 Python 要在環境變數 PATH 加入 Ruby 的 bin 資料夾路徑以及 Python 的安裝路徑,如 C:\Ruby193\binC:\Python27

Clone repository

1
2
3
4
$ git clone -b source https://github.com/[username]/[username].github.io octopress

$ cd octopress
$ git clone https://github.com/[username]/[username].github.io _deploy

Octopress 將 master branch 放在 _deploy/

Rake installation and configuration

1
2
3
$ gem install bundler
$ bundle install
$ rake setup_github_pages

最後一個指令會要求輸入 Github 的 repository URL。

Pull repository

有多台電腦編輯時,開始前要記得將 local repository 更新到最新。

1
2
3
$ git pull origin source
$ cd _deploy
$ git pull origin master

Ref

用想放空的假期把寫在 Dokuwiki 上的筆記搬到 Octopress 來。原本因為可以自己任意編排,加上寫給自己看的筆記是用 Dokuwiki,就繼續沿用 Dokuwiki。漸漸發現要找資料的時候都直接用搜尋功能,沒怎麼在用原本的分類頁。越來越覺得那樣編排可能沒有必要,似乎有搜尋跟標籤就可以了。

好一陣子前 survey 過 Octopress,當時好像因為不習慣網頁上沒有管理的功能,暫且不用。可能最近有點轉性,覺得網頁上沒管理功能好像也還好。本來就喜歡用 Notepad++ 寫東西,配合 Git Bash 讓我覺得在 Windows 上用 command line 沒那麼卡,再加上有 Github 可以放,乾脆搬來了。

目前讓我比較困擾的是這 blog 的 repos 只有在我的桌機上,所以只能從桌機寫,之後要看怎麼在另一台電腦上建立同樣的環境。這是網頁不直接提供管理功能的缺點,可是我在用的電腦就那幾台,也不太可能用手機寫這類的文章,只要幾個環境架起來之後應該還好。

這 blog 主要拿來放 Computer Science 的筆記,之後慢慢寫些小程式應該也會把相關的東西放上來吧。

一邊搬筆記一邊稍微看一下,真心覺得我有些用句很怪,看起來有點像英文文法的中文。XD

清除特定頁面 cache

在該頁面網址後面加上

1
?purge=true

clean cache script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash

cleanup() {
# $1 ... full path to data directory of wiki
# $2 ... number of days after which old files are to be removed

# purge files older than $2 days from attic and media_attic (old revisions)
find "$1"/{media_,}attic/ -type f -mtime +$2 -print0 | xargs -0r rm -f

# remove stale lock files (files which are 1-2 days old)
find "$1"/locks/ -name '*.lock' -type f -mtime +1 -print0 | xargs -0r rm -f

# remove empty directories
find "$1"/{attic,cache,index,locks,media,media_attic,media_meta,meta,pages,tmp}/ \
-mindepth 1 -type d -empty -print0 | xargs -0r rmdir

# remove files older than $2 days from the cache
find "$1"/cache/?/ -type f -mtime +$2 -print0 | xargs -0r rm -f
}

使用方式:

1
$ ./cleanwiki.sh <path of dokuwiki>/data <天數>

Ref

Eclipse 編輯區預設背景是白色的,對於用慣 vim、console 這種底都黑黑的我來說實在是有點不舒服,理所當然的就要來找找 theme。

發現一個 plugin:Eclipse Color Themes

官網:http://eclipsecolorthemes.org/

update site:http://eclipse-color-theme.github.com/update/

Help → Install New Software 將 update site 加進去,就可以選 Eclipse Color Themes 來裝。

theme 可以到官網抓 EPF 格式,File → Import → Preference 套用。

用 github 可以做到類似遠端備份的功能,類似 svn 的中央 server(但不一樣)。每個 client 在本地端都有完整的 git repository,在 local 就可以做 commit 等操作,而非一定要連到 github。

先到 Github 申請帳號。github 提供免費帳號無上限的 public repository,如果要私人的 Repository 就要付錢囉。

以下操作都是在 Linux 上,在 Windows 上沒特別研究。

安裝 git

看是在哪種 Linux distribution 上,通常可以直接裝套件(Fedora 用 yum,Ubuntu 用 apt,Gentoo 用 emerge,可參考這裡)。

設定 ssh key

為了方便跟 github 傳輸資料,要設 ssh 的 public/private key:

1
$ ssh-keygen -t rsa

產生一組 key,預設放在 ~/.ssh/

Enter passphrase 是每次存取這把 key 時要輸入的密碼,有輸入的話每次用 git 指令 access github 都要打一次密碼。

到 github Account Setting 中的 SSH KEYS 增加 key,把剛產生的 public key(預設是 ~/.ssh/id_rsa.pub)貼上去。

在 github 新增 repository

照著網頁按,幾乎只要輸入 repository name 就可以了。

將現有的 git repository 上傳(push)至 github

1
2
3
$ cd mygit
$ git remote add origin git@github.com:[userid]/[rep's name].git
$ git push origin master

[userid] 是 github 上的帳號。[rep’s name] 是 repository name。

下載(clone)github 上的 repository 到 local 端

初次下載,在 Git 稱為 clone。

抓自己或其他人的皆可。

1
2
$ git clone git@github.com:[userid]/[rep's name].git [local dir name]
$ git clone https://github.com/[userid]/[rep's name].git [local dir name]

使用兩種不同 protocol clone。

將自己的修改傳上 github

1
$ git push

將 github 上較新的 code 抓下來

1
$ git pull

Ref