Sunday, September 14, 2008

How to build a Web Host on your computer

Here is the procedure for setting up a web host at home and have PHP/MySQL ready with php_curl library support.

Step 1) Download MoWeS

Goto http://www.chsoftware.net/en/useware/mowes/mowes.htm
Choose "Download" from the left menu.
Click "No thanks, take me to the download"
Click "I Do not have a MoWeS Protable II... "
When choosing the component, check
Apache2
MySQL5
PHP5
PHPMyAdmin
and press "Download now".

Notes: I do not know why people keep asking if they should download the SE version of the modules. Just follow exactly the component named above.

Step 2) Extract & start up
Extract the content to C:\mowes. At this moment you should have mowes.exe as C:\mowes\mowes.exe
Run mowes.exe, it prompt you for setup those components you have chosen.
Start the installation and press "OK" several times.
The webhost will start automatically and your browser will start and goto the hosted website.

Step 3) Get ready with CURL library
In the MoWes Portable II windows, press options.
ON: Start Apache and MySQL automatically when MoWeS starts
ON: Hide the Apache window
OFF: Delete xx logfiles after stooping
OFF: Start Webbrowser
OFF: Start External App
other setting left as default.
Press Accept and OK
Press "End" in your Mowes window. The webhost will be down.

Goto C:\mowes\php5, copy the 2 files:
libeay32.dll
ssleay32.dll
to your windows system32 folder ( usually c:\windows\system32).

Open C:\mowes\php5\php.ini in text editor. Modify the following lines:
205:
implicit_flush = On
321:
max_execution_time = 120
674:
extension=php_curl.dll
696:
extension=php_openssl.dll
727:
date.timezone = Asia/Hong_Kong
Save and exit text editor.

Notes: Some of the changes include removal of a ';' (semi-colon). Be really really careful and the line should be completely like the one written above. No exception for any of the above lines, each line contain changes to be made.

Notes 2: for line 727, it specifies the default time zone so that any time displayed will be under that time zone. If you are not from Hong Kong, take a look at HERE for more cities of your choice.

Step 4) Testing
Start mowes.exe. The webhost will be ready.
Put any file C:\mowes\www , for example a.zip
Open your web browser, URL = http://localhost/a.zip
If successful, you will be prompted to download a.zip
Put mingpao.php to C:\mowes\www
If successful, you will be reading today's mingpao

Notes: mingpao.php is the ultimate testing script for your configuration. It can be obtained here.

Friday, May 23, 2008

BlackBerry Bold 9000 Hands on

As some of you may know, I work for a company that concentrate on developing Input Method for various platform. I am the one responsible for development on Blackberry and today I received the newest product from RIM, the Bold 9000.

If you have ever played with any of the 8xxx series and now holding a brandnew 9000, you may be impressed by its new interface, new functionality and new plastic/metal case.

However, to make things short, I conclude with one sentence: It looks well, it plays badly.

If you are looking for tech details for Bold, read CNET news, or if you want some screenshot, visit crackberry. The one on my hands looks exactly the same. And it's awesome. (Don't compare it with iPhone though)

As a Chinese Input Method developer, what I concern most, as any Chinese would do, is the ability to display and enter Chinese characters. When comparing with the Font on Pearl, which looks like Chinese Char in CWin31 or just eTen, the ones on Bold are clean and clear, and are as good as those on newest Windows Mobile. Bold support HKSCS natively, so there should be no problem reading Hong Kong News. Moreover, Bold has built-in support for multi-lingual User Interface. One can choose its favorite Interface language right from SetupWizard.

The true power of BB handheld relied on its ability on messaging. Actually I didn't see many Hong Kong Blackberry users typing in Chinese (I see users on MTR mostly). Maybe it's because its poor support on Chinese Char Typing. (Visit here for details on Chinese Support).

Bold supports quite a number of Chinese Input Method (natively, like UI) , like 粵拼, 注音 and 倉頡. However, after the "first taste" of using the input method, I lost my chance to test further... THE INPUT METHOD BROKE MY BLACKBERRY!!!

