電影流水帳(2017/2/18~2017/3/1)

2013 Imagen Foundation Awards, Natalie Martinez
Natalie Martinez 是 Death Race 的女主角,超正的。

  • Death Race (IMDB, Wikipedia),台譯:絕命尬車。場面浩大的飆車鏡頭,讓人血脈僨張。
    時間點設定在一個類似末世的未來,監獄被大型財團控制,並利用囚犯想逃出去的慾望來進行死亡賽車。Jensen 被裁員,回到家上樓梳洗完下來,發現妻子倒在血泊中,接著有人打昏他,將現場狀況處理成是 Jensen 殺的樣子。Jensen 因此入獄,在監獄裡,他被徵召去冒充已經勝利四次的 Frankenstein 參加賽車,與 Coach 的裝修汽車小組合作。在參加賽車的過程中,他慢慢搞清楚一切都是典獄長在操控,於是 Jensen 反過來和對手 Joe 串謀設局,讓典獄長以為他們倆要拼個你死我活,結果卻是轟開賽車場圍牆逃出去。最後 Coach 引爆典獄長原本要炸死 Jensen 的炸藥炸死典獄長等人。
  • Paul (IMDB, Wikipedia),台譯:我們撞到外星人。看到主角是 Simon Pegg 就決定把電影看完了,邊看的過程發現這部電影除了 Simon Pegg 跟他的老搭檔 Nick Frost (胖胖的那個) 之外,還有 Seth Rogen 幫那個外星人配音,以及冷面笑匠 Jason Bateman 。電影的故事算是公路電影,主角們到最後都放下了一些心結。
    Graeme 跟 Clive 是好朋友,他們一起去美國玩,並參加科幻展。在結束科幻展的路上,他們遇到了在逃走的 Paul ,一個外星人,從不接受它到變成好朋友,一起在公路旅行。在公路上 Graeme 遇到真命天女 Ruth ,相互喜歡上,而 Paul 治癒了 Ruth 的眼睛。追著 Paul 的警探緊追著他們,想要抓到 Paul ,Ruth 的父親也為了愛女而追著他們,在路上發生了許多事情。到了公路的終點,警探的老闆 (Sigourney Weaver 飾演) 出馬,這時才揭露出,追著 Paul 的 Lorenzo Zoil 是好人,其實是要保護 Paul ,而警探的老闆追著 Paul 是想利用他,最後 Graeme 幫 Paul 檔了子彈,來接 Paul 的太空船降落時幹掉警探的老闆,這時眼看 Graeme 就要死了,Paul 使用了超能力救活 Graeme ,Paul 跟眾人告別,搭著太空船回去,而 Graeme 等人,也繼續自己的人生,完成一個皆大歡喜的收尾。
  • John Wick (IMDB, Wikipedia),台譯:捍衛任務。看到 John Wick 的影評,才決定要看的。看完以後,覺得還不賴。
    John Wick 面臨喪妻之痛,在萬念俱灰的時候,收到一隻小狗,原來是妻子在死前準備好的禮物,John Wick 因為這隻狗而重燃希望。可是某天開車出去時,碰到幫派老大兒子,他覺得車子很酷,想買,可是 John Wick 不鳥他,當天晚上,John Wick 就被襲擊了,狗也被殺了。John Wick 非常的憤怒,於是決定復仇。幫派老大知道了這件事情,教訓了兒子,想跟 John Wick 和解,可是講不通。幫派老大只好派出殺手來追殺 John Wick ,John Wick 一一化解,並且展開殺戮,將整個幫派滅了。最後 John Wick 受了重傷回去,在回去路上還特地去動物收容所收養了一隻狗,電影就這樣落幕。
  • The Amazing Spider-Man 2 (IMDB, Wikipedia),台譯:蜘蛛人-驚奇再起2-電光之戰。這部電影其實在有線電視頻道看了兩三次了,這次終於完整看完。場面還可以,最可惜的就是 Emma Stone 飾演的 Gwen 被賜死了,那後面就沒什麼好演的了啊!!! 還留什麼 Harry 在監獄策劃的梗?
    一開始交代了 Peter 父母與 Osborn 公司的愛恨情仇,兩人是為了避免 Osborn 將他們的研究拿去做軍事用途而決定帶著研究成果逃走,然後在逃亡途中墜機身亡,一眨眼就過了十年。
    Peter 雖然跟 Gwen 在熱練,但他始終難以忘懷 Gwen 老爸要他不要將 Gwen 牽扯到危險之中,所以他最終忍痛與 Gwen 分手。Electro 原本是 Osborn 的電力工程師 Max,但一直都不被看重,某次在街上被蜘蛛人搭救而瘋狂喜歡上蜘蛛人。在意外中,Max 變成了 Electro。Harry 是 Peter 幼時的摯友,但身上有著 Osborn 家族的詛咒 – 一種奇怪的病症,父親致力於研究忽略 Harry 就是為了要讓家族能從這個詛咒解脫出來。
    Harry 在父親死後,為了想讓自己擺脫詛咒而想取得 Peter 的血。在公司被外人奪走之後,他找了 Electro 幫忙,到地下室取得螫到 Peter 的蜘蛛血清,注射到自己身上,血清似乎治癒了身上的詛咒,卻變成了 Green Goblin。Electro 跟前來阻止的蜘蛛人 Peter 打了起來,Gwen 隨後趕來幫忙,總算是阻止了 Electro。但之後的 Green Goblin 就沒那麼容易對付了,一場混戰之下,Peter 雖然阻止了 Green Goblin ,但沒能救到 Gwen。之後,Peter 消沉了很久一段時間,經過沈澱以後,他看到 Gwen 的演說,決定重新振作起來。片子就在 Green Goblin 沒死,Peter 正要阻止 Rhino 的場面下結束。
  • 雙瞳 (IMDB, Wikipedia)。IMDB 上放的電影海報沒什麼張力,我還是比較喜歡維基百科上放的那張,比較有驚悚感。我滿喜歡這部電影的,既驚悚但又不失溫暖。現在回頭看裡面不少擔任配角的演員在當時名不經傳,但現在都已經各據一方了。
    台灣連續發生幾起奇怪的死亡事件,死因都是吸入了奇妙的黴菌而導致意想不到的死亡。警方沒辦法解決,於是找了美國 FBI 來幫忙查案。警局派了黃火土當作跟 FBI 的窗口,黃火土跟 Kevin 一起進行查案,愈查愈覺得不對勁。在查案的同時,黃火土也困在妻子要跟他離婚與女兒美美因為之前被妻舅挾持而無法說話的家庭事件裡。案子查到最後,找到了深藏於科技公司的寺廟,廟裡的光頭涉嫌擄人等罪嫌,這樣看來,似乎已經結案了,但是矛頭隱隱指向看似無辜的謝亞理身上。既然案子似乎已經結案,Kevin 要回去美國,在回國的最後一晚,與黃火土一家吃晚飯。吃完晚飯的隔天,Kevin 被發現死在黃火土家的客廳沙發上,而火土也被發現吸入了這黴菌,緊急送醫。送到醫院以後,火土被救回,後來他醒了以後,跑去找謝亞理。在廟裡,謝亞理緩緩道出事情的前因後果,最終就是要依照成仙的預言,讓火土殺了她,讓她成仙。火土不肯,可是在黴菌的作用下,火土還是殺了謝亞理。警方發現火土不見,趕緊來找人,也因此找到了瀕死的火土,將火土緊急送醫。火土的妻女趕到現場,看到死去的火土,哭喊著要火土回來,女兒這時開口喊了要爸爸回來,而火土也真的因為感動而復活。

