穿梭兩地的貓

“哎唷,怎麼又有小貓了?”

 

父親嚴肅的語氣將我視線轉移到窗外的小花園裡。擔憂小貓被父親親自處理掉,我

掙脫沙發與手機的魅力往窗外一看,花園裡一隻白紋褐色的貓躺在草地上,我們隔著一

片玻璃彷彿看見有人在窺視它。它轉頭看向一群被棕、黑、白塗鴉成各式各樣的小貓與

一隻黑色條紋的灰貓正在嬉戲。

 

“爸,我來處理它們吧。我保證不會被媽看到的”,話剛落音,第一股念頭湧上的是

“真巧”

 

自小我家就是一個貓的磁鐵,父母都將廚餘丟到花園的土壤上做堆肥,而媽媽特愛

吃魚的關係,這股鮮味吸引不少各色的貓都來認我家為自己的領土。每天定時來到我家

外飽餐一頓。 記憶最深刻的就是一隻棕色黏人的貓伴隨我渡過了6 年的中學生涯。 由

於家中兄弟姐妹都到海外留學再加上父母工作忙碌,這只貓自然成了我的生活玩伴。正

巧,她以前的老伴也是只黑灰相夾的貓。不幸,它們在我家附近遭遇車禍,縱然有九條

命也敵不過死神的召喚,雙雙先後去世了,屍體就埋葬在小花園裡。

這些意外到訪的小訪客打開我過往的記憶櫥窗,展示的不僅僅是認流浪貓為玩伴還

的日子有那些年在曜日下到處奔跑為華校籌錢、義不容辭的犧牲休息時刻準備比賽、穿

著潔白的校服在校園內耍鬧、恨不得趕快脫離父母的約束,像哥哥和姐姐能到新加坡國

立大學升學。

 

最終我的高三的成績表現不夠優秀,於是四處尋找老師教授寫推薦信希望能彌補

成績上的劣勢,然而一切努力還是徒然。唯有接受被接受的交通大學入取,帶著一絲遺

憾的打開郵寄到我家的通知書信 。媽見我失望的表情,對我說起了外婆以前老掛在嘴邊

說我是家中最不需要擔憂的孩子,且在最後補上一句“你就努力的去台灣讀書,換算學

費匯率媽還是負擔得起的”。

 

就是這一句話,我決定到一個離家三千公里的國度去留學。早晨,坐在副座的我,

從望後鏡看著漸遠的黑色鐵門,隔壁鄰居在屋外漫步,一種惋惜卻不傷感的景色。內心

中的我相信四年很快就過去。

 

來到了國立交通大學,我所在的校區校狗比較受歡迎,吸引了一群流浪狗來這裡定

居,因此貓聞見狗的存在都躲得遠遠的。唯一一次在宿舍的凳子下看見一隻白黑斑紋的

貓。它眼神謹慎、對於周遭事物有戒心大概也是在確認沒有天敵的蹤影吧。我對它喵了

數聲以顯友好,它見我無威脅,傲慢的掉頭鑽到籬笆間隙中離去。 自此再也沒在校園內

看到貓的蹤影。

 

來到這個新環境裡,猶如貓被丟到狗社群裡的感覺:格格不入。除了人生觀和台灣

年輕人有所差異以外,以往生活中不曾出現的問題都因為離開了父母的遮蔭棚浮出水面。

例如管理個人財務、添購生活用品、確保自己攝取均衡的飲食、 少了一個人一直叮嚀我

喝水,這些以前忙碌的父母都幫我打理的事 現在必須由我自己解決。 打開臉書看到的

是一樣是來台灣留學的朋友在臉書上炫耀在台灣親戚送上的各種生活用品,無助與徬徨

擾亂我規律的心緒。

 

時間飛逝,大一的第一學期在交大獨有的微積分大會考結束畫下了句點。隔天,室

友也一早收拾包袱回家與家人團聚。四人房裡只剩我一人,於是趁著沒有課業、社團煩

惱的日子,到了台北住一晚好好思考明年是否要轉校一事。

 

在台北車站下車時,人生地不熟,於是開著十一號公車開始一連串規劃好的行程。

太遠的地方則靠捷運穿行城市,一種熟悉又陌生的感覺萌現。捷運站與捷運的內部的設

計與新加坡的捷運設施極度相似。這時不禁問起自己“或許去不了新加坡留學在這裡更

適合我? ”。我決定要更深入探索這城市的內涵,於是探訪了台大與它鄰近的市區。也

許是過慣了大學裡隨處遇見相識的人,凸顯了台北這裡的冷漠。對於一開始自問的問題,

答案已經非常的明顯。隔日我帶著失望的心情回到了新竹。

 

從台北回來以後窗外連下起綿綿細雨,室內溫12 度。日曆上距離倒數日期已經不

