シンガポールに行ってきた 2

続き。

今回は木曜の夜に羽田空港を出て、金曜の早朝にチャンギ空港に着く便を利用した。 荷物を預け入れるのも初めてで少しドキドキした。

機内で入国カードが配られるので記入する。

上記のような記入例がガイドブックにも載っているので、それを見ながら書くつもりでいたのだけれど、この入国カードを提出するイミグレーションでのやり取りを思い出すと「実際はそこまで厳密な記述は求められていないのではないか」と思えてきたので、今回は記入例を参照せずに自分の解釈に基づいて書いてみることにした。何ごともチャレンジである。

英語圏の人なら迷わないのだろうけれど純ドメスティックな日本人からすると、まず最初の自分の名前を書くところで「どう書くのが正解なのか?」が気になってしまう。

  • 名 -> 姓の順でいいの? 姓 -> 名でもいいんだっけ?
  • 記入欄が複数行あるということは姓と名で改行した方がいいの?

とか。

今回は名 -> 姓の順で、改行せずに空白を挟んで続けて書いてみた(記入例だと改行してる)。

あと滞在先の名称と郵便番号。

ホテル名称のスペルはうろ覚えだし、住所や郵便番号は全く覚えていないので、これまでであればメモ帳やプリントアウトしたバウチャーなどをバッグから取り出して、一文字も間違えないように確認しながら記入したと思う。

でも、イミグレーションの担当者がホテル名のスペル間違いに気づいたとして訂正を求められるか、というと恐らくそんなことはない。

この入国カードを出すときに実際にそのホテルを予約していることを証明するものの提示を求められることもないので、どのホテルの名前を書いたとしても問題にはならないだろう。(明らかにシンガポール国内にはないと思われる名称を書いたら止められるのかもしれない)

だから、うろ覚えのまま微妙に間違ったスペルでホテル名を記入し、郵便番号は確か空欄のまま提出した。結局それで何の問題もなかった。 きっと、名前のスペルやパスポート番号を間違えていたらまずいのではないかと想像した。

そんなこんなで、あとは機内で寝たり起きたりしつつ過ごしていたらシンガポールに到着した。

イミグレーションを通過して預け入れ荷物を受け取り、空港の到着ロビーに出たところでベンチに腰掛けて小休止。

両替

現金の両替については、市内のおすすめ両替所を教わっていたので空港では必要最小限の額だけ替えることにした。

3,000 円と伝えるとカウンターの兄ちゃんに「three thousand...(ププッ)」と笑われたけれど気にしない。こちらはもっといい選択肢があるのだ。

ちなみに、羽田空港で両替するのはおすすめできない。空港に着いてすぐのところにある Travelex の両替所が最も不利なレートを提示している。同じフロアにある SMBC 信託銀行の両替所と比べても 2 円くらい違ったので驚いた。同じ羽田空港の中でも出国エリアにあるみずほ銀行の両替所の方がよいレートだった。

以下、6 月 6 日時点で提示されていたレートから計算した。

  • Travelex: 1 SGD あたり 87.82 円、10,000 円を替えると 113.87 SGD になる
  • SMBC 信託銀行: 1 SGDあたり 85.03 円、10,000 円を替えると 117.61 SGD になる
  • みずほ銀行: 1 SGD あたり 84.15 円、10,000 円を替えると 118.84 SGD になる

現地で英語でやり取りすることを考えると羽田空港で両替を済ませたほうが安心だという人の気持ちもわかるけれども、実際は一言も喋らなくても現金をずいっと差し出すだけでもちゃんと両替してもらえるから、シンガポールについてからチャンギ空港で替えた方がいいのではないかなと思う。

羽田空港の Travelex と比べると約 10 % 違う!

証拠

適当なことを書き散らかしているわけではないですよ、ということで一応。

Travelex

SMBC 信託銀行

みずほ銀行

UOB

為替レートの変動では?

6/6 から 6/7 にかけて、そもそもの為替レートが円高SGD 安)になったのでは?

確かにその可能性も考えられる。せっかくここまで書いたので確認してみたよ。

Image from Gyazo

0.1 円(10 銭)ほど 円安(SGD 高) になっていたみたい。つまり日本円からシンガポールドルへの両替は若干不利になっていたということ。

  • 1 SGD あたり 79.189 円、10,000 円を替えると 126.28 SGD
  • 1 SGD あたり 79.293 円、10,000 円を替えると 126.11 SGD

これまでも「国内の空港で両替するのはレートが良くないよ」という話は聞いていたけれど、大した違いではないだろうと考えてあまり気にしていなかった。確か 2012 年にフィリピンに行ったときは成田空港で替えた気がする。

今回少し気持ちに余裕があったので各両替所のレートを比較してみようと思って記録してみたら、思っていた以上に差があったのでびっくりした次第。

※今回シンガポールで利用したところの中には、レートを表示しているディスプレイの撮影(写真、動画ともに)を禁止している両替所もあったのでそのあたりは要注意。

