カンテラの光の下で

dNaga392's memorandom

「レッド・アトラス」を読んで

地図は人間が生み出した最も美しい世界の描き方のひとつである。

そう思うほど地図好きな私がこの本を手にするのに時間はかかりませんでした。

レッド・アトラス 恐るべきソ連の世界地図

レッド・アトラス 恐るべきソ連の世界地図

本書はソ連時代の地図を多数収録し、比較考察され様々な観点から地図を説明しています。

しかしながら、体系的にブレることはなく地図の情報を余すことなく示しています。

本書は冒頭にて「推理小説」を自称しています。これは、実際には推理小説ではないのですが、筆者にとって地図がまさにそのような存在であると伝えてくれます。

特に私が気に入っているのが、序文の次の一節です。

 いまはGPS機能付きスマートフォンやカーナビが当たり前の時代。どの道を進めばいいか、どこで渋滞が発生し、スピード違反の取締装置がどこに設置されているか、音声で教えてくれる。もはや紙の地図は時代遅れかもしれない。
 それでも歴史的な意義と、その美しさは少しも色あせないのだ。

この一節だけで筆者にとって地図とは、ただの道具ではなく、さながら美術品のような存在であることが伝わってきます。

実際に筆者であるジョン・デイビス氏らが収集した地図は、現在や近代とも異なる冷戦期に作成されたもので、建物や道路を事細かに描く緻密さと必要な事実が全体に散りばれられて記された情報量が、なにより現在のものとは明らかに違うアンティーク調の色づかいは大変美しいものばかりです。

中学生のころに地図帳や社会の資料集を読んでいた時のような、わくわくした気持ちで読むことができました。

当然ながら現実を記した地図ですので、現在発行されている地図やインターネットで活用できる地図と比べることもできます。

本書の日本語版では特別付記として、ソ連で作成された東京の地図が収録されています。 東京の当時の情景が、ロシア語という異国の言葉によって描かれているそれはミステリアスな雰囲気があり、魅了されます。

地図好き、特に西洋の地図が好きな方であればきっと気に入ると思います。

2019/04/16には、下北沢の本屋B&Bにてトークイベントも開催されます。

bookandbeer.com

特定の地図について識者の方がトークする場はそうそうありませんので、ぜひとも足を運びたいところです。

【GitHub】issue template url ジェネレータを作った【GitLab】

Vue.jp を使って、GitHubとGitLabに対応する issue template url ジェネレータを作りました。

dnaga392.github.io

dnaga392.gitlab.io

GitLabを仕事で使っていて、issueのテンプレートが欲かったので作ってみました。

GitLabでのテンプレートには他の手法もあるのですが、URLでワンクリックというissue作成時の手軽さに魅力を感じました。

ひとまず自分が欲しい機能は実現できたので、あとは利用者がいたり作り込みたくなったりしたら更新すると思います。

Vue.js

普段Web開発をしておらず何かフレームワークを使ってみたかったことから、周りに利用者が多かったこととイケてる感じがしたのでVue.jsを使ってみました。

v-modelv-bind の使い勝手がよくて、なるほど人気が出るわけだと実感しました。動的ページ最高!

基礎から学ぶ Vue.js

基礎から学ぶ Vue.js

もう一つのテンプレート機能

GitLab で issue のテンプレートを実現する方法は次の2つを見つけました。

  1. URLにパラメータを指定する方法
  2. テンプレートファイルをリポジトリに配置する方法

次は方法1の参考記事と公式ドキュメントです。

qiita.com

Create a new Issue | GitLab

次は方法2の参考記事と公式ドキュメントです。

qiita.com

Description templates | GitLab

それぞれの特徴は次の通りです。

  1. URLにパラメータを指定する方法
    • README に URL を書いておけばワンクリックでテンプレートが展開できる
    • URL化するために文字列をエンコーディングする必要がある(テンプレートの編集コストが高い)
    • テンプレートの範囲はTitle、Descriptionなど
  2. テンプレートファイルをリポジトリに配置する方法
    • markdownを既定の位置に配置すればOK
    • issue 作成画面のテンプレート一覧からコンボボックスで選択する(1よりはissue作成の手間がある)
    • テンプレートの範囲はDescriptionのみ

どちらも多少なりリポジトリに干渉するので、好みで選ぶところがあるかと思います。