遠,我從櫥櫃裡拿出累積數月灰塵的行李,開始收拾準備回家慶新年。

 

夜幕降臨,窗外雨還滴答的響著,我靜靜地看著半填滿的行李箱,想著回到家以後

就能仔細的品嚐以前吃膩的菜餚、享受陽光的熱情、從窗口靜靜看野貓的一舉一動、聽

見媽念我的聲音。這遐想間斷出現在我腦中回播一直到我抵達家 。回到家時夜已晚,屋

外溫度約27 度。早睡的母親還沒入睡,她見我時給了我一個溫暖的擁抱 。原以為這時

的我會感動得觸動淚腺,可是恰好相反我的心特別平靜。

 

那夜我從房裡的窗外望出去,漆黑的夜晚中燈火依舊還是一樣的位置,房裡的氣

味和離家前一樣。我呆滯的坐在床邊,在暖和的氣候裡享受當下那份寧靜。從背包裡拿

出在飛機上寫下回來以後要做的清單,仔細想想如何充分的利用在家的時間。

很快廚房的月曆又更換了新數字,表示即將回台灣的日子已經屈指可數。

 

我走出屋外看著眼前這幾隻小貓步覆闌跚,母親懶洋洋地躺著,有種放任它們自

己學習探索的豁達。我蹲下,跨步慢慢接近小貓。母子感覺到異類種族的威脅,用高八

度的嘶聲警告我勿再逼近。我以圓潤,高5 度音的喵聲了回覆以顯友好,小貓見母親的

反應也有樣學樣的發出減弱的嘶叫聲。小貓的母親明白視乎聽得懂人的模仿聲,回頭繼

續傲慢的忽視我的存在,繼續享受夕陽的光照 。

 

看著貓懶洋洋的樣子想起北島在《貓的故事》說過他常妒忌家貓除了三餐剩餘時間

都是睡覺的生活。但人與貓實際上屬於兩種不同的物種。貓依賴人的奉養,而人借貓可

愛的動作暫且忘掉凡塵雜事。 貓往往享受當下的生活,不去顧慮未來、不為去憂慮後代

的發展;人類專注於忙於發展自己的事業、工作換取三餐溫飽 、照顧身邊的人,卻忽視

了周遭生活的美好 。

 

我回憶起上學期在台灣的時光,赫然發現那是我20 年以來渡過最充裕的五個月。

認識一群活潑的馬來西亞留學生、熱心充滿拼勁的台灣人,大家一起在參與活動間玩樂、

吵架時不知覺地創造了共同的回憶,化作這個學期的總結 。這一刻,我明白了為何身處

在黑死病肆虐、科學革命時期的萊布尼茲最終在《神義論》裡寫下“這世界是一切有可

能的世界當中最美好的世界”的結論。雖然我選擇了一個並非我理想中要走的路,但若

重新給我再選擇當初升學道路,依舊選擇當初被迫選下的選擇,選擇做回當下的我 。

 

黃金色的陽光照在我臉上,耀眼的光芒徐徐的往山丘沈下去。眼看夜晚即將降臨,

母親還在學校忙運動會的事務應該來不及回來準備晚餐。我從蹲坐的姿勢站起來動身烹

煮晚餐。兩母子被我突然的舉動驚嚇,同步發出高八度嘶裂聲,這次嘶叫聲振幅比起之

前更大,唯獨這次反而是我這個忽然變身巨人來忽視它們。來到廚房裡。想起以前坐在

飯桌上觀察母親時,她還沒決定今晚的菜單前都會先把洗好的糙米讓文火慢慢的醞釀成

軟面米飯。 母親胃不好,為了方便咀嚼與消化都把飯煮得類似粥的軟度。

 

今晚會有四人用餐,我煮了五人份的飯,而多出的一份是補償接下來一年的思念。

 

飯鍋排氣孔開始噴出的一道蒸汽,站在廚房面對窗口的我。旁晚的陽光透過鐵花

窗傾斜地穿射到廚房裡,被陽光照到平面上都上映了獨一無二的皮影戲,影子與屋後的

香蕉葉同步來回擺動。葉子間的摩擦聲與水槽中水滴落的滴答聲音合奏出簡單的曲子,

我用五味交雜的心情享受這曲子的節奏。

(2016年馬來西亞旅台藝術節徵文比賽散文組第三名)

用Flask建立RESTful API

比過黑客松或是數據探勘一定多少接觸過api,可是呼叫api一行指令的背後又是怎麼做的呢?

上網找了幾筆文章發現原來有個很簡單的方式可以建立自己的api,那就是使用flask框架。flask架構簡單運行速度比Django快,且同樣也是使用簡單易懂的Python語言(撒花),通常適合用來做static 網頁的後段。而這裡我就以flask為框架弄出一個能parse 出json 資料的api

安裝:

在unix上,開啟terminal  安裝virtualenv