電影流水帳(2017/1/12~2017/2/17)

Margot Robbie Margot Elise Robbie ,最有名的角色應該就小丑女了吧~ 那個造型實在太經典。這次在大賣空裡有看到她出來客串說明,所以就選了她的照片。

  • Moana (IMDB, Wikipedia),台譯:海洋奇緣。這是一個風格接近南島語系民族神話的故事,相信故事也是取材自南島語系民族才是,裏面的毛伊畫的就很像是紐西蘭的毛利人。歌曲超級好聽的,中文版是 A-Lin 唱的,非常的有力道。
    電影一開始先帶出持有魔法魚鉤的半神人毛伊的故事,毛伊為了人類,盜取了塔菲緹的心,在要離開的時候,被帖卡打敗,鉤子掉落海底,毛伊被困在小島上。莫娜從小就被海洋眷顧,聽著祖母說這個故事長大,長大以後,她開始質疑為什麼父親不讓族人離開這座島。透過祖母的引導,才知道祖先其實是航海族,但因為毛伊而誕生的黑暗而決定不再外出航海,以免遭遇危險。不過黑暗還是找上門了,在加上祖母的死,莫娜決定外出尋找毛伊,請毛伊找回塔菲緹的心,消滅黑暗。
    莫娜透過海洋的幫忙找到了毛伊,但毛伊是個自大的人,不願意跟莫娜合作。莫娜花了好大的功夫,才讓毛伊願意幫忙。在尋找魔勾跟塔菲緹的心的旅程裡,兩人慢慢敞開心胸,互相信任,互相幫忙。最後要放回塔菲緹的心時,遇到帖卡,毛伊花了好一番功夫引開帖卡,莫娜發現沒地方可放塔菲緹的心,她看著帖卡,突然領悟到,帖卡就是塔菲緹,所以她走向帖卡,將塔菲緹的心交給帖卡。帖卡在這個時候變回了塔菲緹,海洋的黑暗也隨之消失。莫娜告別毛伊、塔菲緹,回到故鄉,整個村子也回歸為航海族的身份。
  • Maidentrip (IMDB, Wikipedia),台譯:處女航。這是一部關於荷蘭小女生的紀錄片,一個十三歲的女生,在歷經十個月的訴訟以後(保護團體要求接管監護權,以阻止小女生進行環球航行的瘋狂舉動),在14歲進行預定兩年,以帆船環遊世界的行動。令人感到佩服的是這小女生十三歲就知道自己要做什麼,而且自己找贊助,擬定計劃,找資料等等,不假父母之手,令人佩服。
  • The Lego Batman Movie (IMDB, Wikipedia),台譯:樂高蝙蝠俠。故事主要是強調伙伴和朋友的重要性。
    大意是蝙蝠俠太自大也怕失去,所以不打算有伙伴,也不認可小丑。小丑在不被蝙蝠俠認同的情況,剛好看到電視訪談超人把某個壞人關掉幽靈空間,就決意進入幽靈空間尋求盟友,於是設了局,讓蝙蝠俠去偷超人的幽靈空間傳送器,將自己送去幽靈空間。
    小丑在幽靈空間裡找到佛地魔、索倫、金剛等曾經在華納電影裡出現過的壞蛋來幫忙,小丑女則算準時煎,奪回傳送器,將裡面的壞蛋都傳送回來破壞高譚市。蝙蝠俠寡不敵眾,得到教訓,學到伙伴和朋友的重要性,於是和阿福、羅賓、高登的女兒(蝙蝠女)等聯手將這些壞蛋送回幽靈空間。但是這並沒有拯救高譚市,城市受到來不及拆的炸彈影響而裂開。蝙蝠俠最後尋求小丑的原諒及幫助而拯救了高譚市。
    笑點不是很好笑,我在看到一半時,差一點點睡著,整體來說我覺得普普,沒有比前作樂高玩電影好看。
  • The big short (IMDB, Wikipedia),台譯:大賣空。有個醫生,也是個基金經理人,在 2006 年研讀了大量的房貸資訊以後,認定與次級房貸相關的金融商品都會泡沫化,所以他大膽的將基金拿去作賣空。許多華爾街的人聽到這消息都當作笑柄,但是有兩三組人聽到這消息,認真的進行求證,確認了這個可能性,也開始賣空。到了 2007、2008 年,次級房貸市場明顯愈來愈危險,但是始終都沒往下掉。在他們資金吃緊的情況下,他們發現政府、評比機構也跟著在作假,所以次級房貸市場還維持著熱絡。不過,到了 2008 年中以後,底層的真實情況終於反映到金融商品上,於是發生了金融海嘯。
    相當警世的一部電影,我對於裏面 Morgan Stanley FrontPoint 的負責人 Steve Eisman 印象深刻,他在聽到次級房貸消息以後,和組員到實際的市場去進行調查與了解,發現房貸市場非常可能會崩盤,才開始進行賣空。最近在看系統思考的書,裏面也提到了同樣的看法,在面對系統前,最好先進行觀察,確定整個系統的流程與各個可能的影響因子,這樣才能找出最好的槓桿點與施力點。想多了解一點關於次級房貸,可以參考 《大賣空》到底在演什麼?簡單搞懂《大賣空》片中的艱澀財經內容!