空港から市内へ

空港から市内に向かうにはタクシー、バス、地下鉄(MRT)などがあり、今回は MRT にした。

日本の Suica のようにシンガポールでは EZ-Link カードという非接触型 IC カードがある。MRT もバスもこれ一枚で乗れる。利便性が大きく変わってくるので短期滞在だとしても買った方がいいと思う。

今回は前回訪問時に購入したカードがあり、残高も 7 ドルくらい入っていたのでそのまま改札を通って乗車できた。

もし残高が不足している場合は券売機でチャージできる。確か現金だけでなくクレジットカードからもできたはず。あと日本でいう「チャージ」は英語では「top up」という。

ちなみに Suica (FeliCa) と比べると改札での処理は少し遅いので、日本で改札を通るときよりも気持ち長めにタッチする必要がある。台湾でも同じような感じだったかな。詳しいことは知らないのだけれど FeliCa が抜きん出て速いんだっけ。

SIM カードを調達

チャンギ空港から MRT に乗って、滞在先ホテルがある Dhoby Ghaut 駅まで移動した。平日の朝ということで周りには通勤通学の皆さん。カジュアルな服装の方が多かった印象。新聞を読む人、スマートフォンでゲームをする人、音楽を聴いている人、寝ている人、この辺は日本と変わらない。

駅ビルが Plaza Shingapura という大きなショッピングセンターになっていて、1 階に携帯キャリア StarHub の大きな店舗が入っている。到着した時点ではまだ開店前だったのですぐそばにあるスターバックスで待つことに。

スターバックスの店員さんはこちらの英語がたどたどしかったからか日本語を交えて対応してくれて、内心「自分の英語はまだまだですな」と感じた部分もあったけれど、でも嬉しかった。

しばらく待っていると開店時間になったので StarHub へ。


店員さん: Hello, may I help you?

私: Hello, can I get a tourist SIM?

店員さん:(あっちのカウンターで受け付けますので、あちらへどうぞ)

私: OK, thank you.

カウンターに行って再び

私: Hello, can I get a tourist SIM?

店員さん: (7 日間で 12 ドルのものと、12 日間で 32 ドルのものがあります)

私: 7 days is enough. (指さしつつ)This one please.

店員さん: (パスポートを見せてください)

私: Here you are.


という感じのやり取りを経て、無事 SIM カードを購入できた。

データ通信が 100 GB も付いているので安心である。5 日間くらいの滞在でたぶん 10 GB も使っていないと思う。

また、SIM カードのトレイを出すピンや外した SIM を入れる簡易ケースなども付いていて至れり尽くせりであった。

入れ替えて少し待つと通信できるようになったので、スマートフォン側の設定などは必要ないみたい。

(続く)

シンガポールに行ってきた

先日、4 泊 5 日でシンガポールに行ってきたので記録を残しておこう。

当初はベトナムの首都ハノイに行こうと思っていた。ハノイは物価が安く、食事も美味しいらしく、のんびり過ごせてよさそうだったが、ふと「目線引き上げ効果」的なものを評価軸においた場合はどうだろうか、と考えた。

きっと今のハノイでしか見られないもの、感じられないものもあるのだろうけれど、これまで行ったことがないし、英語もあまり通じないようだし、現在の自分がもつ受容体とマッチしていないのではないか、と思ったりして。

その点、シンガポールは過去 2 回行ったことがあるし、シングリッシュが強いとはいえ英語が公用語だし、物価はベトナムよりずっと高いとしても滞在することでよい刺激を得られるのではないかと思えてきたのであった。

そもそも、前回 2016 年に行ったときの体験もよかったのでシンガポールに対して好意的な印象を持っているというのもあるのだけれど。

参考リンク

手配

今回は羽田空港発着の ANA 便にした。航空券は下記サイトを両方見て探した。

シンガポール航空のよりよい条件の便があったのだけれど、検索サイトでは表示されていても実際に予約を取ろうと航空会社のサイトに遷移してみると not available で取れない、という状態だった。そういことはままあるらしい。bot が古いキャッシュを持ったままになっていたのかな?

宿泊先は彼女の方で手配してくれるとのことでお任せ。いつも agoda を使っているそう。

航空券はうかうかしているとすぐ値段が変わってしまうので、早めに条件の優先順位(日程、価格)をはっきりさせて、ある程度よさそうであれば取ってしまった方がよさそう。

準備

ガイドブックは 2015 年に買った『地球の歩き方』は持っていたけれど、最新のものを購入。書店に置いてあった 5 冊くらいを見比べた結果、以下のものにした。

10 地球の歩き方 Plat シンガポール (地球の歩き方Plat)

10 地球の歩き方 Plat シンガポール (地球の歩き方Plat)

出発

地下鉄から京急直通で羽田空港へ。

キャリーケースを預けて、出国ゾーン(っていうの?航空券持っている人しか入れないゾーン)に移動。