sudo pip install virtualenv

成立一個flask folder, 在folder內創建一個隔絕的Python 環境。

virtualenv  myvenv

啟動Python環境(退出則是: deactivate)

source myvenv/bin/activate

安裝flask : pip install Flask

之後成立一個app.py檔案,裡面寫著:

from flask import Flask, jsonify
app = Flask(__name__)

data = [
     {
         'id':1233,
         'name':u'Jason',
         'description':u'handsome but impatient'
     },
     {
          'id':1234,
          'name':u'Peter',
          'description':u'tall and humorous'
      }
]

@app.route("/example/api/v0.1/name",methods = ['GET'])
def get_data():
    return jsonify({'data':data})

if __name__ == "__main__":
    app.run(debug = True)

其中data是你的數據List,。當有人GET時,flask就會將data轉為json格式並回傳給他內所data內容。

執行:  python app.py

在另一個terminal視窗執行: curl -i http://localhost:5000/example/api/v0.1/data

輸出結果如下(結果在右邊):

旁邊的terminal

如果想要parse單筆資料要怎麼辦呢?

from flask import Flask, jsonify
app = Flask(__name__)

data = [
     {
         'id':1233,
         'name':u'Jason',
         'description':u'handsome but impatient'
     },
     {
          'id':1234,
          'name':u'Peter',
          'description':u'tall and humorous'
      }
 ] 

@app.route("/example/api/v0.1/name/<int:data_id>",methods = ['GET']) 
def get_data(data_id):
     people = [people for people in data if people['id'] == data_id ]
     if len(people) == 0:
          abort(404) 
     return jsonify({'data':people[0]}) 

@app.errorhandler(404)
def not_found(error):
     return make_response(jsonify({'error':'Not Found'}),404)

if __name__ == "__main__": 
     app.run(debug = True)

在另一個terminal視窗執行:  curl -i http://localhost:5000/example/api/v0.1/name/1233

輸出結果如下(結果在右邊):

api2

當然API侷限在parse資料也太無聊了,所以要能添加與刪除資料吧

from flask import Flask, jsonify, make_response, abort
app = Flask(__name__)

data = [
     {
         'id':1233,
         'name':u'Jason',
         'description':u'handsome but impatient'
     },
     {
          'id':1234,
          'name':u'Peter',
          'description':u'tall and humorous'
      },
      {
          'id':1235,
          'name':u'Henricks',
          'description':u'Geek'
      }
 ] 

@app.route("/example/api/v0.1/name/<int:data_id>",methods = ['GET']) 
def get_data(data_id):
     people = [people for people in data if people['id'] == data_id ]
     if len(people) == 0:
          abort(404) 
     return jsonify({'data':people[0]}) 

@app.errorhandler(404)
def not_found(error):
     return make_response(jsonify({'error':'Not Found'}),404)

#delete database data
@app.route("/example/api/v0.1/name/<int:data_id>",methods = ['DELETE']) 
def delete_task(data_id):
    people = [people for people in data if people['id'] == data_id]
    if len(people) == 0:
          abort(404)
    data.remove(people[0])
    return jsonify({'result' : True})

if __name__ == "__main__": 
     app.run(debug = True)

 

在另一個terminal視窗執行:curl -i -H “Content-Type: application/json” -X DELETE -d ‘{“name”:”Jason”}’ http://localhost:5000/example/api/v0.1/name/1233

 

api_delete3

再次呼叫id 1233的話,就回傳沒有這筆資料了

api_delet4

 

POST資料

好了我們能刪除資料了,刪錯了怎麼辦??

用POST指令把它添加回去好了

from flask import Flask, jsonify
app = Flask(__name__)

data = [
     {
         'id':1233,
         'name':u'Jason',
         'description':u'handsome but impatient'
     },
     {
          'id':1234,
          'name':u'Peter',
          'description':u'tall and humorous'
      }
 ] 

@app.route("/example/api/v0.1/name/<int:data_id>",methods = ['GET']) 
def get_data(data_id):
     people = [people for people in data if people['id'] == data_id ]
     if len(people) == 0:
          abort(404) 
     return jsonify({'data':people[0]}) 

@app.route("/example/api/v0.1/name",methods = ['POST'])
def create_task():
     if not request.json or not 'name' in request.json:
          abort(400)
     people = {
          'id': data[-1]['id'] + 1, #id is default as the next id num
          'name': request.json['name'], #name is a must
          'description': request.json.get('description', ""),
     }
     data.append(people)
     return jsonify({'data': data}), 201 #return all data
@app.errorhandler(404)
def not_found(error):
     return make_response(jsonify({'error':'Not Found'}),404)

if __name__ == "__main__": 
     app.run(debug = True)

以上的api要求添加新的個人資料時,必須要有該資料的名字,如果沒有則回傳400錯誤。