I started up my Blackberry in English Interface with 粵拼 input method. I went to "message" and compose my first email. Everything is the same as in 8xxx machines, nothing surprising. As I have no real experience using 粵拼, I tried some common strokes like "lee" "sin" "sang" and something like that. The control is really bad as if it is programmed by a guy without any experience on Chinese typing. I tried to type a little faster, but it seems to be extremely slow (on searching output?). The speed is unacceptable and I started losing temper. I tried to hit the keyboard in random and finally it showed me "Input Method Error, restarting..." (not exact phrase). That message popup since then whenever I typed fast enough, which is like 3 key per second (not 3 char per second), which is common for any "normal" Chinese typer. I lost my interest and go on testing something else, like Web Browser.

About half an hour later I switch the machine into Chinese Trad Interface, hoping a native Chinese Interface would gain better performance working in Chinese. I start the message editor again and try typing like before. I sense strangely as i switched between input method. The BB gave me 注音 chars when the active input method is 倉頡, wtf. I keep typing until the proper 倉頡 show up, then after like 2 sec... my BB hanged up. There were no response whatever I do, including pressing and holding the POWER button. It showed me the BB is shutting down and is actually hanged.

There's nothing I can do, and I remove the battery and put it back again (a normal hard reset for BB). I think it will be fine since I do reset like 50-60 times a day when i worked on it (install/uninstall require restarts). But no luck, it gave me "SYSTEM PROCESS ERROR" and force me to reset. And of course, no luck after reset. And i am now holding a bricked Blackberry Bold.

To be lucky is that the machine is a sample from the network provider and I can wait for an exchange a few day later. I should not have great hop as it's just a demo machine anyway. I hope that the stability can be improved before its release. The release date is not announced, and they should have lots of things to do. (and Thx to those sloppy programmers, my state in my company is as firm as it can be)

Sunday, May 4, 2008

Charles Wilson's War

昨天看完DVD版的Charles Wilson's War,很失望。

失望的不是Tom Hans的表現、不是Julia Roberts的表現、不是故事、不是整個制作的任何一個部份。反之,在這幾個方面我也很喜歡,很欣賞。

使我失望的唯一一個地方,是香港方面的宣傳。

Charles Wilson's War是人物傳記,講述的是一名美國的Congressman,利用他的影響力,以協助阿富汗於八十年代被蘇聯入侵時作出反擊,說白一點,是反戰電影。

此片是2007的制作,香港於2008年3月左右上映。當初第一次接觸到此片,是在RoadShow上看到的宣傳片,中文名好像叫做「韋氏風雲」。宣傳片上最令我留意的,當然是Tom Hans。(自Forrest Gump開始,只要是Tom Hans我也會很留意)也就是說,我看此片的主因,就是看角色,怎樣看此片也是「大卡士」之作吧。

因那是RoadShow的宣傳片,聲音差點聽不到,所以只能用眼去判斷那是什麼的片。宣傳片的內容除了各人的對手戲外,最特出的就是Julia Roberts從水裡走出來的一段,占時間肯定是最長的。看了不只一次,就是看不出這是什麼主題的作品,沒有所謂,反正都會看。

看罷,不能說是非常出色,但也找不到大問題(除了歷史的部份,有關蘇聯撤兵原因的一段過份簡單)。可能因為此片太「美國」,有些背景未能理解,這是自身認識不足的問題,說不上是什麼缺點。

但這港版的宣傳片,也實在是太爛了。其實片中有很多出色的鏡頭,例如在巴基斯坦難民的一段,又或者是Soviet Copters等,都值得加入宣傳片中。至少,從宣傳片中我看不出阿富汗,甚至看不出戰爭。

想深一層,宣傳片的爛,責任何在?是不是發行商的錯?我想也未必。

爛的不是宣傳,而是香港觀眾。如果打正旗號是反戰片,有多少港人會去看?關心國際事務的人不斷減少,炒股的人數則不斷提升,「關心國際大事」就即是「關心會影響股價的事」的意思。縱使Julia Roberts的角色有如「夏蕙姨」,不打緊,找一段載黑超的就無問題。沒有「美色」的西片,怎樣騙你們入去看?

Tuesday, April 29, 2008

php_curl + cookies

curl_setopt($ch, CURLOPT_COOKIEJAR, "d:\Web\PHP\cookieFileName");

很多script會使用cookies,但cookies path最好是full path

Monday, April 28, 2008

PHP5 + Apache2.2 + cURL + windows XP

我用的是PHP Win32 installer,已選好php_curl的設定,但當行script時發現

Fatal error: Call to undefined function: curl_init() in xxxx.php

於是到phpinfo看,curl module沒有load