出入国審査(パスポート確認等、通称イミグレ)が日本人は有人カウンターではなく、顔認識 + パスポートスキャンの自動認証機械を利用できるようになっていた。全然待たされないので快適であった。

自動販売機は Suica が使えず、ペットボトルの水を買いたい場合はその辺のカフェ、もしくはドラッグストア的なお店をあたるとよい。

この時点で周りはほとんどが外国の人で、みんな身体も大きいし、違う言語を話しているしで少し圧倒される。

その辺のベンチに USB の口がついているので携帯を充電しつつ搭乗時間を待つ。

(少しずつ書き足していく予定)

Elm でランダムにテキストを表示させる(その 2)

先日から作っていた web アプリが一応できた。

こういうスプレッドシートに文章を入力して、こういうサイトでランダムに表示させる、というもの。(何に使うものなのかは雰囲気で察してもらえればと)

Google スプレッドシートからは JSON でデータを吐くことができる(GET でのリクエストに対応するための関数が用意されている)ので、そちらは特筆すべきことなし。

下記記事のサンプルを参考にして、サクッと書いた。

変更したのはシート C 列 enabled のチェックがオフになっている行は除外する点と、選択したシートではなく全シートを対象とした点かな。

/**
 * Sheet から object にする
 * @param {Object} sheet
 * @param {Object}
 */
function convertFromSheet(sheet) {
    var rows = sheet.getDataRange().getValues();
    var keys = rows.splice(0, 1)[0];

    // filetering
    rows = rows.filter(function (row) {
        // enabled == true
        return row[2] === true;
    });

    var result = {};
    result["sheetName"] = sheet.getName();
    result["rows"] = rows.map(function (row) {
        var obj = {};
        row.map(function (item, index) {
            obj[String(keys[index])] = String(item);
        });
        return obj;
    });
    return result;
}

/**
 * 各シートのデータを filter した上で object にする
 * @returns {Object}
 */
function getObjectFromSheets() {
    const sheets = SpreadsheetApp.getActive().getSheets();
  return { sheets : sheets.map(convertFromSheet) };
}


/**
 * web app として公開する
 */
function doGet(e) {
    const data = getObjectFromSheets();
    return ContentService.createTextOutput(JSON.stringify(data, null, 2))
        .setMimeType(ContentService.MimeType.JSON);
}

で、Elm ですよ。

汎用的なプログラミング言語ではなく、Web のフロントエンドを作ることに特化した言語。Dart とかもそういう感じなのかな?知らないけれど。 コンパイルして html を出力したり、JS を出力したりできる。

# html
$ elm make src/Main.elm --output=index.html

# js
$ elm make src/Main.elm --output=elm.js

静的型付けで型の不一致をすぐ教えてくれるのがよい、ということを少し Twitter で書いたけれど、それに加えて、言語とフレームワークが一体となっていてプログラムの構成などで迷う必要がないのもいいところ。

細かいところについては各種ノウハウなどあるだろうけれど、大枠では Elm way に乗っかっていけばよくて、他の人も同じ構成でやっているからブログ記事なども参考にしやすかった。

OCamlHaskell に興味を持っていて少しだけかじったこともあった(歯型がついたかどうかくらいのレベルだけれど)ので、文法などはそんなに苦労せず理解できた。あと最近出たばかりの書籍があって丁寧に解説されていてわかりやすかったな。公式のガイド An Introduction to Elm も何回も読んだっけ。

基礎からわかる Elm

基礎からわかる Elm

あと、こうやってパイプライン演算子 |> を使ってすっきり書けると気分が良い。

addLineBreak : String -> List (Html Msg)
addLineBreak note =
    String.lines note
        |> List.map text
        |> List.intersperse (br [] [])

もう少し何か書こうと思っていたのだけれど、ひとまずこの辺で。

Elm でランダムにテキストを表示させる

所用で(?)シンプルな web アプリを作ることになり、Elm で書いてみることにした。

要件としてはルーレットのような感じで文章をシャッフルしてランダムに表示するもの。もう少し作り込む予定だけれどひとまず載せておこう。

とりあえずの感想

  • 見よう見まねで書いていると値は immutable ということを忘れがちだった。
  • エラーメッセージが親切なのでギリギリやっていけるという感じ。
  • バージョンが上がるごとに結構いろいろ API が変わっているようで、ブログ等の情報が参考にならない場合も多い印象。
  • update の処理を連鎖させるのはどうしたらいいのか、よくわからなかった。
    • 結局 Task.perform で繋ぐ感じでやっているが正しいのか不明。
  • 公式のフォーマッター elm-format があるので助かる。
    • でもインデントがずれていると動かなかったりするので Go の gofmt と比べると少々頼りない気がする。

もし、JavaScript で書いたとしたら、オンラインで公開されている参考にできるサンプルの数が多いので、おそらく半分くらいの時間でできたのではないかと思う。