執行一下指令就能添加一個名為DBlackKat的個人資料:

curl -i -H “Content-Type: application/json” -X POST -d ‘{“name”:”DBlackKat”}’ http://localhost:5000/example/api/v0.1/name

api_post2
function最後要求回傳所有資料

學會了怎麼添加那麼如何更改個人資料呢?

from flask import Flask, jsonify, make_response, abort, request
app = Flask(__name__)

data = [
     {
         'id':1233,
         'name':u'Jason',
         'description':u'handsome but impatient'
     },
     {
          'id':1234,
          'name':u'Peter',
          'description':u'tall and humorous'
      }
 ] 

@app.route('/todo/api/v1.0/tasks/<int:data_id>', methods=['PUT'])
def update_task(data_id):
    people = [people for people in data if people['id'] == data_id]
    if len(people) == 0:
        abort(404)
    if not request.json:
        abort(400)
    if 'name' in request.json and type(request.json['name']) != unicode:
        abort(400)
    if 'description' in request.json and type(request.json['description']) is not unicode:
        abort(400)
    people[0]['name'] = request.json.get('name', people[0]['name'])
    people[0]['description'] = request.json.get('description', people[0]['description'])
    return jsonify({'result': people[0]})

if __name__ == "__main__": 
    app.run(debug = True)

在另一個終端執行:

curl -i -H “Content-Type: application/json” -X PUT -d ‘{“name”:”Raymond”}’ http://localhost:5000/example/api/v0.1/name/1233

 

api_put2

輸出結果如上,注意 Json 名字已經被更改成Raymond了

以上都是建立一個開放式的api, 如果今天想要使用認證才能登錄要怎麼辦呢?

Python 對於一切問題都有自己的library這裡我們就安裝 http_auth,

在同一個虛擬環境下執行 pip install http_auth

一下簡單介紹最基本的認證方式,如果是使用在產品上建議使用http_auth的flask網站上提到的範例,並且secret_key是由file讀取為佳。

from flask import Flask, jsonify, abort, make_response, request
from flask_httpauth import HTTPBasicAuth

app = Flask(__name__)

auth = HTTPBasicAuth()

data = [
       {
          'id':1233,
          'name':u'Jason',
          'description':u'handsome but impatient'
       },
       {
          'id':1234,
          'name':u'Peter',
          'description':u'tall and humorous'
       }
]

@auth.get_password
def get_password(username):
    if username == 'theblackcat102':
         return 'blablabla' #this is our password
    return None

@auth.error_handler
def unauthorized(): #make unauthorised access return
    return make_response(jsonify({'error': 'Unauthorised access'}), 403)

@app.route("/example/api/v0.1/name/<int:data_id>",methods = ['GET']) 
@auth.login_required
def get_data(data_id):
    people = [people for people in data if people['id'] == data_id ]
    if len(people) == 0:
        abort(404) 
    return jsonify({'data':people[0]}) 

@app.errorhandler(404)
@auth.login_required
def not_found(error):
     return make_response(jsonify({'error':'Not Found'}),404)

#delete database data
@app.route("/example/api/v0.1/name/<int:data_id>",methods = ['DELETE'])
@auth.login_required 
def delete_task(data_id):
     people = [people for people in data if people['id'] == data_id]
     if len(people) == 0:
          abort(404)
     data.remove(people[0])
     return jsonify({'result' : True})

if __name__ == "__main__": 
     app.run(debug = True)

在另一個終端執行:

curl -u theblackcat102:blablabla -i http://localhost:5000/example/api/v0.1/name/1233

輸出結果如下:

unauthorized_access3

如果密碼打錯了,結果就會出現我們設定的回饋(注意密碼打錯了):

unauthorized_access4

參考來源: http://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask

 

Silicon Valley :追劇完三季後感?

silicon valley Intro

我關於矽谷的認知,很多都來自對於早期閱讀steve jobs, 看social network ( 故事靈感來自fb 的創辦故事 ), 閱讀新聞雜誌得來的。

期末結束前夕,youtube上跳出了silicon valley的搞笑短片,按耐不住之下就點進去看了一下。於是我就在隔天三天內把第一第二季看完了,第三季也在今天順利看完( 1 Mbps 網速沒有讓我更失望 )。

Silicon Valley, 這部戲講了一個典型的新創公司在矽谷的各種日常故事。例如:面臨VC募資時的各種談判搞笑、尋找管理與領導諮詢(別小看這個環節)、迅速壯大所面臨的問題等等,都一一在這裡出現了。

故事中的5位演員( 分別扮演公司的: CEO/founder , PR , CTO , full stack / backend engineer , software engineer ) 精湛的演出為這部連續劇增添了許多幽默環節,從頭到尾留住了觀眾的注意力。

silicon-valley
故事的男主角們(左到右):兩位工程師,CEO,CTO?,PR

