読者です 読者をやめる 読者になる 読者になる

unhurried

コンピュータ関連ネタがほとんど、ときどき趣味も…

シリコンバレー周辺のお土産

最近にそれなりの量のお土産を買う機会があったので、お土産に良さそうなものを調べてみました。

探す条件

  • 多人数に配れるように個包装されている食べ物や飲み物
  • シリコンバレー周辺で購入できるもの
  • カリフォルニア、アメリカ、もしくは北米地域発祥で日本では入手しにくいもの

お土産リスト

  • Ghirardelli Chocolate

    • サンフランシスコ発祥の1852年から続く老舗チョコレートメーカー
    • 正方形のチョコレートが定番で色々なフレーバーがある
    • Great Mallにアウトレット、West Field Valley Fairに小さな販売ブースがある他、スーパーマーケット等でも購入できる
    • (アメリカの定番お土産になっているので新鮮味は少ないかも)
  • See's Candies

    • ロサンゼルスにて1921年に開業したチョコレート、キャンディメーカー
    • 棒つきのキャンディやチョコレートが人気がある
    • シリコンバレー周辺にお店が5,6店舗ある
  • Sugarfina

    • ロサンゼルスにて2012年に設立されたおしゃれなキャンディショップ
    • 箱に色々な種類のキャンディを組み合わせて詰めて
    • Santana Rowにお店がある
  • スーパーマーケットで購入できるお菓子(キャンディ、チョコレートなど)

    • Whole Foods、Trader Joe's、Safewayなどで購入できる
    • (Trader Joe'sのリテールブランドのお菓子は個包装のものが少ない)
  • DAVIDs TEA

    • カナダのトロントに2008年に開店した紅茶ショップ
    • アメリカにも多くの店舗を出店していて人気がある
    • Palo Altoにお店がある

Callback地獄対策 (2) co generator

Callback地獄対策の2つ目はcoについてまとめました。
coはGeneratorの仕組みを利用して簡単に並列・直列処理フローを記述できるようにするライブラリです。

const co = require('co');
const thunkify = require('thunkify')

// callbackを引数にとる一般的な関数
var callbackFunction = function(message, timeout, callback) {
    setTimeout(function() {
        console.log(message);
        callback(null, message);
    }, timeout);
};

// thunkifyはcallbackを引数にとる関数をthunkを返却する関数に変換する
// thunkにはgenerator内でyeild式を適用できる(yeildable)
var thunkifiedFunction = thunkify(callbackFunction);

// Promiseを返却する一般的な関数
var promiseFunction = function(message, timeout) {
    return new Promise(function(resolve, reject){
        setTimeout(function() {
            console.log(message);
            resolve(message);
        }, timeout);
    });
};

// co関数にGenerator(function*(){...})を渡すと、
// co関数はGeneratorの処理をyeild式まで進め、
// yeild式に指定されたPromiseの完了を待ってから処理を再開させる
co(function*() {
    console.log('--- co start ---');
    
    // 2つの関数を並列処理する
    // 並列処理をするにはyeildにArrayもしくはObjectを指定する
    var response = yield [
        thunkifiedFunction('co two', 800),
        promiseFunction('co one', 600),
    ];
    console.log("response: " + JSON.stringify(response));

    // 2つの関数を直列処理する
    yield thunkifiedFunction('co three', 200);
    yield promiseFunction('co four', 400);

    // co.wrapで定義した関数(後述)はco generator内で利用できる
    yield wrappedFunction();

    console.log('--- co end ---');

    // Generatorでreturnするとco.then()に指定した関数が実行される
    return "Generator finished.";

    // いずれかのPromiseでreject関数が呼ばれると
    // co.error()に指定した関数が実行される
    // yield Promise.reject("An error happened.");

}).then(function(value){
    console.log('--- then start ---');
    console.log(value);

}).catch((error) => {
    console.log('--- error start ---');
    console.log(error);
});

// co.wrapを使うことでco generatorを利用した関数を定義できる
// この関数もPromiseを返却するのでyeildableとなる
var wrappedFunction = co.wrap(function* () {
    console.log('--- co.wrap start ---');

    var response = yield [
        thunkifiedFunction('co.wrap two', 800),
        thunkifiedFunction('co.wrap one', 600),
    ];
    console.log("co.wrap response: " + JSON.stringify(response));
    yield thunkifiedFunction('co.wrap three', 200);
    yield thunkifiedFunction('co.wrap four', 400);

    console.log('--- co.wrap end ---');

    return yield Promise.resolve(null);
});

実行結果

$ node co_generator.js
--- co start ---
co one
co two
response: ["co two","co one"]
co three
co four
--- co.wrap start ---
co.wrap one
co.wrap two
co.wrap response: ["co.wrap two","co.wrap one"]
co.wrap three
co.wrap four
--- co.wrap end ---
--- co end ---
--- then start ---
Generator finished.

Callback地獄対策 (1) Promise

NodeJSで非同期処理を書いていくと必ずはまるのが、Callbackで階層が深くなりすぎるいわゆるCallback地獄です。対策を調べてみたところ色々ありすぎて混乱してきてしまったので、何回かに分けて整理してみようと思います。

今回は、非同期処理を行う関数でCallbackを引数にとる代わりに、実行状態を保持するPromiseオブジェクトを返却する方法をまとめてみました。

// Promiseを返却する関数の例
var promiseFunction = function(message, timeout) {
    // Promiseオブジェクト生成時の引数に
    // resolve、rejectを引数に持つFunctionを渡す
    // * resolve: 処理成功時の返却オブジェクトを渡す関数
    // * reject: 処理失敗時のエラーオブジェクトを渡す関数
    return new Promise(function(resolve, reject){
        setTimeout(function() {
            console.log(message);
            resolve(message);
            // エラー発生時はreject関数を呼び出す
            // reject(error);
        }, timeout);
    });
};

// Promiseインスタンスの使い方
var promise = promiseFunction('promise', 100);
// then関数:後処理を記述する
promise.then(function(result){
    console.log("result: " + JSON.stringify(result));
// catch関数:エラー処理を記述する
}).catch(function(error){
    console.log("error: " + JSON.stringify(error));
});

実行結果

$ node promise.js
promise
result: "promise"

参考: http://qiita.com/koki_cheese/items/c559da338a3d307c9d88

Forever Stampでアメリカから国際郵便を送る

アメリカから国際郵便(USPS Frist-Class Mail Int'l)を送るときはGlobal Forever Stampを1枚貼れば良いのですが、普段国内郵便しか使わない人にとっては、Global Forever Stampが手元にないことが多いと思います。調べてみると、国内郵便用のForever Stampでも少し損はするものの国際郵便も送れるそうです。

→ Foever Stampを3枚貼れば国際郵便を送ることができます。

Google Cloud Print APIを使った印刷手順

最近はどのプリンターもインターネットに繫がっているのが当たり前になって来ています。Webサービスを作るときにバックグラウンドでプリンターに印刷ジョブを投げれたらいいなというケースがいくつかあったので、その手段の一つとしてGoogle Cloud Print APIを調べてみました。

Google Cloud Print APIを使ってWebページを印刷する手順

(0) Google API ConsoleでクライアントIDとクライアントシークレットを取得する

(1) 認可画面を出力し、ユーザーから認可をもらう

https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri={登録したリダイレクトURI}&
response_type=code&
client_id={発行されたクライアントID}&
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloudprint&
access_type=offline

(2) リダイレクトURIにて認可コードを受信し、アクセストークンを取得する

  • リダイレクトURIのcodeパラメータに認可コードが付与されてリダイレクトされて来ます。
  • URIから取得した認可コードをToken Endpointに送信し、アクセストークンを取得します。
リクエスト

POST https://www.googleapis.com/oauth2/v4/token
Content-Type: application/x-www-form-urlencoded

code={認可コード}&
client_id={発行されたクライアントID}&
client_secret={発行されたクライアントシークレット}&
redirect_uri={登録したリダイレクトURI}&
grant_type=authorization_code

レスポンス

{
  "access_token": {アクセストークン},
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": {リフレッシュトークン}
}

(3) プリンター検索APIを呼び出し、印刷したいプリンタのプリンタIDを取得する

リクエスト

GET https://www.google.com/cloudprint/search
Authorization: OAuth {アクセストークン}

レスポンス

{
    "printers": [
    {
        "id": {プリンタID},
        "displayName": {プリンタの表示名},
        ...
    }]
        ...
}

(4) プリンタジョブ送信APIを呼び出し、印刷を実行する

  • 例)URLを指定してそのWebページを印刷するリクエスト
POST https://www.google.com/cloudprint/submit
Content-Type: application/x-www-form-urlencoded

printerId={プリンタID}&
title={印刷タイトル}&
contentType=url&
content={印刷するURL}&
ticket={チケットオブジェクト}
{"version":"1.0","print":{"vendor_ticket_item":[],"color":{"type":"STANDARD_MONOCHROME"},"copies":{"copies":1}}}

参考

成田・サンフランシスコ間航空機の荷物制限

成田からアメリカへのフライトの際にできる限り多くの物を持っていこうと、成田・サンフランシスコ間を就航している航空会社の荷物制限を調べていました。どなたかの参考になるかもしれないので、載せておきます。

  • アメリカン航空
    • 手荷物の制限:23kg/個、158㎝/個
    • 無料範囲:2個
    • サイズ超過:最大320cm/個(230cm以上は要問合せ)
    • 重量超過:最大45kg/個(32kg以上は要問合せ)
    • 数量超過:特に規定なし
  • ユナイテッド航空
    • 手荷物の制限:23kg/個、158㎝/個
    • 無料範囲:1or2個
    • サイズ超過:最大292cm/個
    • 重量超過:最大43kg/個
    • 数量超過:一部路線では3個まで
  • 全日空
    • 手荷物の制限:23kg/個、158㎝/個
    • 無料範囲:2個
    • サイズ超過:最大320cm/個
    • 重量超過:最大45kg/個
    • 数量超過:特に規定なし

理容室で使う英語

だいぶ髪が伸びてきてしまったので理容室に行ったのですが、英語でどのように注文すればよいのか悩みました。 結局色々と表現を下調べしてから行き、私の場合はこんな感じのやりとりでできましたので、参考までに紹介します。

Hi, I don't have an appointment. How long will I wait?
(About xx minutes, ...)
That's fine. I'll wait here.
---
(How would you like your hair today?)
I'd like just a haircut. I want to have it cut by around 1 inch. (= 2.5 cm)
And I don't like to clip sides and back, just cut it by scissors and thin out a little.
--
(How long would you like your sideburns?)
Around here. (point out the length)