今回は作成コストと記述可能な範囲の広さから方法1を採用し、そのデメリットを軽減するためにツールを作った次第です。

Links

GitHub/GitLab それぞれのリポジトリです。

参考資料

【Qt】QSignalMapperは まいそうされます。

Image from Gyazo

画像のような複数のUIの操作に応じて一つのUIを更新する処理は QSignalMapper が担ってきました。

しかし Qt5 では QSignalMapper は非推奨とされ、 ラムダ式 への置き換えが推奨されます。

そこで、実際にどのように置き換えていくかをここに記録します。

従来の QSignalMapper を用いた手法

    // legacy style signal mapping
    mapper = new QSignalMapper(this);
    QVector<QPushButton *> foobarButtons({
        ui.fooButton,
        ui.barButton,
        ui.foobarButton,
    });
    for (auto const &button : foobarButtons)
    {
        connect(button, SIGNAL(clicked()), mapper, SLOT(map()));
        mapper->setMapping(button, button->text());
    }
    connect(mapper, SIGNAL(mapped(QString)), this, SLOT(foobarLabelUpdate(QString)));

処理の流れは次の通りです:

  1. QSignalMapper を作成する。
  2. sender(button) から QSignalMapper へ connect をする。
  3. QSignalMapper::map() が実行されるとき、 QSignalMapper から送出する内容を登録する。
  4. QSignalMapper::mappped() から送出される内容を受け取る slot (foobarLabelUpdate) へ connect する。

前提として必要なことは2つ、 QSignalMapper のインスタンス該当の操作に対応できるSlot そして、くじけない心です。

世界樹の迷宮II 諸王の聖杯(特典無し)

世界樹の迷宮II 諸王の聖杯(特典無し)

ラムダ式を用いた手法

    // qt5 style signal mapping
    QVector<QPushButton *> fizzbuzzButtons({
        ui.fizzButton,
        ui.buzzButton,
        ui.fizzbuzzButton,
    });
    for (auto const &button : fizzbuzzButtons)
    {
        auto const &text = button->text();
        connect(button, &QPushButton::clicked, [=] { ui.fizzbuzzLabel->setText(text); });
    }

処理の流れは次の通りです:

  1. sender(button) からラムダ式へ connect をする。

もう少し言うと、[=] ではじまるラムダ式なので送出していた内容を変数textに格納するという準備をしています。

これは比較のためにQStringで揃えているだけですので、buttonそのものを渡すことでより簡潔に書けます。

    for (auto const &button : fizzbuzzButtons)
    {
        connect(button, &QPushButton::clicked, [=] { ui.fizzbuzzLabel->setText(button->text()); });
    }

非常にシンプルになりました。 これなら気軽に書いていけますね。

参考資料

【Rust】Rustチュートリアルをはじめました

いまイケてる言語と噂の[要出典]Rustを触ってみました。

www.rust-lang.org

まだチュートリアル第2節の「数当てゲームをプログラムする」までしか進んでないですが、 よさが感じられたのでここで記録しておきます(チュートリアルは付録込みで21節まであります)。

比較的容易な開発環境の構築手順

プログラミングをする場合、何をやるにも最初は環境構築の壁が存在します。

Rust の場合、LinuxMacならコマンド一発な感じです。 ただ、Windowsの場合は次の依存関係があります。

記事執筆時点では、Microsoft Visual C++ Build Tools 2019 が最新です(Rust公式のインストールページにも反映されてますね)。

これはインストールページに書いてあることですが、僕みたいにうっかり読み飛ばす人は注意が必要です。

Install - Rust programming language

読みやすいチュートリアル

公式はバリバリ英語ですが、チュートリアルは日本語訳が存在します。

https://doc.rust-jp.rs/book/second-edition/

Rust のチュートリアルは、いわゆる教科書やリファレンスのような形式だったものとは異なります。

しかし、実際に動くコードを動かして、なぜそのように動くのかを一行一行、一つ一つ説明しています。 それは既知の方には退屈なくらい丁寧に述べられています。

これはどんな些細なことであってもキチンと解決させるという Rustacean (Rust開発者)の性格が見えるような気がします。

私はここが気に入ったのですが、一方で関連技術についてはあまり深く説明してないまま進めているので、 分かりやすいかは評価が分かれるだろうと感じます。

build と check が分かれている

Rust はコンパイルを実行する cargo build のほか、コンパイルできることを確かめる cargo check というコマンドを提供しています。