まぁこうやって新しい概念に触れて、チャレンジしてみるのも大事だからね。

コード

Elm はシンタックスハイライトに対応していないか、そうか。

(190404 追記)
言語指定を Haskell にすることでそれっぽい感じでハイライトされるようになった。

module Main exposing (Model, Msg(..), init, main, subscriptions, update, view)

import Array
import Browser
import Html exposing (..)
import Html.Events exposing (..)
import Random
import Task
import Time



-- MAIN


main =
    Browser.element
        { init = init
        , update = update
        , subscriptions = subscriptions
        , view = view
        }



-- MODEL


type alias Model =
    { sentences : List String
    , index : Int
    , sentence : String
    , shuffling : Bool
    , count : Int
    }


init : () -> ( Model, Cmd Msg )
init _ =
    ( { sentences = sampleSentences
      , index = 0
      , sentence = ""
      , shuffling = False
      , count = 0
      }
    , Cmd.none
    )



-- https://www.thetoptens.com/random-sentences/


sampleSentences : List String
sampleSentences =
    [ "I am so blue I'm greener than purple."
    , "I stepped on a Corn Flake, now I'm a Cereal Killer."
    , "Everyday a grape licks a friendly cow."
    , "Llamas eat sexy paper clips."
    , "Banana error."
    , "Don't touch my crayons, they can smell glue."
    , "There's a purple mushroom in my backyard, screaming Taco's!"
    ]


maxCount : Int
maxCount =
    20



-- UPDATE


type Msg
    = Pick
    | GetIndex Int
    | Tick Time.Posix
    | CheckCount Time.Posix
    | Shuffle Time.Posix


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Pick ->
            ( { model | shuffling = True }
            , Random.generate GetIndex (randomIndex model.sentences)
            )

        GetIndex i ->
            let
                s =
                    pickByIndex model.sentences i
            in
            ( { model | index = i, sentence = s }
            , Cmd.none
            )

        Tick newTime ->
            let
                c =
                    if model.shuffling then
                        model.count + 1

                    else
                        model.count
            in
            ( { model | count = c }
            , Task.perform CheckCount Time.now
            )

        CheckCount newTime ->
            ( resetStatus model
            , Task.perform Shuffle Time.now
            )

        Shuffle newTime ->
            ( shuffleSentence model
            , Cmd.none
            )


randomIndex : List String -> Random.Generator Int
randomIndex sentences =
    Random.int 0 <| List.length sentences - 1


pickByIndex : List String -> Int -> String
pickByIndex sentences index =
    let
        default =
            "this is default sentence."

        arr =
            Array.fromList sentences
    in
    Maybe.withDefault default (Array.get index arr)


resetStatus : Model -> Model
resetStatus model =
    if model.count == maxCount then
        let
            s =
                pickByIndex model.sentences model.index
        in
        { model | shuffling = False, count = 0, sentence = s }

    else
        model


shuffleSentence : Model -> Model
shuffleSentence model =
    let
        randomId =
            modBy (List.length model.sentences) model.count
    in
    let
        randomSentence =
            pickByIndex model.sentences randomId
    in
    if model.shuffling then
        { model | sentence = randomSentence }

    else
        model



-- SUBSCRIPTIONS


subscriptions : Model -> Sub Msg
subscriptions model =
    Time.every 40 Tick



-- VIEW


showBool : Bool -> String
showBool bool =
    if bool then
        "True"

    else
        "False"


view : Model -> Html Msg
view model =
    div []
        [ h1 [] [ text model.sentence ]
        , h2 [] [ text (String.fromInt model.count) ]
        , h2 [] [ text (showBool model.shuffling) ]
        , button [ onClick Pick ] [ text "Pick" ]
        ]

Ellie というオンライン開発環境(いわゆる playground 的なやつ)にも保存してみたけれど、表示されないかもしれない。

Elm の記事からヤギ画像を取り除く User Script を書いた

Elm とヤギ画像

Elm というプログラミング言語があって面白そうだなと思っているのだけれど、まぁ何というか、個人的にはアレだなーと思うところもあって。

ということで、User Script 書いてみた。

User Script

最近あまり聞かなくなった気がするけれど以前、Greasemonkey というものがあって、それの Chrome 版として Tampermonkey という拡張があった。

で、以下のスクリプトを登録することで目的を達成できた。

Qiita

// ==UserScript==
// @name         removeGoatQiita
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to remove images of goat
// @author       ryskosn
// @match        https://qiita.com/arowM/items/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    const imgs = document.getElementsByClassName('it-MdContent')[0].getElementsByTagName('img');
    for (const img of Array.from(imgs)) {
        img.parentNode.removeChild(img);
    }
})();

ちょっと雑かもしれないけれど、他のやり方が思いつかなかった。

elm-lang.jp

