Google Homeで音声アプリを作るときの3つのポイント

supporterzcolab.com

このイベントで初めてのLTをしてきました。
前の人のテーマもGoogle Homeというまさかの事態が起きましたが、スベることなく無事に終わりました。

会社で買ったGoogle Homeを使い、Dialogflowと組み合わせて会議室予約システムを作ったときの話です。 5分という短い時間用に作ったスライドなので、3つのポイントについて内容を少し補足しておきます。

本当に音声がベストか?

最新のテクノロジーは、やはり過剰な期待がつきもののようです。
今回のGoogle Homeは会社で買ったのですが、何を作ってほしい?といろいろな人に聞いたところ、
- 資料を印刷してほしい
- 退社時刻を知らせてほしい
- 電話に出てほしい
など、絶対自分でやった方が早いものばかり出てきました。

VUI(音声によるUI)が効果的なシーンは、音楽とIoT以外ではまだほとんど確立していません。イベントでGoogle Homeを持っている方何人かと話しましたが、どの方もいつGoogle Homeを使うとぴったりはまるのか、悩んでいる様子でした。
今回の会議室予約アプリは、「会議室で急な打ち合わせをしたいが、今空いている部屋は空室なのか、単にまだ使う人が来ていないだけなのかがわからず、その場でノートPCを開いて確認するのも面倒くさい」という実体験をもとに作ったものです。(これが他の人にもあてはまるかは、しばらく様子を見ないとわかりませんが)
他の人に使ってもらうアプリを作るときは、本当にスマートスピーカーでやるべきかをしっかり考えてからの方がよいです。

フローをシンプルに

スマートスピーカーは「話しかけるだけで使える」という簡単さが売りなのに、そのフローが複雑だと利用価値が減ってしまいます。
今回、非エンジニアの社員に使ってもらったのですが、基本的に覚えられるフローは一直線だけです。
もともとは、Google Homeを会議室の中に置き、その会議室が予定上空いているときとそうでないときでフローを分けていたのですが、2つのフローを覚えてもらえず、空いているときしか使われませんでした。
まだスマートスピーカー自体になじみのある人が少ないため、機能を多くするよりもフローを単純にすることを優先させる方がよいでしょう。

日本語の固有名詞は取扱注意

これは作ってみるまでわからなかったのですが、音声入力の場合、日本語は勝手に変換されます。
そのため、社員の名前を認識させたい場合、難しい漢字の場合は思うように認識されません。
対策としては、DialogflowのTraining機能を何度も使うことや、Googleの音声入力履歴を見ながらEntityにいろいろなパターンを登録していくという地道な作業が必要です。
ちなみに、英語の名前であれば、よくある名前がDialogflowのデフォルトのEntityとして用意されてたりします。いいなあ。

会議室予約アプリは今も鋭意改善中です。また進化したら書きます。
Amazon Echoも早く開けてセットアップしないと...

「若手エンジニアが転職で困らないように今から実践できること」に参加しました

supporterzcolab.com

紹介文の「会社にロックインされないために」というところに惹かれて参加しました。
自分自身、転職に興味があっても今すぐ転職はできないという感じなのですが、そういう人にこそ刺さるコンテンツでした。

ロックインされない自覚を持つ

今の自分、ロックインされてるんじゃない?という自覚はなんとなくあったのですが、まず「ロックイン」とは何かという定義から始まりました。
講師のmncさんによると、

  • プロダクトの要件定義
  • プロダクトに関する問題解決
  • 社内調整

こういう「社内に長くいるほど自然とやりやすくなる」ようなスキルしか持っていない状態が、ロックインされているということです。

それと反対のものが、いわゆる技術力。これは社内ではなく、市場で一般的に通用する考え方のことです。
企業に転職するのであれば、何かの分野について深い技術力を持つ、尖った人材の方が求められます。 社内の問題を考えるときも、社内の事情だけではなく、一般的な解を意識して考えなければ、気づかないうちにロックインされてしまいます。

アウトプット前提で仕事をする

転職をするとき、自分のブログや発表資料などは名刺代わりになるとはよく言われていますが、mncさんは面接で「ブログやってないの?」「githubは?」などと本当に聞かれたそうです。 そしてその時は何もアウトプットがなく、とても苦労したとのこと。

継続的なアウトプットをするには、「良い仕事をしたらアウトプットしよう」ではなく、何か仕事をしたら必ずアウトプットをするくらいの意識が必要です。
そうすれば、記事を作るために仕事に関連する技術的知識も自然と調べるようになります。 家に帰るとだらけちゃう、という人は、帰宅してからではなくオフィスでブログを書くのがおすすめだそうです。

mncさんのブログはこちら。

manchose.hatenablog.jp

コミュニケーションから逃げない

そして今回の最大にして最難関のポイントがこれ。
一人で勉強してるだけだと、どうしても業務レベルの知見までたどり着くのが難しいです。自分のやりたい分野の仕事を会社が常に振ってくれるわけでもないですし。
なので、人の力を使って機会をつかむのが重要になります。