django-channels websocket 與 nginx

django-channels 的佈署指南,裏面的幾個重點:

  1. 先安裝 redis,再用 pip 安裝 asgi_redis ,然後將 settings 裡 CHANNEL_LAYERS 的 “BACKEND” 改為 asgi_redis.RedisChannelLayer ,這樣效能會比較好些。
  2. 執行 worker :
    python manage.py runworker
  3. 在 wsgi.py 的同個資料夾,新增 asgi.py ,裏面放
    import os
    from channels.asgi import get_channel_layer
    
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")
    
    channel_layer = get_channel_layer()
  4. 執行 ASGI server :
    daphne your_project.asgi:channel_layer

    ,daphne 是在安裝 channels 時,會跟著裝上的。使用了 daphne 以後,就可以不需要 gunicorn 了,至於 uwsgi ,因為我沒在用,所以沒有深入研究。

runworker 跟 daphne 的部份,可以使用 supervisor 或者是寫 upstart script ,讓他們自動啟動。除了這些重點以外,nginx 的設定也需要調整,設定不多,只有幾行,這可以參考這兩篇文章:

大致的設定如下:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

upstream app_server {
    server 127.0.0.1:8000 fail_timeout=0;
}

server {
    include mime.types;
    default_type application/octet-stream;
    access_log /var/log/nginx/access.log combined;
    sendfile on;

    listen 80;
    client_max_body_size 4G;

    # set the correct host(s) for your site
    server_name example.com;

    keepalive_timeout 5;

    # path for static files
    location /static/ {
        alias /srv/app/site/static/;
    }

    location /media/ {
        alias /var/app/media/;
    }

    location / {
        # checks for static file, if not found proxy to app
        try_files $uri @proxy_to_app;
    }

    location @proxy_to_app {
        proxy_buffering off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;

        proxy_pass   http://app_server;

        # For websocket
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
    }

    error_page 500 502 503 504 /500.html;
    location = /500.html {
        root /srv/app/site/static;
    }
}