// ==UserScript==
// @name         removeGoatElmLangJp
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to remove images of goat
// @author       ryskosn
// @match        https://elm-lang.jp
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    const eyeCatch = document.getElementsByClassName('eyeCatch')[0];
    const moment = document.getElementsByClassName('moment')[0];
    eyeCatch.parentNode.removeChild(eyeCatch);
    moment.parentNode.removeChild(moment);
})();

それぞれのスクリプトを Tampermonkey のダッシュボードから設定する。

Image from Gyazo

190323 リカバリー中

2 月は自分のやるべきことに注力できていて、 結構いい感じで過ごせたのだけれど、3月に入ってから 低空飛行が続いている。

その要因として思い当たるものとしては、

  • 生活のリズムが少し変わった
  • イレギュラーなイベントも多々あった
  • 花粉症

といったところだろうか。

3/14 までは外部要因の影響が大きく、まぁこんなもんでしょうという 認識もあったが、その後の 1 週間もなかなか 2 月のようにはいかず、 現在リカバリーの真っ最中である。

どう考えても花粉症のせいだよね。まったくもう。

リカバリ

まぁ杉花粉に文句を言っても解決しないので、リカバリーについて考える。

何が問題かというと、2月と同じように行動できていないこと。 2月は守れていたルーティン、習慣がすっかりどこかに行ってしまった。

ここで悲観したり自己嫌悪に陥ったりするのはただの素人であり、 我々のようなもの(?)は、「あー、なるほどなるほど」と自身の状況 (続けていた習慣が途切れ、規律が乱れてしまっている現状)と、 それについてこれから対処しようとする自分を俯瞰して捉えるのだ。多分。

規律

まぁとにかく、復帰するためのアプローチとしては 「規律を取り戻すこと」を意識するのがいいのではないかと思う。

それも小さなところから少しずつでよくて、例えば、

  • 朝起きたらコップ半分の水を飲む
  • 脱いだ靴を揃える
  • 手洗い、うがいをする
  • 帰宅したら机の上にノートを開いて日付だけ書く

など、毎日続けられるようなことを意識して毎日続けていくのだ。

ある程度継続していれば、そのうちにそれをするのが当たり前になってきて、 都度意識する必要がなくなるので、空いた脳内メモリで他のちょっとしたことを やるようにするのがいいと思う。

規律と自己肯定感、あとは食事と睡眠、という感じで生活していれば 徐々に調子も上がってくるんじゃないかな。

OPAM、OCaml をアップデートする

OCaml コンパイラをインストール

まず opam 自体をアップデートする。パッケージマネージャは MacPorts を使っている。

$ sudo port upgrade opam

1.2 から 2.0 へメジャーバージョンアップということで多少コマンドが変わっているみたい。

opam switch list-available でインストール可能なコンパイラの一覧を表示する。

各種オプション適用版も含めて大量に表示されるのでコンパイラのバージョンだけを見るなら | grep base をつけてもいいかもしれない。

$ opam switch list-available
# or
$ opam switch list-available | grep base

最新のコンパイラ 4.07.1 をインストールしてみる。

$ opam switch create 4.07.1

バージョン 4.07 の変更点などはこちら。

各種パッケージをインストール

お好みで。

$ opam install -y utop
The following actions will be performed:
  ∗ install conf-m4     1          [required by ocamlfind]
  ∗ install ocamlbuild  0.14.0     [required by react]
  ∗ install dune        1.8.2      [required by utop]
  ∗ install ocamlfind   1.8.0      [required by utop]
  ∗ install jbuilder    transition [required by cppo, camomile, lambda-term]
  ∗ install base-bytes  base       [required by zed]
  ∗ install result      1.3        [required by lwt]
  ∗ install cppo        1.6.5      [required by utop]
  ∗ install camomile    1.0.1      [required by utop]
  ∗ install topkg       1.0.0      [required by react]
  ∗ install lwt         4.1.0      [required by utop]                        For the PPX, please install package lwt_ppx
  ∗ install react       1.2.1      [required by utop]
  ∗ install lwt_log     1.1.0      [required by lambda-term]
  ∗ install zed         1.6        [required by lambda-term]
  ∗ install lwt_react   1.1.1      [required by utop]
  ∗ install lambda-term 1.13       [required by utop]
  ∗ install utop        2.3.0
=====17 =====
$ opam install -y ppx_inline_test
The following actions will be performed:
  ∗ install sexplib0                v0.12.0 [required by base]
  ∗ install ocaml-compiler-libs     v0.11.0 [required by ppxlib]
  ∗ install ppx_derivers            1.0     [required by ppxlib]
  ∗ install base                    v0.12.0 [required by ppx_inline_test]
  ∗ install ocaml-migrate-parsetree 1.2.0   [required by ppxlib]
  ∗ install stdio                   v0.12.0 [required by ppxlib]
  ∗ install ppxlib                  0.5.0   [required by ppx_inline_test]
  ∗ install ppx_inline_test         v0.12.0