mncさんは、副業をやりたくても自力では見つけられないという状況から抜け出すために、エンジニアの知り合いや勉強会で出会った人に「サービス作りたいんです!人手が必要になったら声かけてください!」とひたすら話しかけまくり、案件をゲットされたそうです。こういうの、自分がいちばん苦手なやつだ...

「恐れない」の一言に尽きる

最終的にはこういうことなのかなと思いました。
エンジニアになって日が浅いし、実績もないのですが、だからといって言われた仕事をこなすだけでいいわけないですね。
まずは社外にいる知り合いのエンジニアに連絡を取ってみようと思います。それこそ「久しぶりだから話聞きたい!」みたいな感じで。

【Vue.js】computedとmethodsの違い

会社のソフトウェアがVue.jsによってリファクタリングされることになり、急に身につけなければいけないことになった。
まさか自分がVue.jsをやるなんて、先週までは考えもしてなかったんだが...

今公式ドキュメントを読み始めたところだけど、computedとmethodsの違いがよくわからなかったので、そこだけしっかり調べてみた。

computedはプロパティ

ドキュメントでcomputedの説明を見てみる。

Vue インスタンスに組み込まれる算出プロパティ (Computed property) です。

ん、プロパティ?
ここがmethodsとの違いその1。computedとmethodsって何が違うの?という問いには、「プロパティとメソッドは違うだろ」という答えを返せる。

試しに、computedとmethodsの部分だけを変えた、同じ処理を書いてみた。

computed

<div class="use-computed">
    <p><input v-model="number" type="number"></p>
    <p>Even / Odd : {{ answer }}</p>
</div>
new Vue({
  el: '.use-computed',
  data: {
    number: '0'
  },
  computed: {
    answer: function() {
        if (this.number % 2 != 0) return 'Odd';
      return 'Even';
    }
  }
});

methods

<div class="use-methods">
    <p><input v-model="number" type="number"></p>
    <p>Even / Odd : {{ answer() }}</p>
</div>
new Vue({
  el: '.use-methods',
  data: {
    number: '0'
  },
  methods: {
    answer: function() {
        if (this.number % 2 != 0) return 'Odd';
      return 'Even';
    }
  }
});

HTMLのmustache構文に注目。同じanswerでも、computedの方はプロパティなので()がない。対してmethodsの方はメソッドなのでanswer()と書く。
またcomputedはプロパティなので、getterだけでなくsetterも定義できる。

computedはキャッシュされる

2つめの違いとして、computedは依存関係にもとづきキャッシュされる。
上の例では、入力した整数をもとに偶数か奇数かを判定する処理をしているが、仮にページを更新しても前の入力値が変わらなければ、answerが呼び出されてもfunction()以下の処理は実行されず、前に算出したプロパティの値がそのまま出力される。
もちろん入力値が変われば再び処理が走るが、そうでなければ何回呼び出されても計算が発生しないので、不要に処理が遅くなることがない。
これに対して、methodsはメソッドなので、入力値が変わらなくても、呼び出されるたびに毎回処理が走る。

methodsは計算量を増やしてしまうことが多いが、あえてmethodsを使う場合もある。
ドキュメントにもあるが、例えばDateオブジェクトを使って今の日時を返したい場合、computedを使うと日時の値がキャッシュされ、いつアクセスしても同じ日時になってしまう。
このような場合はmethodsにしなければいけない。

【Python】親クラスのプロパティ・メソッドを子クラスで使いたいときの書き方

書くたびに調べることになるので、忘れないようにメモ。

親クラスと同じメソッドを子クラスでそのまま使うとき

superなどで指定しなくても普通に使える。

class Animal:
    def __init__(self, legs):
        self.legs=legs
    def legnum(self):
        return "I have " + str(self.legs) + " legs!"
 
class Dog(Animal):
    pass

John = Dog(4)
John.legs # 4
John.legnum() # "I have 4 legs!"

Pythonでは、指定したメソッドがクラス内で見つからない場合、親クラスまでたどって探してくれる。

親クラスのメソッドを使って別のメソッドを定義するとき

superが必要。でないとローカルスコープの変数とみなされ、NameErrorになる。

class Cat(Animal):
    def greet(self):
        return "Hello " + super().legnum()

Tom = Cat(4)
Tom.greet() # "Hello I have 4 legs!"

親クラスのプロパティと子クラス独自のプロパティを併用したいとき

今までの例は、子クラスで独自のコンストラクタを何も書いていなかったが、
子クラスでも独自にコンストラクタを立てると、親クラスのコンストラクタが完全に上書きされ潰されてしまう。 そうならないよう、superを使う必要がある。

class Mouse(Animal):
    def __init__(self, legs, ears):
        super().__init__(legs)
        self.ears = ears
    def greet(self):
        return "Hello " + super().legnum() + " And " + str(self.ears) + " ears!"  

Jerry = Mouse(4, 2)
Jerry.legs # 4
Jerry.greet() # "Hello I have 4 legs! And 2 ears!"

【MySQL】カラムがNULL値を取りうるときの検索条件の書き方