最近看了許多關於世界上不會出現第二個矽谷的各種評論文章後,對這部戲的寫實感大感讚嘆。待在新竹,台灣已有差不多一年時間,當地政府一直推行各種技術創新、專利轉讓等等的口號,極力將這裡打造成為新創公司萌芽的地方。然而,正如許多評論文章中提到的,美國矽谷不可能會在台灣發生是因為矽谷的文化正是由風險投資人、技術人才、開放自由的環境匯集一處才孕育出的獨有文化。而台灣正是少了這些敢於投資與冒險的VC、天使投資人與尋求資深領導人的諮詢管道。台灣新創公司據我了解不是籌集不到資金死在沙灘上,就是在海洋中處於半死不活的狀態(不知道TapPay的近況如何了?)

返回正題,Silicon Valley 以幽默的方式,道出了矽谷文化鮮少人知的另一面。但是也許集數太少,很多時候故事即將到了高潮時,那一季就結束了。每段男主角們遇到的挑戰之間銜接性很好,做到了前呼後應的效果。對於在矽谷裡的各個角色(工程師、投資人、億萬富翁、資深領導人)的性格特點勾勒出非常到味。十分推薦週末在家消磨時間,或者半夜寫程式沒動力了可以看一看。

PHP初學感言

PHP 在網頁開發社群內普遍被眾人鄙視的程式語言。大家以往對於PHP都抱著資安防護弱、程式結構亂的負面印象,Python入門的我對於PHP的觀點也只用從網絡社群聽來。因為接了一些案子的緣故,我被迫要去認真的深入探討PHP,這過程讓我對於PHP有了深度的改觀。

資深網絡開發員Travis Neilson 說過  “ 無論你使用任何的框架開發網頁,最中心的核心還是逃不過 Javascript, CSS和 HTML. 與其在猶豫到底要從何下手,不如開始實作才是最重要的。 “

說了那麼多廢話,我們來看看PHP究竟

phphelloworld.php

可以看得出,php內容開始於”<?php “ 結束於 ” ?>”, 因此在一個php擋中可以有無數個 這樣的標籤重複出現,很容易使程式碼變得混亂。

PHP的語法

Php 的語法的特點在於 變數無時無刻都會有 $在變數前方,而編寫時不需要給予任何預設記憶體。預設初值就決定了變數的型態,例如

$double = 0.11;

$int  = 1;

$string = “67812”;

$boolen = true;

$convert  = (double)$string; //各種變數切換與c的type casting使用一樣

$array = array{24,432,412,5432,213,12};

這些都是我們在c中常見的變數型態,而PHP本身卻有其他變化的變數型態,例如:

$dictionary = array{ “one” => “Steve”, “two”=> “Jane”,”three” =>”Kelvin” };

echo $dictionary[“one”] //這會印出: Steve

每個陣列的元素可以用一個索引鍵來呼叫(“one” 是  “steve”的索引鍵 ),因此這與Python的Dictionary又非常相似,而這樣的資料型態也經常使用到。可是要注意,如果陣列經過asort()函數處理過以後,索引鍵就會消失。

因此需要參考ksort(), 或自訂函數來排序陣列。

接著我們來看看其他if..else, while, do{}while, switch 的使用方式吧。

if-else

….到了這裡我已經懶得繼續寫下去了,沒錯,他們的型態都與C語言一樣,唯獨變數無須特別宣告。

PHP的物件導向特色 - class, private, static, protected, inheritance (extends)

class

bottle.php

UnitCounter.incScreen Shot 2016-05-25 at 3.14.24 AM

繼承 Inheritance:

繼承准許類別繼承某個現有的父類別的能力。

extend

除非函數被宣告為private , 否則衍生的類別都能使用。

若子類別和父類別內都有constructor則函數只會呼叫子類別的constructor而已。

函數重新定義

redefine-class

Exception Model

描述throw與 try…catch 實在例外的情況跳出錯誤處理程式的方法之一,這個是為了解決大錯誤而終止程式。利用丟出例外,捕抓例外並加以處理。throw 一般與 try…catch結合使用。

try-exception

http://php.net/manual/zh/

範例參考自:《PHP與MySQL 應用實例》

這巷子裡的歲月

DSC_0019
好有趣的招牌

趁著來台北出席一場有趣的文學獎決審會議的機會,我來到了忠孝敦化區拜訪一間星馬(新加坡與馬來西亞)餐廳—【Mamak檔】星馬料理。 從忠孝敦化區一路走到目的地的路上,都是具有獨特個性的服裝店、咖啡廳、酒吧,是一條富有生命力的街道。

街道上的商店少了台灣與中國普遍使用刺眼的亮色招牌,取而代之的是輕鬆,隨意的店面設計。從街道望向街尾,是一道和諧舒適的景色。路上與我插肩而過的,是各種身穿年輕裝扮的路人。有些成群結伴,其餘則成雙入對。這裡屬於他們的街道,而我才是街道上的路人。