=====8 =====
$ opam install -y spotlib
The following actions will be performed:
  ∗ install ppx_tools_versioned 5.2.1 [required by ppxx]
  ∗ install seq                 base  [required by re]
  ∗ install ppxx                2.3.2 [required by ppx_test]
  ∗ install re                  1.8.0 [required by ppx_test]
  ∗ install ppx_test            1.6.0 [required by spotlib]
  ∗ install spotlib             4.0.3
=====6 =====
$ opam install -y ocp-indent
The following actions will be performed:
  ∗ install cmdliner   1.0.3 [required by ocp-indent]
  ∗ install ocp-indent 1.7.0
=====2 =====
$ opam install -y merlin
The following actions will be performed:
  ∗ install conf-which  1     [required by biniou]
  ∗ install easy-format 1.3.1 [required by yojson]
  ∗ install biniou      1.2.0 [required by yojson]
  ∗ install yojson      1.7.0 [required by merlin]
  ∗ install merlin      3.2.2
=====5 =====
$ opam install -y js_of_ocaml
The following actions will be performed:
  ∗ install uchar                0.0.2 [required by js_of_ocaml]
  ∗ install js_of_ocaml-compiler 3.3.0 [required by js_of_ocaml]
  ∗ install js_of_ocaml          3.3.0
=====3 =====

OCamlFormat というフォーマッタが開発中らしい。 gofmt みたいにカチッとフォーマットしてくれるのだとしたら嬉しいな。おって試してみるかも。

集中して仕事するクセ

いやー、何とか元気でやっています。
前回書いてから、もう 4 ヶ月くらい経ってるのか。早い。

最近の関心事としては、先週末くらいに以下のエントリを読んで、今さらながら「本当に集中しているか?」ということを考えるようになった。

いろいろあって、2 月からは 9 時から 18 時(休憩 1 時間)で、ほぼきっかり 8 時間勤務というスタイルでやっている。

それまでは遅くとも 20 時にはなるべく帰る、19 時台のときもあれば 20 時半とか 21 時を回ることもないわけじゃない、という感じだったので、2 月に入ってからは集中してやらないとすぐ 18 時になってしまうなーと感じてはいた。

でも、本当に集中してやっている時間がどれくらいあるだろうか、と自問するとどうだろう。

仕事の都合上、頻繁に割り込みタスクが発生して中断させられることがままあるという点を考慮したとしても、8 時間フルに集中してやっていると胸を張れるかというと難しい。(Toggl で時間を計ったりちょっとした工夫もしていたけれども)

そんなこんなで上記エントリを読んで、書かれているような 6 時間勤務の会社だと本当に集中してやらないと価値を発揮できないまま 1 日が終わってしまいそうだし、相応のプレッシャーも感じるだろうなと想像した。

ただ、

1 日 6 時間を継続して働き、成果を出し続けるというのは並大抵のことではない。ただこのことで会社に依存する時間をぐっとへらすことができるのは事実だし、6 時間という時間の使い方が慣れていく。

そして、

毎日集中して働き続けるはある意味、修行に近いと思う。ただそれになれることで集中して仕事するクセを付けられるのではないか?という考えに基づいている。

このようにも書かれていて、いずれも全くもってそのとおりだと思う。

最初はプレッシャーがあったり、しんどさを感じるかもしれないけれども、続けていくうちに「集中する筋力」が鍛えられていき、やがてはそれがその人にとっては普通の働き方になっていくのではないか。

頭は使わないと悪くなる一方だというし、文章も日頃から書いていないとスピードが落ちる。

同様に、ものごとに集中して取り組むスキル(?)というのも鍛えれば向上するかもしれないし、鍛えなければ緩やかに低下していく一方なのだとしたら、これは無視できないなーと思っている。

会社の制度も違うし、そのまま同じようにできるかというとそうもいかないかもしれないけれど、できる範囲で集中して仕事するクセをつけられるよう、取り組んでいきたい。

(早速月曜から意識してやってみているんだけどなかなかハードだ)

ホテル宿泊料金の変動について

それはどうなんだろう、と思ったことがあったので記録として残しておく。

澤氏の tweet から

他者の反応など

その 1

その 2

その 3

思ったこと

  • ホテル名称明記ヤクザ呼ばわりがなければ、ここまで引っかからなかっただろう。
  • 繁忙期やイベント時に高額な設定となることに対して「こっちの足元見やがって、チクショウ!」というような腹立たしい気持ちになったとしたら、それもしょうがないとは思う。
  • しかし、今回はホテル側が一方的に悪い話なのかというと、そうではないと考えている。

前提の推測

いずれも推測なので外れているかもしれない。

1. 宿泊予約を手配するタイミングが遅かった(と思われる)

  • 著しく高額に設定された部屋(今回の部屋)しか選択肢がない状況にあったらしいという点から。