再看apache的error log

Unable to load dynamic library 'd:\\PHP\\ext\\php_openssl.dll' - The specified module could not be found.\r\n in Unknown on line 0

file明明存在,但就是load不到,所有file都在其位,path variable, php.ini,httd-conf都ok,但就是不行

最後將ssleay32.dll及libeay32.dll放到system32... 就行了

原因不明,path 明明是正確的... 算了,能行就好

Sunday, April 27, 2008

My MingPaoNews

記得大學Year 3時曾上過一個course,名為Information Retrieval,學會編寫網上蜘蛛,因忙著做Final Year Project而沒有放心血下這course的project上,回必一想真是感到有點可惜。

兩三年前,當我還在玩PDA的時候,有網友編了個exe,功能是download 即日Apple Daily同明報,再用ebook工具做成電子書,加上定時功能放到PDA上,那麼每天上班也有新聞可讀。可惜這種program要時常update,網上的報紙要是一改版,program即時報廢。當時心想,不如自己寫一個... 幾年也沒有做出來...

今日,不知為什麼一起床就想去做這個東西,寫了一整天,完成了整個php script。

工作:
到www.mingpaonews.com取得所有headline,
用家選擇若干篇興趣的文章後,再submit即可一次過閱讀所選的文章。

功能:
自動設charset為Big5-HKSCS,不用每頁也要手動轉;
文章的附圖也會貼上,onMouseOver可放大。

限制:
娛樂、財經及賽馬的排版是獨立的,沒有處理它們。

Code:


<?php

function DisplayNewsPage($title,$body,$pic,$pictext)
{
global $base_url;

print '<table border=1><tr><td width=200 VALIGN="top">';
if (is_array($pic))
{
foreach ($pic as $key => $val)
{
print "<img src=\"".$base_url.$val."\" onmouseover=\"popImg(true, this);\" onmouseout=\"popImg(false);\" width=180>"."<BR>\r\n";
print $pictext[$key]."<BR><BR>\r\n";
}
}
print '</td><td VALIGN="top">';
print '<H1>'.$title.'</H1><BR><BR>';
print $body;
print '</td></tr>';
print '</table>';

}

function ProcessNewsPage($url)
{
global $base_url;

$main_content = file_get_contents($base_url.$url);
$pic = "";
$pictext = "";
preg_match_all('|<font size="4" class="txt150" color="#006666">(.*)</font>|U',$main_content, $layer1, PREG_SET_ORDER);

$title = $layer1[0][1];

if (preg_match_all('|<input type="hidden" name="content" value="([^"]*)"|is',$main_content, $layer2, PREG_SET_ORDER))
{
$body = $layer2[0][1];
}

if (preg_match_all("|<font size=2 class='txt150'>(.*)\n.*;javascript:viewlargephoto\('([^']*)'\);|U",$main_content, $layer3, PREG_SET_ORDER))
{
foreach ($layer3 as $val)
{
$pic[] = $val[2];
$pictext[] = $val[1];
}
}

DisplayNewsPage($title,$body,$pic,$pictext);
}

function ProcessPage($name,$url)
{
global $title_keys;
global $base_url;

$main_content = file_get_contents($url);
preg_match_all("|<a[^>]*>(.*)</a>|U",$main_content, $layer1, PREG_SET_ORDER);
foreach($layer1 as $val)
{
if (strstr($val[0],'http')) continue;
if (strstr($val[0],'mailto')) continue;
if (strstr($val[0],'href="#')) continue;

$found = 0;
foreach ($title_keys as $k)
{
if (strstr($val[0],$k))
{
$found = 1;
break;
}
}
if ($found == 1) continue;
if (preg_match_all('|href="([^"]*)"|U',$val[0], $layer2, PREG_SET_ORDER))
{
$a = $layer2[0][1];
if (strstr($val[1],"..."))
{
@$pages[$a]="";
}
else if (@strstr($pages[$a],trim($val[1])))
{
}
else
{
@$pages[$a].=$val[1];
}
}
}

print '<FORM action='.$_SERVER['PHP_SELF'].' method=POST target=_new>';
print '<table border=1><tr>';

print '<td width=100 valign=top>'.$name ."<BR>\n";

print '<INPUT type=SUBMIT value=Submit><INPUT type=RESET>';
print '<INPUT type=HIDDEN name=ShowNews value=1>';
print "<BR>\r\n</td><td valign=top>";
foreach ($pages as $key => $val)
{
print "<INPUT type=CHECKBOX name=$key value=$key>";
print "<a href=".$_SERVER['PHP_SELF']."?ShowNews=1&$key=$key target=_new>$val</a><BR>\n";
}
print '</td></tr></table>';
print '</FORM>';

}