在街道裡穿梭,難免會有些被人忽視的角落。這些角落裡,都是在支撐繁華街道的幕後人員。而他們臉上露出與街道主人相反的臉色:疲累、失落、無力。

DSC_0021

我經過一家售賣自制工藝品的店面,透展示窗的反光,看見了一位正在收拾紙皮的叔叔。我回頭看著他,緩慢地將紙皮一張一張堆疊、捆紮。這場景,不是與每天6點半清理我宿舍的清潔阿姨一樣嗎?阿姨每天早晨清理垃圾桶、洗刷廁所的發霉的磁磚、清洗馬桶水槽。這累人的工作,全是一位阿姨一手包辦打理著一層樓的基礎衛生。她照顧的廁所地面也許比某些數月未清掃過的房間還乾淨。阿姨年紀看似不輕,年紀應該接近四五十來歲。

一個完整的社會,有如金字塔一般,越是基礎的工作,越是依賴人力資源才能完成。而我們處在的社會,在沒有先進廉價的機器人取代這些工作前,只能依賴年長一代來代勞。然而當現有教育的目的都是為了未來能有高薪低勞力高思考性的工作時,10年後,當這些學生出來畢業以後,年長一代退休後,這些工作究竟誰來代勞?

Milo車—兒時回憶

DSC_1730.JPG
今早用從馬來西亞帶來的Milo配上台灣購買的煉乳調製的Milo飲料

今早,氣候與馬來西亞兒時的早晨相似,勾起了小學時一幕又一幕難忘的記憶。其中莫過於定期到各小學宣傳的巧克力飲品—美碌,以下通稱英文名字Milo。

記得如果早晨抵達學校時看見一輛Milo貨車停在籃球場上時,就特別期待上午9.30到放學時間的這段期間。因為這就是Milo車開始為學生免費提供冰冷的Milo。這段時間總是望著走廊外,等待隔壁班的班長來傳達福音給學生們,老師聽到後總是露出一臉無奈的樣子。

nestle
小學生排著隊透過小窗口從叔叔手上接過Milo(圖源自網絡)

依次序走到籃球場後,在炎熱的天氣底下,大家排著隊伍等待從貨車叔叔手中接過那一杯飲料。而排隊過程我們就爭論著Milo車泡Milo的秘訣與各種Milo混搭其他飲料的心得。

從叔叔手中接過冰冷的Milo時,總會認為前一位同學拿到的比較冷、比較濃而手中的那一杯比較溫、份量較少。拿了飲料的大夥就站在一旁,用自己享受的方式,品味手上那一小杯的Milo。有人慢慢一口一口的吮吸仔細品味其中的濃郁感,有人一口氣灌入肚子享受那瞬間的冰涼感。我則努力的嘗試記得當下的甜度與濃度以便回家可以重新調出一模一樣的Milo。

無論再怎麼努力,回家總是無法調配出那一樣的口感。曾有一度還認為是貨車內使用的是特別調製過的Milo才能調出那麼美味的Milo。

小學畢業後,到了居鑾中華中學以後初一時好像還有辛品嚐到Milo車調出的那獨一無二的Milo。殊不知,已經是我最後一次喝到從Milo車的“特調”Milo了。

DSC_1732
 馬來西亞帶來的Milo會比台灣的Milo在顏色上較偏巧克力色,麥與巧克力的比例也會比較低,麥香味沒那麼重

 

新竹西區 大海拉麵

春假待在交大養病的日子眼看就要到尾聲了,於是趁著許多餐廳都休息的星期一到位於新竹Sogo西區的大海拉麵店慶祝一下,步入在小小的店,一般是開放式廚房另一半則是10個座位的吧台式餐桌。很不幸遇上午餐時間,等了10分鐘左右才有空位能開始點餐。店內吧台的設計使饕客不能面對面對談,與廚房又隔著一道突起來的櫃檯隔著,無法欣賞廚師料理自己點的豚骨拉麵,讓等待變得十分無聊。

大海豚骨拉麵的菜單中可以自由選擇湯頭的鹹度(店家的菜單寫的是濃度,選擇最濃的湯服務員會提醒您濃湯頭會很咸),當然還有麵條的硬度。以上兩者我都點了普通的選項,並外加一份看特別的野蔬菜。完成點餐後,我被安排到了10號座,位於店面的廁所旁。由於店面過於狹小,所以有股輕微酸敗的味道。

所幸廚師動作迅速,我點的豚骨拉麵與野蔬菜就上桌了。湯頭的豬骨香暫時掩蓋掉了剛入坐時的不良體驗。

wp-1459750292215.jpg