2. 澤氏(が依頼したダイナースの担当者)の前にも当該ホテルを検討したユーザーはいた(と思われる)

  • 当該ホテルが料金設定を変更してから、澤氏(が依頼したダイナースの担当者)がアクセスするまでの間、同じ日程で宿泊施設を探している他のユーザーからも当該ホテルへのアクセスはあっただろう。
  • 上記の通りタイミングが遅かったと思われるので、その間、他のユーザーが当該ホテルに全くアクセスしていなかったとは考えにくい。

3. 「ホテルに宿泊する」以外の選択肢もあった(と思われる)

  • 福岡市内であればカプセルホテルや漫画喫茶などの、よりカジュアルな施設も利用可能だったのではないか。

もし著しく高額な料金設定ではなかったとしたら

  • 澤氏(ダイナースは省略)が宿泊予約を手配しようとした時点で、すでに他のユーザーがその部屋を確保して埋まっていたのではないだろうか。

言い換えると、ホテル側が著しく高額に設定していたからこそ、その料金設定のおかげで、(その金額を支払うことは難しい)他のユーザーは諦めざるを得ず、その金額でも払おうと思えば払える澤氏がアクセスするまで空室が残っていた、とも言えるだろう。

元の tweet へリプライしている方々も「そのホテルは酷いですね」という反応だけれど、高額な料金を払うくらいなら埋まっていた方がマシだったと考えるのだろうか?

だから「市場価格から大きく乖離している≒やり過ぎ」が気に入らないというのであれば、その空き室も埋まっていたものとして泊まらなければよかったのではないかと思う。

これは「相対取引なのだから文句があるなら買うな」とか「双方合意の上なのだから後から文句言うな」という話とほとんど同じようだけれど、部分的に異なるのではないかと個人的には思っている。

価値について

再掲

通常 10,000 円程の部屋が 48,000 円で提供されたことを指して「価値と見合わない価格設定を平気でしちゃって」と書いている。

これを読んで澤氏はホテルの施設・サービス等だけを「価値」の評価対象としているような印象を受けた。

このホテルが提供した価値はそれだけだというのは、何だか「原価はこれだけなのに販売価格が高い!」と言い立てる人と似通っている部分があるように感じるのは私だけだろうか。

  • 11 月下旬の 3 連休
  • 人気アーティストのコンサート x 2
  • 大規模な学会

といったイベントが重なり大混雑が予想される状況の中で、最低限安全で清潔で独立した個室で宿泊できるという部分にも、目に見えない価値が含まれていると思う。現に澤氏は漫画喫茶や野宿等ではなくそのホテルで宿泊することを選択したわけで。

「○○という状況で▲▲を提供する」という形で▲▲が通常時よりも高額な設定になるというのは観光地や、海とか山でもよくある話。

まぁ、提供価値に比べて値段が高い、という意見自体を否定するつもりはない。感じ方は人それぞれだし、感じたことを tweet するのも個人の自由だ。

ダイナース

すごそう。

再掲

ダイナースは他のカード会社・ホテルのコンシェルと比べて店舗側の手続きが煩雑で尚且つ手数料が高いので、ぼったくりたくなる衝動に駆られますね。

という店舗側の視点からのお話があった。

ダイナースがカード利用者へ還元している分の原資はどこからやってくるのだろうか。

結論

繰り返しになるけれども、48,000 円で申し込まざるを得なかったような人は、仮に当該ホテルがもう少し穏当な料金設定をしていたとしたら空室にありつくことはできなかったのではないだろうか。

(需要 > 供給の状況下で、手配のタイミングが遅めだったから)

もし、

  • 漫画喫茶や野宿ではなくホテルに泊まりたい
  • 高額な料金を請求されるのは許せない(請求するホテルが悪い)

というのであれば、早めに手配するというユーザー側で取りうる対策があったと思う。

澤氏もリプライしていた諸氏も、まさか知らなかったわけではないだろう。もちろん、その対策を取らなかった、取れなかったのはホテル側の責任ではないはず。

それもわかっていながら、ホテル名称を明記して

  • 「ぼったくり」
  • 「たぶんここヤクザが経営してると思うw」

と発言するというのはどうなんだろう。

仮にこれが、申し込み時には 10,000 円と聞いていたのに会計時に 48,000 円を請求されたとか、そういう話であれば上記の発言もわからなくもないけれど、そうではないよね?

1 ユーザーの体験としての話、個人の感想は全く否定しませんが、自身の責任を棚上げして一方的に誹謗しちゃってこの先いいことあるんかいな、というのがポイントでございました。

「言い方」大事ですねー!

(正直なところ、これは自分の認識や考え方がどこかおかしいのだろうか、という思いを拭い去ることができず、こうして書き連ねてしまった次第)

参考

混雑の原因

大きなイベントが重なっていたようだ。

料金の変動について

追記

2018-11-25 13:09 追記

私もこういう料金変動と無縁ではない。今年も例に漏れず出遅れた。

同日 13:40 追記