function ProcessAllTitles()
{
global $title_pages_set;
if (!is_array($title_pages_set))
{
echo 'pass 12:00';
return;
}
foreach ($title_pages_set as $key => $val)
{
if (!strstr($val,"main"))
{
ProcessPage($key, $val);
}
}
}

function PrepareTitles()
{
global $title_keys;
global $title_pages_set;
global $today;
global $base_url;
global $main_url;

$title_tag = '<font color="FFFFFF">';
$main_content = file_get_contents($main_url);
$title_pages_set = "";

preg_match_all("|<a[^>]*>(.*)</a>|U",$main_content, $layer1, PREG_SET_ORDER);
foreach($layer1 as $val)
{
if (preg_match_all("|".$title_tag."|U",$val[0], $layer2, PREG_SET_ORDER))
{
$title_pages[$val[0]]=$val[1];
}
}

$removal = array('<font color="FFFFFF">', '</font>');
foreach ($title_pages as $key => $val)
{
$key = preg_replace('| target="[^"]*"|U','',$key);
$new_key = str_replace($removal, "", $key);
$new_val = str_replace($removal, "", $val);

preg_match_all('|href="([^"]*)"|U',$new_key, $layer3, PREG_SET_ORDER);
if (!strstr($layer3[0][1],"http"))
{
$title_keys[] = $layer3[0][1];
$title_pages_set[$new_val] = $base_url.$layer3[0][1];
}
}
}



function PrintJavaScript()
{
print '<script type=\'text/javascript\'>';
print 'function get(eid)';
print '{';
print ' var d = document;';
print ' var r = d.getElementById(eid);';
print ' return r;';
print '}';
print 'function popImg(open, iref)';
print '{';
print ' if (open)';
print ' {';
print ' var top = (iref.offsetParent.offsetParent.offsetTop + iref.offsetTop) + \'px\';';
print ' var curleft = 0;';
print ' var obj = iref;';
print ' do {';
print ' curleft += obj.offsetLeft;';
print ' } while (obj = obj.offsetParent);';
print ' var left = (curleft + iref.offsetWidth )+ \'px\';';
print ' var img = \'<img src="\' + iref.src + \'" />\';';
print ' var d = document;';
print ' if (null == get(\'popImg\'))';
print ' {';
print ' var pop = d.createElement(\'DIV\');';
print ' pop.id = \'popImg\';';
print ' pop.style.position = \'absolute\';';
print ' d.body.appendChild(pop);';
print ' }';
print ' var pop = get(\'popImg\');';
print ' pop.innerHTML = img;';
print ' pop.style.top = top;';
print ' pop.style.left = left;';
print ' pop.style.display = \'block\';';
print ' }';
print ' else';
print ' {';
print ' var pop = get(\'popImg\');';
print ' pop.style.display = \'none\';';
print ' }';
print '}';
print '</script>';
}

function PrepareGlobals()
{
global $HTTP_HEADER;
global $HTTP_FOOTER;

global $today;
global $base_url;
global $main_url;

$HTTP_HEADER = '<html><header><meta http-equiv="Content-Type" content="text/html; charset=Big5-HKSCS"><title>My MingPaoNews</title></header><body>'."\r\n";
$HTTP_FOOTER = "\r\n".'</body></html>'."\r\n" ;

$today = date("Ymd");
$base_url = "http://www.mingpaonews.com/".$today."/";
$main_url = $base_url."main.htm";
}

function DoShowNews()
{
global $HTTP_HEADER;
global $HTTP_FOOTER;

print $HTTP_HEADER;
PrintJavaScript();

foreach($_REQUEST as $key => $value)
{
if ($key == "ShowNews") continue;
ProcessNewsPage($value);
}

print $HTTP_FOOTER;
}

function DoIndex()
{
global $HTTP_HEADER;
global $HTTP_FOOTER;

print $HTTP_HEADER;

PrepareTitles();

ProcessAllTitles();

print $HTTP_FOOTER;

}

// MAIN HERE