他のコンパイルを必要とする言語では、 コンパイルの実行でコンパイルできることを確かめています。 これは実行可能ファイルができるまでを指示するため、しばしば時間を要します。

Rust でも cargo build を実行すると同様のことは発生します。 しかし、 cargo check によりその悩みはいくらか軽減されます。

実際に開発していると、コンパイルできることを確かめたくなることがよくあるので、 cargo check は嬉しい機能です。

コンパイラのエラーメッセージ

Hello world でうっかり文字列の終了記号(")を付けそびれたとします。

fn main() {
    println!("Hello, world!);
}

Rust の場合、この異常を次のように関連する複数行を提示してくれます。

f:id:dNaga392:20190408232923p:plain

同様のバグコードが C++ の場合は次のようになります。関連するすべてのエラーを出しているので比べるとうるさく感じますね。

f:id:dNaga392:20190408233020p:plain

このため、親切さでは Rust がよさそうに感じます。

一方で、必ずしもわかりやすくはないとも感じました。 次のエラーメッセージでは match guess.cmp(&secret_number) の行が示されています。

f:id:dNaga392:20190408234908p:plain

しかし実際に問題があったのはそれより前の行でした。

        // 本当は次のように match をつける
        // let guess: u32 = match guess.trim().parse() {
        let guess: u32 = guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

        println!("You guessed: {}", guess);

        match guess.cmp(&secret_number) {  // この行がエラーメッセージに出ていた
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            }
        }

このあたりは C++ など他言語とおなじように慣れが必要かもしれません(勘が働くというやつですね)。

最後に

良いことと同じくらい注意したことを書いていますが、 Rust がかなり好きになりました。

なにより、公式ガイドが読んでわくわくする仕上がりになっているのがとても大きいです。

まだまだ最初の段階ですので、楽しんで読み進めて書いていきたいです。

ドヤ会のススメ( ・´ー・`)

ちょっと誇張タイトルです。

先日会社でドヤ勉強会(以降、「ドヤ会」と呼びます)を開催しました。

それまで不定期ながら会社で勉強会が開催されていたのですが、 しばらく開催されなくなっていたので、じゃあ自分がやるかと企画したのがドヤ会です。

ドヤ会のコンセプト

ドヤ会はドヤるための勉強会です(ここが重要です)。

自分にとって好きなことや調べたことを発表・紹介をしても、 いい評価がつくとは限りません。

だとしても、お前の発表はダメだとだけ言われると、 凹んでモチベが下がり発表しなくなります。

それを乗り越えてこそなどという根性論もありますが、 そういうのはそういうのが好きな人同士でやっててほしいです。

そこで、全体の利益は無視して、各自好きなこと・話したいことをテーマに 自分にとってのスゴイことを発表する会としました(つまりは自由発表ですね)。

ドヤ会のルール

初回ということもあり、今回は技術的な内容としかルールは設けていませんでした。

ただ、理念として次のことをお話ししました。

  • 「勉強会」という名前から受ける発表の敷居の高さを下げたい。
  • 自己評価の低い人にも発表をすることで自信をつけてほしい。
  • 発表をするときはドヤって、発表を聞くときはドヤらせてください。

多くはないものの、「勉強会」で自分が感じた問題点を踏まえた内容になっています。

どこにでも一言言って存在感を出したがる人はいるのですが、 ほとんどの場合は誰の得にもならないので、それを制限したいという意図があります。

アドバイスについては、話し手次第で毒にも薬にもなるため悩んだのですが、 社内開催ということもあり今回は特に制限をかけませんでした。

また、存分にドヤってもらうため、時間に制限はかけませんでした。

ドヤ会アフター

実際に開催して感じたことは次の通りです。

  • 思っていたより発表者が増えた。
  • 普段交流が少ない人の興味や関心を知ることができた。

一番驚いたのは、話したいって人が意外といたってことです。

構想をお話しして賛同してくれた先輩に勇気づけられて企画したものの、 せいぜい4人くらいしか集まらないんじゃないかと思っていました。

それが最終的には発表者5人、聴講のみ3人の計8人となりました。 会社全体で50人程度なので、1/5近くの人に参加いただいたことになります。

本人許可を取ってないので詳細は避けますが、発表は次の内容でした。

  • Docker を用いた現場の開発環境について
  • Markdownによる軽量予定管理ツールを作っていること
  • MP3のタグ情報について
  • React Hooks入門ライブコーディング
  • 時系列データに関するクラスタリング手法の紹介

発表者には他社常駐や元社員の方もいたため、 普段会わない方がどのような視点でどういうことに興味があるかを知れてよかったです。

ひとつだけ、企画側として気になったことは時間のことがありました。

発表が5人ということもあり時間を気にしていなかったのですが、 想定より遅くまで盛り上がってしまったので、キチンとやるなら時間制限を検討するとよいと感じました。

おまけ

似たような企画がないか調べたら出てきました。「そう、その目標を掲げたかったんだ!」という気持ちになったので紹介しておきます。

www.sjc-net.co.jp

まずは、「自信をもって、自らの考えを相手にわかりやすくかつ正確に伝える」ことを目標に掲げました。もう少し具体的に言うと、「プレゼンテーション」と「スモールトーク」の技術の習得と向上です。

【C++】ifstreamで一行戻す

ifstrean には「一行戻すため」の関数は存在しない。しかし、tellg()seekg() を用いることで実現できる。

std::ifstream myReadFile("route.txt");
....
auto oldpos = myReadFile.tellg();  // stores the position
getline(myReadFile, line);
myReadFile.seekg(oldpos);   // get back to the position

Go back one line on a text file C++ - Stack Overflow

参考資料

【地理】ポケモン新作の「ガラル地方」をスコットランド地方とみた

要点

  1. ポケモンの新作の発表があった。舞台は「ガラル地方」。
  2. 「ガラル地方」のモチーフをブリテン島と考える人たちがいた。
  3. 「ガラル地方」のモチーフをスコットランド地方と考え、類似性が挙げてみた。

「ガラル地方」とは

ガラル地方は、昨日のニンテンドーダイレクトで発表された、ポケモンの最新作『ポケットモンスター ソード』『ポケットモンスター シールド』の舞台です。

f:id:dNaga392:20190228225107j:plain
ガラル地方

いまのところ何人かがガラル地方のモチーフをブリテン島とみています。 私が最初に見かけた次の方もその一人です。

スコットランドの田舎町からロンドンを目指すというシナリオは、ストーリー的にもわかりやすく、現在主流の見方となっています。

ただ、この説の場合は地形に違和感が残ります。というのも湿地や平地が多いはずのイングランドに山地が重なってくるのです。

そこで私は「ガラル地方」上部の山地に着目し「スコットランド地方」ではないかと考えました。

ガラル地方とスコットランド地方の類似性

ガラル地方を正位置で見たとき、奥に山地が広がり手前に平地と森が広がっています。 かつ、手前は雲に隠れていて陸続きか海で途切れているかわかりません。

仮に手前の雲に隠れているところが陸続きだった場合、 スコットランドイングランドの一部を含めたブリテン島北部との類似性が見えます。

f:id:dNaga392:20190228233434j:plain
ブリテン島北部とガラル地方

この範囲を「スコットランド地方」として、具体的には次のような類似性があると考えます。

ガラル地方 スコットランド地方
奥の山地の町 インヴァネス(Inverness)・ネス湖(Loch Ness)
奥の山地 ハイランド地方(Highlands)
山地の手前の壁 アントニヌスの長城(Antonine Wall)
中央の上方の町 グラスゴー(Glasgow)
中央の右側の港町 エディンバラEdinburgh
中央の城壁の上の町 ダンフリース(Dumfries)
中央を横切る城壁 ハドリアヌスの長城(Hadrian's Wall)
中央下方の湖 湖水地方(Lake District)
下の島 マン島(Isle of Man)
手前の町 リーズ(Leeds)

f:id:dNaga392:20190301004249p:plain
ブリテン島北部とガラル地方(比較テキスト)

まとめ

こうして図で示すことで、よりスコットランド地方らしく見えてくるのではないでしょうか。 実際のモチーフがどうであったとしても、こうした地図の考察は楽しいものです。

もしガラル地方のモチーフがスコットランドであれば、スコットランドと「古い同盟(Auld Alliance)」の関係にあるフランスをモチーフにしたカロス地方との関係も気になりますね。

なお、ガラル地方のつづりは「Galar」だそうで、北欧神話ドワーフ「フィアラルとガラール(Fjalar and Galar)」と同じつづりです。 こちらの名前に関する考察をしても面白いかもしれませんね。

参考資料