当社では平成19年12月より、MSNトラベルのツアー情報ページをマイクロソフト社から全面移管し、運営しております。大手旅行会社から中小、中堅旅行会社まで幅広く営業し、Webでのツアー販売のサポートをさせていただいております。

2010年 06月 01日

現在は関わっていないのかもしれないけれど。

 とはいえ、相手の意見や主張が明らかに理不尽だと感じたり、自分の不利益が大きくなるような事象に直面したりした場合には、自分が怒っていることを相手に伝える必要があります。その時に必要なのは、「事実を具体的かつ明確に伝え、自分の所感とは分けておく」という考え方です。

 怒っていると、自分の感情を中心にものを言いがちですが、まず大事なのは事実の共有です。

気をつけたい。

台湾に行ってきた

先日 2 泊 3 日で台湾に行ってきた。

以前 8 月くらいに彼女の台湾の友人が仕事で日本に来て、僕も一緒に食事したことがあった。そのことを思い出して、いつか行きたいね〜などと話していた際にちょっと調べてみようかと航空券の価格を確認したら案外安かったので、週末にサクッと行こうということになった次第。

LCC(Jetstar)とはいえ往復で 18,000 円くらい、ホテルが 2 泊で 7,000 円くらいだった。かなり安いね。

月曜、火曜と有給を利用して、土曜 -> 火曜の 3 泊で検討していたけれど土曜発だと結構価格が変わるのと、2 泊でもいいかという話になって、土曜の夜に成田を出て深夜 1 時くらいに台北の桃園(タオユエン)空港に到着、日曜、月曜を台北で過ごして、月曜の深夜 2 時くらいの便で発って火曜の早朝に成田着、というスケジュールだった。

感想

言葉

駅やデパート、タクシーなどの観光客と接する人たちはだいたい英語が通じるっぽい。それ以外のお店でも、英語か日本語が話せる人が一人はいるという印象だった。

茶器のお店や、お洒落なカフェの店員さんはかなり流暢に日本語で応対してくれたのでびっくりした。それだけ日本人のお客さんも多いんだろうな。

あと公園の広場みたいなところで掃除係のおばさんに「日本人?」って話しかけられて、そうですと答えたら

昔 1 年だけ大阪に行っていたことがある、私は日本が大好き!日本人はホンマ世界一!
(中略)
韓国出身なんやけど兄弟はみんなアメリカにおる。日本人は本当に一番や!
この辺は天王寺みたいなもんでガラ悪いから気ぃつけてや!

と勢いよくブワーっと話し始めたので、びっくりした。と同時に、そういうふうに思ってくれているというのはありがたいことだと感じた。

物価

  • 通貨はニュー台湾ドル(TWD)で、1 TWD が 3.7 円くらい。
  • 電車の運賃が安い。普通に 5、6 駅移動しても 20 TWD とか。
  • 食事もだいたい安いと思う。夜市のカジュアルなお店ではご飯ものが 50 TWD くらい、他のメニューも 100 TWDとかだった。

wi-fi

空港到着が深夜だったので通信会社の店舗は閉まっていたのと、公共 wi-fi があるというからそれで済まそうとしたが、ちょっと苦しかった。

公共 wi-fi はあまり繋がらなくてほぼ役に立たなかった印象。旅慣れていない素人は素直に SIM を買って入れるべきだった。

観てきたところ

龍山寺

多くの仏様、神様(道教)が祀られているメジャーなお寺。お参りの作法も日本とは異なるので見よう見まねでやってみた。長いお線香に火をつけてそれを持ちながら歩き回るので気が抜けない。

建物の柱や天井などの装飾もとても凝っていて綺麗だった。10 年以上前だけれどタイに行ったときにバンコク市内の寺院にて細かい装飾を見て感嘆したっけ。

日本、タイ、台湾と仏教というくくりでは同じだけれど様式は結構違いがあるね。大乗仏教小乗仏教とかそういう話だっけ?今度調べてみるかも。

迪化街

昔の建物が残る問屋街。新し目の小洒落たお店もあり、レトロな雰囲気もあり、で面白かった。好きな人は好きだと思う。

夜市

日本でいうお祭りの夜店と屋台と商店街が合わさっている感じ。人が多く、ごった返しているので、移動にも気を使う。

観光客だけでなく、若者グループや家族連れなどローカルの人たちも利用しているようだった。

故宮博物院

台湾の国立博物館。敷地が大きくいくつか建物があるようだった。今回見たのは本館のみ。館内が基本的に撮影 OK でみんな写真撮ってた。

HTC VIVE とのコラボレーション(?)の展示があった。いくつか種類があって、時間がなかったので試さなかったけれど係の人の PC を覗いた限りではいずれもかなり綺麗な映像で面白そうだった。

中正紀念堂

「中正」とは中華民国初代総統であった「蒋介石」の本名(=蒋中正)を指し、1975 年 4 月 5 日に亡くなった蒋介石に対する哀悼の意を込めて建てられました。