iPhoneの音声入力を使ってみた感想

今まで気恥ずかしくて音声入力を使っていなかったんだけど試しに使ってみたら案外悪くなかった

この記事では私が音声入力を使ってみたところでの感想を書く

便利だと感じたところ

  • 入力インターフェースが貧弱なときに便利だと感じた(フリック入力しかできないときとか)
  • キーボードがあったらキーボードのほうが早いのだけどフリック入力ってどんだけがんばっても速度が出ない

不満に思ったところ

  • 外で使うには周りの人に聞かれてしまうから使いづらいところ
  • いい間違えた時に修正するのがめんどう
  • ネットスラングを打とうとしても自分の思った通りに変換されない
  • 技術記事を書く場合特殊な固有名詞が出てくるため使いにくい感じがする

副次的な効果

  • 家の中でしゃべることが増えた
  • 正しい日本語を考えるようになった(文章的におかしいと認識の精度が悪くなるため)

今まで使っていなかった理由

  • 今まで使っていなかったのはそもそも認識の精度が悪いと思っていた
  • 仮に認識の精度が悪かったら、せっかくしゃべったのに認識の精度が悪いともう一回同じことをしゃべり直すことになるから、手間が増えそうというのがあった

 感想

  • 音声入力していてそういう事はなくはないけれど思っていたより精度が高くて、ちょっとブログ記事を書く分には悪くないと思った
  • 家の中で使うのはすごく便利だと思う
  • 外で使うのはやっぱり抵抗がある・・・

活用場面 

  • ブログ記事の下書きを書く時
  • チャット返信
  • ちょっと思いついたメモをする

以上、感想でした

 

 

1週間でやったこと(2017/08/28~2017/09/03)

やったこと

なんとなくConohaのiOSクライアントを自分用に作り始めている

github.com

  • Moya
  • RxSwift
  • Realm

このあたりのライブラリを使っているのだけど、iOSの開発をするのも久しぶりだし、Moya RxSwift は初めて触るので全然進まない

あと画面構成がほとんどTableViewになってしまった。とりあえず自分用だしいいか。

実家に帰った

法事で実家に帰った

ちなみに 9/9 にも法事で実家に帰る予定

法事だから仕方がない

仕事用にキーボードを購入した

www.instagram.com

一緒に働いている人がもう使わないというので、ちょっと触らせてもらった。 使ってみると結構いい感じだったので格安で譲ってもらった。

プリンセスプリンシパルというアニメにハマった

www.pripri-anime.jp

ネット配信がことごとく有料だったので見ていなかったのだけど、ニコニコ動画で期間限定無料配信だったので見てみたらハマってしまった

プリンセスの食えない女感が非常に好きです

SHIROBAKOというアニメを見始める

アニメ制作会社の制作進行の女の子が主人公の物語。

「納品に間に合うのか、間に合わないのか」というようなカタルシスがあって面白くもあり、胃が痛くもなる。

まだ5話くらいまでしか見ていないので、ネタバレはご遠慮ください。

雑感

やっぱり進捗だめですといった感じがする。

帰ったらアニメを見るのを辞めたらたぶんもうちょっと進捗が出ると思うのだけど、気づいたら見ているんだよなぁ・・・

capybaraコードリーディング(find, synchronize)

はじめに

capybaraでは find メソッドを使うとある一定の時間が経過するまでリトライし続けます。

今回は find メソッドをターゲットに、どうやってリトライし続ける動作を実現しているのかを見ていこうと思います。

ちなみに私は最初それを知らずに 「ページのロードが終わってないからかな?(適当)」なんてアタリをつけて sleep 1 をテストコードに埋めてたりしていました。

しかしそんなことをするくらいだったら Capybara.default_max_wait_time の時間を伸ばしたほうがいいです。 Capybara.default_max_wait_time とは findall メソッドを使用したときに探し続けるのに使用する最大の待ち時間です。

ちなみに調べた時点での capybara のバージョンは2.14.3です

コードリーディング

まずはエントリーポイントとなるfindメソッドを見ます

31 def find(*args, &optional_filter_block)
32   query = Capybara::Queries::SelectorQuery.new(*args, &optional_filter_block)
33   synchronize(query.wait) do
34     if (query.match == :smart or query.match == :prefer_exact) and query.supports_exact?
35       result = query.resolve_for(self, true)
36       result = query.resolve_for(self, false) if result.empty? && !query.exact?
37     else
38       result = query.resolve_for(self)
39     end
40     if query.match == :one or query.match == :smart and result.size > 1
41       raise Capybara::Ambiguous.new("Ambiguous match, found #{result.size} elements matching #{query.description}")
42     end
43     if result.empty?
44       raise Capybara::ElementNotFound.new("Unable to find #{query.description}")
45     end
46     result.first
47   end.tap(&:allow_reload!)
48 end