最近MySQLを扱う業務をやってみたら、がぜん興味が出てきて、この機会にちゃんと勉強しようと思い立った。
今回は業務で少しはまった、空文字を絞込でうまくはじく書き方について。

空文字をはじきたい

例えば、コンバージョンポイントと会員IDというカラムがあって、両方CHARやVARCHAR型を取る。そして会員IDはnull値も取りうるとする。
このとき、会員IDがある行だけを絞込みたくて、こんな感じのクエリを書いてしまった。

SELECT cv_point, user_id FROM table WHERE user_id IS NOT NULL;

これだとnull値しか弾かれず、空文字は弾かれない。null値と空文字は違う。
正しくはこう。

SELECT cv_point, user_id FROM table WHERE user_id != '';

これで空文字が弾かれる。ちなみにnull値が許可されているカラムでも、この書き方でnull値も弾くことができる。

特定の値以外に絞り込みたい

例えば、会員IDがaaaでない行に絞りたいとき。

SELECT cv_point, user_id FROM table WHERE user_id != 'aaa';

これで良いときが大半だが、もし会員IDのカラムがnull値を許可している場合、これだとnull値が入ってこない。
そのときはこう書く。

SELECT cv_point, user_id FROM table WHERE user_id != 'aaa' OR user_id IS NULL;

初めてのテーブルでは、null値を許可しているかなどをチェックしてから触るようにしよう。

「オブジェクト指向言語解体新書」が神ってた話

10月に行われた技術書典3、行きましたか?
私も当日いろいろ本を買ったのですが、その中の一冊「オブジェクト指向言語解体新書」が、今年読んだ本の中で一二を争うレベルですばらしい内容だったので、感想を書き残しておきます。
※技術書典から1ヶ月以上経っているのは、単に積ん読してたからです。こんなにいい本だとは思わなかったもので...

f:id:Udomomo:20171202203947p:plain:w200

http://shop.comiczin.jp/products/detail.php?product_id=34612

オブジェクト指向は、初心者でつまづかない人はほぼいない、一種の鬼門なわけですが、
入門書では何かしらの比喩を使って説明しているものが多いです。
例えば「哺乳類を継承した犬と猫がいて、両方とも「鳴く」「歩く」などができる」みたいな。

こういう比喩を使う理由もわかります。全くの初心者が相手の場合、「なんとなくわかる」レベルでもいいのでとりあえずコードを書いてもらわないと挫折しやすいからです。
ただ、ある程度基礎が身につき、少し複雑なコードを書こうとすると、比喩に頼った理解だけでは限界があります。
私自身、クラスを使った処理は書けるものの、それがどういう仕組みなのかを説明できず、is-aポインタや多態など少し抽象的な考え方になるとさっぱりでした。それでも仕事をまわすことはできるのですが、どうも落ち着きません。

この本は、そんな悩める「中の下」レベルの人たちのために書かれた本です。

f:id:Udomomo:20171202204004p:plain

これは裏表紙の画像です。この図がこの本のコアであり、2章以降でその意味が詳しく説明されています。
オブジェクト指向をマスターした方にとっては常識かもしれませんが、私はこんな内部の処理まで想像したことがありませんでした。
個人的には、こうやって中の仕組みを丁寧に説明してくれる方が、下手に比喩を使うよりも理解しやすいです。

この本では比喩は一切使われていません。それでも(むしろそうだからこそ)文章がとてもわかりやすく、一つひとつ理解していけます。
1章で「オブジェクト指向として本当に重要な性質は『多態』です」と書いてあって「?」となったのですが、後半まで読むと「多態すげぇ...」と言えます。
(皮肉なことに犬や猫の比喩も、この本を読むことでやっと真の意味を理解できました)

また、この本では特定の言語に縛られず、オブジェクト指向言語全般を扱っています。サンプルコードもJava, Python, JS, Rubyなどいろいろ出てきます。
この本の意図ではないかもしれませんが、オブジェクト指向という共通の考え方のもとでいろいろな言語に触れたことで、新しい言語に対する抵抗感が減った気もします。

もちろんこの本を読んだからといって、すぐに自分で見事な設計ができるようになるわけではないですが、
まず先輩のコードや良いライブラリのコードがどのような意図で設計されているのかを理解するのに役立ちそうです。

他に買った本も早く読まないと...

【Objective-C】this class is not key value coding-compliant for the keyエラーについて

忘れないうちにメモ書き。
Objective-CiOSアプリを作っていて、presentViewControllerを使って画面遷移を実装しようとしていた。
StoryBoardにボタンを設置して、nextBtnという名前でコードと紐付け、処理を書いてRunするとエラーが。

this class is not key value coding-compliant for the key nextBtn

紐付けはあってるはずだけどなあ、と悩んでいたら、この記事を見つけた。

humangas.hatenablog.jp

まさにそのままの内容。この通りにStoryBoardのソースを見てみたら、なぜか遷移先の画面のヘッダファイルの中にnextBtnがあった。
この行を消してビルドし直したら解決。無事に画面遷移できた。

Swiftではこんなこと起こらなかったけどなぁ。
StoryBoardを使わないで開発する人を多く見かけるけど、その理由がだんだんわかってきた。