我在套用這些設定以後,websocket 仍然無法順利連上,找了好半天,才找到這篇:Websockets fail to work after upgrading to 1.0.0 · Issue #466 · django/channels  ,看完才知道,channels/daphne 在升級到 1.0 以後,程式裡的 websocket consumer 必須要送出

{"accept": True}

才行。這部份可以參考 1.0 的 release note ,也可以參考新的 Getting Start。不過我在參考 Getting start 時,居然沒注意到這行,也是我太大意了。

TypeScript 學習筆記(6) – Classes

主要看這篇:Classes

大致用法跟 C#/Java 差不多,幾個特別的地方:

  1. readonly :成員可以加上 readonly 來修飾,表示是唯讀。
  2. 有 getter/setter:可以用 get/set 這兩組 accessor 讓 method 變成屬性。
    class Employee {
        private _fullName: string;
    
        get fullName(): string {
            return this._fullName;
        }
    
        set fullName(newName: string) {
            this._fullName = newName;
        }
    }
    
  3. static:類似 java/c# 那樣的用法,原本 javascript 是沒有的。
  4. abstract 修飾:可以加在 class 前面,也可以加在 method 前面,用法跟 java/C# 相似。

後面提到的 constructor functions 是一個進階技巧,不過感覺上用到機會不大。

TypeScript 學習筆記(5) – Interface

今天是看這篇:Interfaces

TypeScript 有 anonymous interface ,就像下面的程式一樣:

// 有點 anonymous interface 的味道
function printLabel1(labelledObj: { label: string }) {
    console.log(labelledObj.label);
}

// 也可以明確的用 interface 寫
interface LabelledValue {
    label: string;
}

function printLabel2(labelledObj: LabelledValue) {
    console.log(labelledObj.label);
}

 

在宣告成員時,如果加入 ? ,表示可有可無,這個寫法應該是參考了 Ruby 的作法

interface SquareConfig {
    color?: string;
    width?: number;
}

 

用 readonly 修飾詞則是表示唯讀

interface Point {
    readonly x: number;
    readonly y: number;
}

 

如果要需告一個唯讀的陣列,可以用 ReadonlyArray

let ro: ReadonlyArray = a;

 

我覺得 Function types 比較不是那麼直覺,不容易看懂

interface SearchFunc {
    (source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
    let result = source.search(subString);
    return result > -1;
}

大抵來說就是 python 的 __call__ 或是 c++ 的 operator()。

Indexable type 也是不太直覺

interface StringArray {
    [index: number]: string;
}

let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0];

大抵來說就是 python 的 __item__ 或是 c++ 的 operator[]。

要讓類別實作介面是用 implements 關鍵字

interface ClockInterface {
    currentTime: Date;
}