https://github.com/teamcapybara/capybara/blob/2.14.3/lib/capybara/node/finders.rb#L31

(ドキュメント) http://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Finders#find-instance_method

要素が見つからないシチュエーションを考える

要素が見つからない場合、

query.resolve_for

したあとに、下記の行が実行されて Capybara::ElementNotFound が発生します

43     if result.empty?
44       raise Capybara::ElementNotFound.new("Unable to find #{query.description}")
45     end

じゃあどこでリトライの処理をしているかというと

        synchronize

にリトライの実装があります。

synchronizeをコードリーディング

 77 def synchronize(seconds=Capybara.default_max_wait_time, options = {})
 78   start_time = Capybara::Helpers.monotonic_time
 79
 80   if session.synchronized
 81     yield
 82   else
 83     session.synchronized = true
 84     begin
 85       yield
 86     rescue => e
 87       session.raise_server_error!
 88       raise e unless driver.wait?
 89       raise e unless catch_error?(e, options[:errors])
 90       raise e if (Capybara::Helpers.monotonic_time - start_time) >= seconds
 91       sleep(0.05)
 92       raise Capybara::FrozenInTime, "time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead" if Capybara::Helpers.monotonic_time == start_time
 93       reload if Capybara.automatic_reload
 94       retry
 95     ensure
 96       session.synchronized = false
 97     end
 98   end
 99 end

https://github.com/teamcapybara/capybara/blob/2.14.3/lib/capybara/node/base.rb#L77

(ドキュメント) http://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Base#synchronize-instance_methodhttp://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Node/Base#synchronize-instance_method

Capybara::ElementNotFoundときには

 84     begin
 85       yield
 86     rescue => e

yield を実行中のはずなので、87 ~ 93行目の条件に引っかからない場合には

 94       retry

が実行され yield が再び実行されます。 これが Capybara::ElementNotFound が発生されなくなるまでループするという実装になっているということがわかりました。

おわりに

余談ですが、 click_link などのメソッドでも内部的には findメソッドを呼び出しているので結局要素が現れるまで待ってくれてるようです

Anemone gemをコードリーディングする(1)

これを読む

GitHub - chriskite/anemone: Anemone web-spider framework

anemone.gemspec

  s.require_path = "lib"

libを読むっぽい

lib/anemone/anemone.rb

require 'rubygems'
require 'anemone/core'

anemone/core ってのを読んでるっぽい

エントリーポイント

def Anemone.crawl(urls, options = {}, &block)
  Core.crawl(urls, options, &block)
end

ここであらためてAnemoneの使い方をおさらい

require 'bundler/setup'
require 'anemone'

url = 'http://kytiken.hatenablog.com/'
Anemone.crawl(url) do |anemone|
  anemone.on_every_page do |page|
    if page.doc
      p page.url.to_s
      p page.doc.at('title').inner_html
    end
  end
end

今日はここまで

次は

Anemone.crawlanemone.on_every_page が動くようになるのかを見ていく

転職してました

2017年3月までで前の会社を退職して、2017年4月から別の会社で働いてます

dockerを使って即席nginxをたてる(メモ)

いつも忘れるのでメモ

dockerコマンド

docker run -v /path/to/document_root:/usr/share/nginx/html:ro -p 80 nginx

参考URL

https://hub.docker.com/_/nginx/

今日の作業ログ

これは作業ログです。

作業内容

今日はwebpack hot module replacementの設定をしました。

今作っているやつのpackage.jsonとwebpack.config.jsを触っていました。

package.json

{
  "name": "frontend",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "actioncable": "^5.0.0",
    "babel-core": "^6.18.2",
    "babel-loader": "^6.2.7",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "material-ui": "^0.16.5",
    "normalize.css": "^5.0.0",
    "react": "^15.3.2",
    "react-dom": "^15.3.2",
    "react-redux": "^4.4.5",
    "react-tap-event-plugin": "^2.0.1",
    "redux": "^3.6.0",
    "redux-thunk": "^2.1.0",
    "webpack": "^1.13.3",
    "webpack-dev-server": "^1.16.2",
    "webpack-init": "^0.1.2",
    "whatwg-fetch": "^2.0.1"
  }
}

webpack.config.js

var webpack = require('webpack');

module.exports = {
  entry: './app/index.js',
  output: {
    path: '/',
    filename: 'bundle.js',
    publicPath: '/'
  },
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }
    ]
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
  ],
  devServer: {
    port: '4000',
    contentBase: './build',
    inline: true,
    hot: true
  }
}

ハマったところ

f:id:kytiken:20170209234714p:plain

Uncaught Error: [HMR] Hot Module Replacement is disabled. とか言われてブチギレていました

  plugins: [
    new webpack.HotModuleReplacementPlugin(),
  ],

を書いていなかったのが原因でした。

以上