PrepareGlobals();

if (isset($_REQUEST['ShowNews']))
{
DoShowNews();
}
else
{
DoIndex();
}


?>

Tuesday, March 25, 2008

我的編程歷史

8歲:父親買了我第一部真正接觸的電腦,為386SX25(以往還有AT/XT機、Apple II等,都沒有真真正正地玩過)
10歲:暑假到元朗大會堂學Logo,就是Turle走來走去的那一個Logo。一般同學畢業前學懂repeat,我學畢後自修學會recusion,還編寫了簡單的作曲function,記得有生日歌、聖誕歌等。
11歲:任天堂末代推出過「家用電腦」軟件連Keyboard,內有Basic的,由於不太出名,reference不足,摸不上手。
12歲:在MSDOS 5.0內玩MS Quick Basic,Programming還是在電腦上做比較好。主要為了修改裡面的猩猩+香蕉遊戲而學的。
14歲:得知上會考班要讀電腦,在暑假自修Pascal,中四上課前寫好了Mastermind,學會了linked list,也就是大學一年級的Introduction to programming的程度吧,因為我是在圖書館借了一本Pascal的教本學的,我記得上面寫住給College First Year收讀,當年以為College就是高中的意思...
15歲:在數學科上學會了Calculus,寫了一些Polynomial四則、D、In的function。同年,在Win 3.1上試學Delphi,失敗了... Event-driven model 還是太新了。
16歲:當大家還沒有在用56k modem的時候,我已經在hkstar上有自己的homepage,是手寫的HTML,對應的是Internet Explorer 3.0及Netvigator Communicator 3.5。由於hkstar上不能行script,只好用外國的message board,不然已經給自己編了一個Blog...
17歲:DHTML時代,接觸java、ActiveX等,成立Blog型式的homepage,但還要手動加post的,所以一直都沒有加新文章入內。當年的筆記上,還寫著「public static void main <--???????????????」。
18歲:升大學的暑假,除了做暑期工外就沒其他事做,學會了Visual C,更寫了第一隻DirectX Game,是一個scriptable的plane shooting遊戲,對應的是VC6+Dx7。
19歲:偶然見到同學拿著一本「手機鈴聲大全」,裡面全是鈴聲code... 而且Nokia、Ericsson和Motor等的code都不同的,突發奇想,寫了第一個MFC的program,就是Mobile Phone Song Player,除了能翻譯各機的code外,還可midi發聲及output midi file的。不知為何會有人知道有這個作品的存在,有當時的大鈴聲網站link到我的作品處,介紹說:「這可是香港人的作品!」,下載次數高達5位數... 當年還只是一個year 1的大學生...
21歲:畢業作品為波子棋的AI研究,寫了一個Windows(Doc/View Framework)的client,除了可以和AI對戰,還可以網絡IP對戰,而且有chat room功能呢。
22歲:為給女朋友做生日禮物,學會了Flash,寫了一張Interactive的生日卡,用的還是ActionScript 1.0,還沒有class的概念。
23歲:參加了ACM Online Programming Contest,有興趣可以去看看 Valladolid Online Judge,活躍了一兩年,解決近150題。其中有一題有關 15-puzzle的題目,論速度、論內存,當年還是世界第一呢!
24歲:從事數學教育工作,為工作寫了很多教學上的小幫手,除了offline的「出題機」外,還有一些帶到堂上使用的PocketPC工具,成為我上課不可缺少的一部份。代表作為「24計算」及「火柴遊戲」。
26歲:真真正正成為一名全職的Software Engineer,接觸到的可多了... C/C++/Java/PHP/Blackberry Java/Symbian C++/Mac Cocoa (Objective C) ... 未能盡錄...

Friday, March 21, 2008

論壇管理

進入Web 2.0時代,特徵之一是資訊的發佈不再只有個別的組織或團體,用家的全面參與使Web的內容更充實及生活化。用家最主要的參與,最要是以Blog Post,或者是在論壇上進行討論。Blog與論壇的最大分別,在於前者比較個人為主,用家想表達什麼就寫什麼,主題自主性很大;後者則面向公眾 ,用家就一定論題提出意見,互動性較強。

數年前,因迷上一遊戲而加入了一個專門的論壇,更因積極討論而被邀為版主,一做就三年,期間論壇發展迅速。最近重遊舊地,論壇的光榮看來已經不復再,看到這樣的情景,不禁有點心傷。