一開始看到蔬菜其實有點小小失望,50元的野蔬菜實際上是一碗豆芽、包菜與零碎的玉米共同浸在日本醬油裡的菜肴。份量雖多,依然過於平凡,明顯是不被廚師重視的菜色之一。

wp-1459750301498.jpg

 

說完了小菜,就進入主軸豚骨拉麵吧。

小嘗了豚骨湯時,表面的油脂有點過多,造成還沒吃麵已經有種油膩不開胃的感覺。湯頭鹹度適中,能夠讓人喝下整碗湯還不會感覺口渴的等級。豬骨味道很淡,輕易的被奶味所掩蓋掉了,喝第一口不容易品嚐到任何豚骨的滋味。但綜合來評論廚師在準備湯時沒犯什麼大錯。面的筋度適中,份量有輕微的過多但是對於多數人可接受的量。

wp-1459750311857.jpg

豬肉片著肉質軟面,夾起來時看得出豬肉組織幾乎要分裂了一樣,能輕易的將肉片撕斷。可惜肉片是整碗麵裡最咸的材料,肉缺乏肉味,感覺像是一塊豬肩肉在鹽水中煮了數小時。

wp-1459750307086.jpg

心得 | 如果有些心意不能向你坦白

image

《曾經有一個這樣的你》是我買middle的第一本書,當時讀著讀著淚就悄悄流下。講的是人事變遷的故事,暗戀的女生對於自己完全無感。對此與文字段落產生共鳴。
自此對於middle的文體有著一種著迷。每星期追他的網絡專欄,贊了幾乎每張面書的文章。後來需要上博客來買書於是順便收下《如果有些心意無法向你坦白》這本書。
書採取文字排版來表達文字的含義。
例如心灰意冷的句子會明度漸漸變淡。
又或是心意混亂會特意將文字排版的特別混亂。藝術上這是一種文字之外表現心情的一種方式。可是卻為閱讀體驗上大打折扣。不僅讀者閱讀時需要費時理解文字排版是要怎麼開始讀起,有些段落過於短,這樣類似詩的排版的散文閱讀起來類似點了蝦餃卻送上了蝦肉燒賣一樣。同樣的餡料,外皮卻完全不同。

再來簡單說說內容吧,《如果有些心意無法向你坦白》與《曾經有一個這樣的你》相比垂淚程度已經大大減弱。或許是我已經習慣了作者的寫作風格,也許是對於愛情、男女關係已經麻木的我,讀完全部文章都感覺不出文體有什麼特別之處。相比當初讀《曾經有一個這樣的你》那種同步,共振的感覺完全在這本書裡體會不出來。

也許是人變了,也許是作者對於這本書投入較少的心意(《曾經有一個這樣的你》是middle出版的第一本書)。當然這僅僅是一個讀後感短文,但是如果問兩本想比我會推薦那一本,我還是認為在《曾經有一個這樣的你》愛情上各個階段的詮釋。
從暗戀、分手、回憶、麻木這四個階段中最中肯的文筆都在裡面都可以找到。

頭戴式耳機入門體驗 X Philips Fidelio M1

由於環境因素,所以很少接觸音響,所以音樂與我邂逅是我高中擁有第一部智能手機,經朋友介紹流行歌曲,音樂才漸漸走入我的生活裡。那時候,小米剛剛打入東南亞市場,而它最初的金色耳塞式耳機正好就解決了手機音響問題的痛楚。

後來換了幾代的小米耳機,體驗也很不錯,唯獨音域不廣、耳塞容易掉的問題之外還有出現了一個奇怪的困擾,那就是聽久了耳油分泌速度異常的快,需要經常清理耳道。

入手頭戴式耳機

不久前我的小米耳塞左邊喇叭音量異常小,造成左右聲量不協調。於是趁此機會購入了飛利浦的 Fidelio m1 系列耳機。這是一款從2016開始算起,也有三年多的耳機了。主打Fidelio系列耳機單體經過“大師”調配過….外觀是鋁金屬搭配仿真皮革的頭戴,音源線是可拆卸更換的。整體外觀和今天智能手機追求的金屬機身與高品質畫上等號的宣傳有些相似。

 

DSC_1581
可以看得出,耳機音源線的接口並非像其他廠商將插座做到耳機殼中,而是選擇將耳機插拔延長出來。

體驗

戴上Philips M1 的時候,有種耳朵被左右夾子壓著的感覺。由於這個頭戴式耳機屬於on-ear headphones 也就是耳墊沒有完全包裹著耳朵外圍,而是直接按在耳殼上。但都是on ear 耳機的通病,不完全是Philips M1本身的設計問題。

這部耳機我沒有開聲過,意思是開啟最大音量播放高低兼具的曲子將驅動單體(喇叭)進行所謂的預熱。使用過幾款耳塞有開聲與沒開聲我覺得沒什麼差別。 (更新:也許是耳塞式耳機單體小很難察覺開聲後的差異,頭戴式耳機開聲後會有差異性)