class Clock implements ClockInterface {
    currentTime: Date;
    constructor(h: number, m: number) { }
}

 

下面這例子是想要限定 ClockInterface 裡的 constructor 必須符合 ClockConstructor 規範的作法,第一眼不太容易看懂。

interface ClockConstructor {
    new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
    tick();
}

// 傳進來的 ctor 必須符合 ClockConstructor 的規範,要有 hour 跟 minute 這兩個 number 型別的參數。
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("beep beep");
    }
}
class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick tock");
    }
}

let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);

 

介面也可以繼承,跟類別一樣,是用 extends,而且允許繼承多個

interface Shape {
    color: string;
}
interface PenStroke {
    penWidth: number;
}
interface Square extends Shape, PenStroke {
    sideLength: number;
}

 

蠻令我驚訝的是,Interface 可以繼承 class … @_@

TypeScript 學習筆記(4) – 變數

JavaScript 提出了兩個新的關鍵字:let 與 const。使用 let 可以避免使用 var 的一些奇妙現象;而 const 就是跟 C 的 const 一樣,避免再次指定值給這個變數。

Variable Declarations 裡提了許多 JavaScript 使用 var 宣告變數時的奇妙現象,然後解說為什麼要改用 let。這部份我偷懶跳過去了,我的想法是,就都改用 let 吧。

另外有提到 Destructuring,就是類似 Python 的 unpack :

// JavaScript/TypeScript
let input = [1, 2];
let [first, second] = input;

Python 則是:

# Python
first, second = (1, 2)

也跟 Python 3 一樣,有取 remain items 的效果:

let [first, ...rest] = [1, 2, 3, 4];
console.log(first); // outputs 1
console.log(rest); // outputs [ 2, 3, 4 ]

Object destructuring 是個比較特別的東西,意思跟 destructuring 差不多,但對象是 object,也就是可以將 object 的某幾個屬性放到變數裡。

let o = {
    a: "foo",
    b: 12,
    c: "bar"
}
let { a, b } = o;
({ a, b } = { a: "baz", b: 101 });  // 這樣也可

也支援 remaining items 的方法:

let { a, ...passthrough } = o;

Object destructuring 還支援 default values,意思是如果 wholeObject 沒有 b 屬性時,就把 b 指定為 1001:

function keepWholeObject(wholeObject: { a: string, b?: number }) {
    let { a, b = 1001 } = wholeObject;
}

也可以應用到 function 上,我覺得這個例子比較清楚,可以應用在只取物件的某幾個屬性來使用時:

function f({ a, b } = { a: "", b: 0 }): void {
    // ...
}
f(); // ok, default to { a: "", b: 0 }

Spread 算是陣列相加的一個 syntax sugar,可以把 first, second 塞到 bothPlus 這陣列裡去:

let first = [1, 2];
let second = [3, 4];
let bothPlus = [0, ...first, ...second, 5];

也可以應用在 object 上,目前想到可以用來做 object proxy 或是 composite 之類的,不過不適合也不一定。

let defaults = { food: "spicy", price: "$$", ambiance: "noisy" };
let search = { food: "rich", ...defaults };

 

TypeScript 學習筆記(3) – 基本型別

今天是看這篇:Basic Types

裏面直接建議用 ES6 的 let 替代 var 了。

  • boolean:布林型態
  • number:數字型態,沒有 integer, long, float, double 之類的,只有 number,JavaScript 裡的數字都是 float。
  • string:字串
  • array:陣列,在型別後面加上 [],例如: let list: number[] = [1, 2, 3]; ,要注意的是,無法指定固定個數。
  • tuple:就 tuple ,有點像陣列,但能指定每個元素的型態,這跟 Python 不一樣。例如:
    let x: [string, number];
    let x = ["Hello", 100];
    let y: [string, number] = ["John", 200];
    y[2] = "Doe";
    console.log(y);  // 輸出 [ 'John', 200, 'Doe' ]
    
  • enum:列舉,用法跟其他語言大致相似:
    enum Color {Red, Green, Blue};
    let c: Color = Color.Green;
    // 比較特別的用法
    let colorName: string = Color[2];
    console.log(colorName);  // 輸出 Blue
    
  • any:任意型態,但要注意的是跟其他語言所指的 Object 型別不同,TypeScript 有獨立一個 Object 型別。說起來跟 C# 的 dynamic 比較相似。
    let notSure: any = 4;
    notSure.ifItExists(); // 通過編譯,因為可能在執行時期就有 ifItExists()
    notSure.toFixed(); // 通過編譯,因為可能在執行時期就有 toFixed()
    
    let prettySure: Object = 4;
    prettySure.toFixed(); // 編譯錯誤,編譯時會有 Object 型別沒有 toFixed 的錯誤。
  • void:就 void ,表示不會傳回任何東西
  • null:就 null ,可以把任何型態的變數指定為 null
  • undefined:就 undefined,可以把任何型別的變數指定為 undefined
  • never:表示絕對不會傳回變數,
    // 只會丟出例外
    function error(message: string): never {
        throw new Error(message);
    }
    // 裏面是不會結束的迴圈
    function infiniteLoop(): never {
        while (true) {
        }
    }