一個論壇的興衰由無數因素決定:資訊夠不夠豐富、題材夠不夠新鮮、目標用家的選擇......但當中最決定性的,是一個論壇的管理質素。

論壇由三個主要部分組成,分別為管理員(administrator/admin)、版主(moderator/mod)及用家(users),三個組別成員之間的互動,形成活生生的社群。管理員為論壇的當家,人數最少,一般由二至三人組成。版主負責版務,一般要檢視所有文章/回復,人數視乎論壇的主題性質及數量而定,一般每種類的版由不同的人處理,每版人數一至三人。用家則不用太多說明吧,就是參與的人,一般分為「會回覆」及「不會回覆」(CD-ROM,取其Read-Only)兩類。

下表顯示各組別的互動關係:





AtoAAtoMAtoU
MtoAMtoMMtoU
UtoAUtoMUtoU
所謂論壇管理,應該是指政策的制定(AtoA)、指令的傳達(AtoM)、版務的處理(MtoU)、用家的互動(UtoU)等全部九個範疇的大共和,進一步改良,粗略總結出下表:





政策的制定指令的傳達規則的執行
定期的報告工作的協調版務的處理
用家的意見身份的提升用家的互動

由於曾經作為中層的管理者,後期升級至較高級的身份,同時亦是論壇中最活躍的會員之一,我對以上的種種都有切身的感受,往後一一細談。

Wednesday, March 12, 2008

New Project with C# 2008 + .Net 3.5

學習Visual C,以VS6開始,都差不多十年。陪著我走的有VS6, VS.Net, VS 2003, VS 2005,雖然沒有什麼大作,但過程中包括了Game, Midi, MFC, Network, AI, Mobile等多方面的知識。

去年 1 1月,因工作關係接觸了C#,寫了有關Office plug-in的tech demo,進一步理解什麼是「與時並進」,從前的基礎很重要,新的語言也要好好學習,不然就會好像公司近來interview的求職者一樣,不能達到現今的要求。

所以今天開始,要好好學習,最有效的方法就是切實地去完成一個Product。一直都想更新以前的ChineseCheckers2,今次就以Visual C# 2008,編寫我的ChineseCheckers3。

什麼是「母校」?

「母校」就是你就讀過的學校,或者是你畢業的地方。

但為什麼不就稱為「就讀過的學校」而稱為「母校」呢?重點在於「母」。

母親除了給你Give Birth外,還和你有數之不盡的關係:無條件的包容、無條件的照顧、無條件的愛... 最少,一個母親在沒有病痛、沒有受傷的情況下,都不會忘記自己的兒女。

和你享有相同的母親的人,我們稱他們為兄弟姐妹。

這三個月來,我到過我畢業於的中學、大學,見過不少同學、朋友和老師, 令我再次對「 母校」的定義反思,令我從新再一次判斷那裡是「我的母校」。

學校沒有生命,它不會有記憶,能把你「記憶」下來的,最多是你比賽、成績的記錄,又或者是你破壞的永久傷痕。但對很多人來說,這些紀錄都不存在,除非你是top或bottom students... 所以這種「 記憶」不完全成立。

「記憶」還是生物的專利,也就是說,我們存在的證明,在於「人」。就算你沒有豐功偉蹟,也沒有永久破壞,只要你曾經存在過,總會有人會記得。這些人不一定還存在於過往的物理位置,「笑回客從何處來」都是見怪不怪, 我所指的人,是曾經和你一起渡過多年歲月的「兄弟姐妹」。你記得的不止是你認識的人 ,他們記得的不止是你一個人,這是一種集體回憶,就像皇后碼頭的乘客一樣,每人都有不同的故事,你曾出現於不同人的故事中。

回到學校、參加組聚,見到很多人,亦被很多人見到,聽到的是「呀!多年不見 ,你近來如何?」、「你是... 忘記了,但我認得你」等等,既陌生又親切。不 要害怕說:「我已經忘記了你的名字。」這會使你永久失去珍貴的回憶。反之,說一句:「你以前是鄰班/住在二樓的/上過xxx課的同學吧!」這可更新兩人的回憶。

愈說愈遠了,什麼是母校?能給我以上那些感覺、感想的那些「就讀過的學校」,都是我的母校。

Tuesday, January 8, 2008

歡迎光臨

測試的第一文