不過分享體驗前列了耳機的配置

 

  • 40mm 驅動單體
  • 3.5 mm 耳機插
  • 6~26,000 Hz 發音範圍
  • 16 歐姆 阻抗
  • 記憶海綿耳墊

聽歌

以下是我所選出來的測試歌曲:

  1. 魔力紅 Maroon 5 — Sugar, Payphone, Animals
  2. Taylor Swift 《1989》— Style, All you had to do was stay, Clean, New  Romantics。
  3. 蘇妙玲 — 眼神總會認為
  4. 曲婉婷 — 沒什麼不同

當然還有特別托朋友借了 Hotel California, 耳機測試的經典曲子試試。 所有歌曲都是flac無損檔案而Hotel California 是24 位數,其他只有16位數的無損格式。至於播放方式用的是我的Xperia Z2, 畢竟多數時間我是用它來聽無損音樂,並且設定內部均音器關閉。

從耳塞式轉頭戴式最大的差異就是單體倍增帶來的震撼感。瞬間音樂的廣度變大了,雖然這部耳機是封閉式的後殼阻止漏音發生同時抑制了音樂的發散無法產生那種被音樂環繞的感覺。可是從耳塞換頭戴,這差別還是可以明顯感知到的。

講講 《Clean》、《New Romantics》背景低頻強而有力,完全發揮40mm 單體還有最低的 6Hz 發音範圍的優勢。類似的效果在《Sugar》,《Animals》上也是重複的出現,說明以上的感覺並非歌曲緣故。

再換聽蘇妙玲《眼神總會認為》與曲婉婷《沒什麼不同》,我選這首是因為這兩首大概是我歌庫裡重複聽最多次的歌(歌庫有限),但都是在耳塞式耳機聽,因此切換頭戴式應該有明顯的差異。果然,女音更加的細膩、鋼琴曲與背景曲子猶如有力的海浪在耳道來回湧動拍打耳膜,海浪的細膩程度是能明顯的感知到的。女歌手飆高音時,音符沒有因為單體無法負荷而像琵琶弦忽然繃斷而是完美的抵達最高音符,順滑的滑落。

最後稍微講講我不怎麼喜歡的Hotel California,  這首歌聽的是前後琴弦與鼓拍打交錯的感覺。低頻與高頻兼具的一首歌曲。忽然單體變得十分靈活,各種樂器在左右耳骨膜靈巧的敲打。男主角與合唱團的聲音沒有意外,都十分的細緻。

_20160323_003245
耳罩壓倒眼鏡真的很不舒服

價格:

最後談這部耳機在pchome24 的價格是6990元,網絡上售價介於6500-7000元。這個價位實際上還有許多更佳舒適的耳機例如 鐵三角的M50x 才售價5600元,論舒適度與音質兩者都是廣受眾人歌頌的。

那麼這樣的耳機適合什麼用戶呢?

因為外型金屬搭配仿真皮革,給人一種前衛的感覺,耳機大小剛好可以適合旅行攜帶。可拆卸式的耳機線雖然接頭有些奇怪,但還算得上是可更換的。而只要搜索耳機延長線,任何一款使用 3.5 mm的音源線都可以代替你壞掉的接頭。對於剛入頭戴式耳機的讀者,我推薦這個價位上還是另選其他耳罩更加大的耳機。

奇怪的音源接口是在左耳機一段短短的線之後(圖源:cnet )
奇怪的音源接口是在左耳機一段短短的線之後(圖源:cnet )

《遊戲》|Once Upon a Time

photo-1453106037972-08fbfe790762

記得以前,

曾經答應過你要把一個你很喜歡的網絡小遊戲做成離線版的。

那時候的我們是如此的天真,如此爽快。

彼此一起在教室裡玩那個遊戲,開啟時還要等超慢的網絡將遊戲準備好。

每個格子移動象徵一個感情的階段,

一步一的進展,

愚笨的我們還抓不到遊戲的訣竅

那是美好卻殘缺時代

最近隊友的一個提議讓我再次想起以前對你的承諾,

那,年幼的我無法辦到的約定

最後做好遊戲,並且快速的破關的方式也知道了

唯獨人也不玩遊戲了。

當下美好的是未來的傷疤,

傷疤痊癒後痕跡依然會緊貼在身上

能隱藏卻不能抹滅

那曾經的記憶

 

Once upon a time.

When we were still young

Playing the game which I promised to refine for you

Even though I can’t comply the promise

Once upon a time.

When we were still naive

Believing such relationship could further to the next level

Just as the game was

Yet,

Once upon a time.

Where relationships turns out to be complicated

Only to find out

Fulfilling the promised is within my capability

Things had went so far, which the promise no longer matters

Finishing it, only to compensate my regret

wii