Type assertion ,有 C/C# 強制轉型的意味。

let someValue: any = "this is a string";
let strLength: number = (someValue).length;
// 也可以用類似 c# as 的語法
let strLength: number2 = (someValue as string).length;

 

TypeScript 學習筆記(2) – Type annotation/Interface/Class

以下是看 Quick start 的紀錄:

  • Type annotation:一般動態語言是沒型別的,但 TypeScript 加上了這部份的支援,這可以讓開發者在編譯時期就預先發現型別錯誤,也可以編譯出更有效率的程式,讓程式執行的更快。語法像是 Go 或 Pascal (知道這語言的人應該不多了),是在變數後面加上 :type,例如:
    var str:string="hello world";
  • Interface:介面,沒啥特別的,看範例比較快
    interface Person {
        firstName: string;
        lastName: string;
    }
    
    function greeter(person: Person) {
        return "Hello, " + person.firstName + " " + person.lastName;
    }
    
    var user = { firstName: "Jane", lastName: "User" };
    
  • Class:大致上跟 java 的用法相似,不過在看到 QuickStart 範例時,還是驚訝了一下,主要是因為 TypeScript 語法並沒有明確指定類別實作了 Person 介面,但這個類別所產生的物件仍可以直接丟到只接介面的函式裡。後來仔細看了一下,才知道是因為 TypeScript 的 constructor (建構子)裡的參數加了 public,那麼會自動將這個參數放到同名的屬性去,也因此就符合了 Person 介面的要求。
    class Student {
        fullName: string;
        // 這裡的 public firstName,等同是函式裡有 this.firstName=firstName
        constructor(public firstName, public middleInitial, public lastName) {
            this.fullName = firstName + " " + middleInitial + " " + lastName;
        }
    }
    
    // 故意不要有 lastName
    class Employee {
        constructor(public firstName) {
        }
    }
    
    interface Person {
        firstName: string;
        lastName: string;
    }
    
    // 因為 Student 裡有 firstName, lastName 屬性,視同實作了 Person
    function greeter(person : Person) {
        return "Hello, " + person.firstName + " " + person.lastName;
    }
    
    var user = new Student("Jane", "M.", "User");
    var employee = new Employee("John");
    console.log(greeter(user));
    // console.log(greeter(employee));  // 加了這行,編譯會發生錯誤,告知 employee 不符合 Person 介面
    

TypeScript 學習筆記(1) – 安裝與執行

我習慣用的環境是 Ubuntu,目前用的是 16.04 Xenial。

第一步是安裝,安裝 nodejs 有幾種方法:

  1. nodejs.org 下載 tarball,手動安裝。
  2. 用 debian package 來安裝 (nodesource)
  3. 用 nvm 來安裝

之前有用過 nvm 了,這次我選擇用 debian package 來安裝 LTS 版的 nodejs。

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs

安裝好,就可以利用 npm 來安裝 TypeScript 了。不過,因為我不想把 typescript 安裝在系統路徑 (一般是用 sudo npm install -g typescript),所以我多設定了 .npmrc 以及環境變數

prefix = /home/user/.local
root = /home/user/.local/lib/node_modules
binroot = /home/user/.local/bin
manroot = /home/user/.local/share/man

 

export LOCAL_PATH="$HOME/.local"
export MANPATH="$LOCAL_PATH/share/man:$MANPATH"
export NODE_PATH="$LOCAL_PATH/lib/node_modules:$NODE_PATH"
export PATH="$LOCAL_PATH/bin:$PATH"

 

在設定好以後,使用 npm install -g 時,會將這些套件安裝到自己的 $HOME/.local 目錄下。

在使用 npm install -g typescript 以後,我另外安裝了去年推出的 yarn。

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt install yarn

 

首先寫一個 hello.ts

console.log("Hello world.");

然後用 tsc 來將 hello.ts 編譯為 hello.js: tsc hello.ts ,最後就可以用 node 執行 hello.js 印出 “Hello world.”

電影流水帳(2017/1/1~2017/1/11)

有村架純 #jdgmovie #jdgacter 有村架純

  • 寒戰2 (IMDB, Wikipedia)。整體來說,我覺得比前集稍弱了些。
    延續上集的發展,李文彬兒子李家俊入獄,但幕後的黑手蔡元祺以劉傑輝的家人作為人質跟劉傑輝談判、斡旋,劉傑輝不得已,只能隻身押解李家俊去指定的地點,但透過同黨的幫忙,李家俊逃走,劉傑輝因此面對調查會與輿論的壓力。
    蔡元祺這時出面拉攏李文彬,說明香港政治高層的佈局計劃,要求他一起加入這行動。於是就開始利用之前的衝鋒車與調查會來鬥爭劉傑輝。調查會裡的簡奧偉覺得事情不單純,派自己好友的女兒歐詠恩去調查。而劉傑輝也不甘示弱,結合了廉政署展開警政體制外的祕密調查行動。後來歐詠恩因為調查行動而被蔡元祺人馬害死,於是簡奧偉跟劉傑輝聯手,找出蔡元祺一行人窩藏衝鋒車的地方,並展開反擊。最後,劉傑輝與蔡元祺達成協議,蔡元祺遠走國外,劉傑輝穩住自己的位置以及香港高層的穩定,李文彬則被強制退休。從最後的故事走向,似乎是會有第三集的樣子。
  • ビリギャル (IMDB, Wikipedia),台譯:墊底辣妹。之前有買書,所以特別把電影也看過一次。我覺得改編的不錯,保留了書裡的故事性,把書裡大部份教怎麼唸書的地方抽離,卻又不失味道,相當勵志的故事。
    さやか是個沒怎麼唸書的少女,在母親的支持之下,到了青田塾。青田塾的坪田老師是個特別的老師,以一對一的對談去了解並引導學生, さやか因此慢慢開始轉變,並且開始對唸書有了興趣,也對自己有了信心。
    最後,在 さやか的努力下,家裡的氣氛改變了,自己的成績也愈來愈好,順利考上了慶應大學。
  • 盜墓筆記 (IMDB, Wikipedia)。前面的劇情還可以,到了後面就走味了,而且是濃濃的腐味。
    一開始是帶出悶油瓶跟外國人反派的過節,接著鋪陳出吳邪的身世以及銅片與蛇母的祕密。經過一番交代,三叔就帶著吳邪、悶油瓶跟潘子下墓探險了。值此同時,外國人反派也派了阿寧(馬思純)帶著一群傭兵去伺機搶奪。在蛇母墓展開一場你追我奪的探險,到了最後,蛇母出現,從這邊開始,莫名其妙的帶出阿寧跟胖子(阿寧隊上的翻譯)的愛情線,悶油瓶跟吳邪的腐味。與蛇母的大戰並不順利,吳邪天真的要求外國人反派幫忙,而反派居然答應了,於是順利的逆轉局勢,消滅蛇母。三叔、吳邪跟阿寧等主角順利的逃出,悶油瓶則犧牲了,看起來是還有續集的樣子?
  • 瘋狂的賽車 (IMDB, Wikipedia)。好幾年前看過一次,這次是重看的。話說啊,維基百科裡的劇情真的寫的超清楚的。
    耿浩在一次比賽後被設計了,導致拿到的銀牌飛了,也被禁賽。他的師傅氣到中風,耿浩只能開著貨車幫人送貨過活。後來師傅在電視上看到害他們的李法拉,再次氣到從樓上滾下去,死了。耿浩為了安葬師傅,決定找李法拉討錢。
    李法拉則是想把妻子殺了,所以找了殺手二人組來動手,結果反被妻子收買,改為去修理李法拉。後來陰錯陽差的變成李法拉親手殺了自己的妻子。從台灣來的烏龍幫四人組,來中國做毒品交易,結果一直沒能做成交易。故事就在這些人裡轉來轉去,產生出一連串的巧合,到了最後,李法拉跟烏龍幫四人組死了,殺手二人組成了証人,耿浩報了仇,拿到了錢,為師傅風光大葬。