JDBな人生  専門的なことから日常的なことまで~ まぁ自由きままに書いていきます。
2016年12月 / 11月<< 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 >>01月

アクセスランキング

[ジャンルランキング]
コンピュータ
381位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
50位
アクセスランキングを見る>>

外国語学習と辞書

 お久しぶりです。いよいよ冬っぽくなってきました。

 最近、イタリア語の学習に少し力を入れています。どのように学習を進めていくかというところは色々とあるのですが、やっぱり文章を口に出して読んでみるというのは欠かせないですね。プログラミング言語ならともかく喋って使うための言語なので、それを抜きにして習得というのは難しいだろうと。ということで、2言語分の字幕ファイルを並行して再生&音声認識で音読する、なんていうツールを作って使っています。数時間で作った割には中々良い練習になっている気がします。好きな話の好きなシーンを朗読(?)するのは意外と楽しいですね。ただ効果のほどはまだよく分かりません。一週間使ってみて、会話の授業で少し口が動きやすくなったかな?気のせいかな?というところです。

 さて、どの言語でもだいたい2000語を使いこなせばある程度の会話はできる、という話があります。ちなみに論語も約2000語の語彙で書かれているそうです。そうすると、いかにしてその2000語を習得していくかというところが問題になります。色々と論じられているところかと思いますが、これは堅苦しい論文ではないのでそこは飛ばすとして(何か面白い参考文献などあったらご教授ください)、2000語を単に頭に入れるだけであれば、そんなに難しくないはずです。その言語の学習に全力を注ぐのであれば、一ヶ月もあれば一問一答はできるようになると思います。
 じゃあ一ヶ月で話せるようになるのかというと、なかなかそう簡単な話でもない。知っての通り、単語学習の最も弱いところは、文脈がほとんどと言っていいほど無いところだと思います。これを克服する手段としては(そしてある意味では対極と言えるのが)、一定のストーリーの中で単語を学んでいく、という方法があります。ちょうど中学高校の英語の教科書の感じです。これもこれで、特に総仕上げとしては良いのですが、一つの文脈で繰り返し学んだところで、どこまで応用が効くのか、というところには疑問が残ります。そもそも単語の使い方を練習する上で、数百語の大き文脈の情報が必要なのか、という点も怪しそうです。

 そこで単語学習と長文による学習の中間に何か無いのか、と考えるのですが、これは辞書の例文なんじゃないかと思います。辞書を参照するとき、時間がないと一対一の対応を見て終わりになりがちですが、辞書の例文というのはなかなかひねりが効いていて、読んでいて普通に面白いと感じられます。また例文というのは、その語の中心的な意味ごとに、だいたい2、3は載っているものなので、複数の例文に同時に触れることで、その語のニュアンスをより正確に感じ取ることができる、というところも見逃せません。特に電子辞書であれば類語や対義語にも即座にアクセスできるので、一つの語を「ひとつの文脈における使用」「語彙の分布の中の位置付け」の二つの視点から見ることができます。単語を応用していくために必要な感覚は、こうした方法で複数の接近した語の、複数の例文に触れていく中から「でも」付けていくことができるのではないかと思います。
 近頃は特にアクティブラーニングが話題になっていますが、まさにこのような「些細な違いに気づく」「気づいたことを学習に活用する」という姿勢が問われているわけです。
 余談ですが、例文をつなげてストーリーを作るというのも良い練習になるかもしれません。

 とは言っても、「順番をつけて学習していく」「いくつかの同じ例文を反復でチェックしていく」とやろうとすると、電子辞書と言えども少し面倒ではあります。既存の学習アプリにそういうものがあれば良いのですが、ただでさえコンテンツの多くないイタリア語学習、となると…。
 本でも実現できる語学ツールをあえてスマホのアプリとして作る利点は、何と言っても圧倒的な手軽さです。本を持ってきてページをめくる抵抗感よりも、手元のスマホでパッとアプリを起動する手軽さは、比べ物にならないと思います。(通知に妨害されるリスクは各々で対処ということで)この季節であればなおさらです(?)。次いでゲーム感覚で学習できる、学習状況を管理してくれるというところでしょうか。
 また語学に限って言えば、近年のデータの蓄積を活用して、特定の表現がどの程度一般的か、ということも判定できるわけです。例えばある単語の例文の一部分を、類語・対義語や同じ分類の語(色なら青を赤と言ってみるなど)で置き換えて、その表現が認められるかどうかをチェックする、なんていうこともできます。表現として応用していくという点では、このような機能を載せたアプリが出ても良いとは思っているのですが…。なかなか出ませんね。

 ただ、ストーリー中心の学習の良いところして、(上手く作られている前提ですが)展開の面白みがある、という点があります。いくら例文にひねりが効いていても、そのように物語が展開していく面白さにはそうそう勝てないのかなあ、とも思います。この辺を考えると、例文の代わりに、あるストーリーの中でその語が使われている文章に着目する、というやり方もあるのかもしれません。
 語学が積み上げ式だということを考えると、はじめの500語は詰め込みで学び、以後は和訳なしで例文を2、3参照しながらどんどん学んでいく、という方法もあるのかもしれません。

 なかなかよくわかりませんが、見て読む、読んだ表現を使う、というところはやっぱり重要なポイントだろうと。何か良いアイデアでも思いつけばアプリか何か作ってみようと思います。
   最近考えていたこと    TB(0)    CM(0)    EDIT    ページ↑

WEBアプリ vs. ネイティブアプリ論争の決着?

 お久しぶりです。ずいぶん長いこと広告が表示されていました。

 先日、こんな記事(↓)を見かけました。お約束のこの話題ですが、なんと決着がついたとのことです。

HTML5 vs. Native: The Debate Is Over - DZone Mobile
https://dzone.com/articles/html5-vs-native-the-debate-is-over

 大雑把に要約すると、①市場はネイティブ開発を選んでいる②なんだかんだ言ってやっぱりそれが一番良い、という内容です。

 筆者がWEB推しなのは読者の皆さん(?)であればご存知かと思いますが、ここ一年ちょっとiOS/Androidのネイティブアプリの開発に携わってきて、「UXを第一に考えるならやっぱりネイティブ開発じゃないとなあ」と漠然と感じています。

 ブラウザの対応能力の限界という意味もありますし(それこそいわゆる音ゲーをWEBでというのは反応・処理速度から言って厳しいと思います)、iOS/Androidともに見過ごせない新機能がいくつも追加されている中、その端末上で引き出せる最高の使用感というものを実現するためには、ブラウザの中だけでは制限が大きすぎます。WEBベースだと実現しにくい機能はいくつもありますが、その中でも特に通知や連携は重要、重大な要素です。

 記事中では、他にセキュリティはどうか(保存領域の安全性)、通信環境が悪い時はどうか、という点にも触れていますが、これらについてはそんなに大きくとる必要は無いと考えています。
 前者については、まずHTML5のストレージのセキュリティはそんなにざるではないはずですし、WEBアプリはともかくハイブリッドアプリにすれば、トークン類の保存だけはOSの機能を使う、という対応もできることがあります。
 後者については、そもそもネイティブアプリの中にもオフラインではほとんど使えないものがありますし、上手く設定さえすれば、オフラインで全く使えないという事態は避けられます。ただし、この設定自体がややこしいことと、ユーザデータをどう保持しておくか、という点が悩ましく、また工数増加に繋がることは指摘する必要があります。

 じゃあ結局どっちなんだ、という話ですが、やはり「スマホアプリ」というメディアの魅力を最大限引き出すためには、ネイティブでしっかりと作り込んだ方が良いと思います。この点については経験上でも、先ほどの記事を念頭に置いてもはっきりと言えます。
 一方で、OSのサポート・端末の性能向上という意味でも、ライブラリの充実という意味でも、ハイブリッド開発を支援する各種ソリューションの進歩という意味でも、WEBベースのアプリを開発する基盤はかなり整ってきています。そうした点を考慮すれば、多少の妥協の上でWEBアプリやハイブリッドアプリの形を選択するというのも、「今となっては」立派な選択肢の一つだと言えるはずです。Facebookが撤退した頃と比べれば状況はずいぶん改善されています。
 それこそiOS, Androidで動くのは当然のこと、B2B向けにWindows Phoneにも展開したい、でも開発リソースがあまりない、とかいう状況だったら悪くない選択になるかもしれません。そんな状況なら進出するな、という気もしますが…。

 最後に一つ付け加えておくと、

Welcome
http://docs.nativescript.org/

 最近知ったのですが、こんなものも登場しているようです。TypeScriptとAngular(の新しい方)を使って、ネイティブアプリをビルドできるとかいう話です。これはこれで今後の展開が面白そうですね。機会があれば少し使ってみようと思います。そのうちレビューの記事でも書くかもしれません。
   プログラミング/開発全般    TB(0)    CM(0)    EDIT    ページ↑

input type="file"の隣に画像のプレビューを表示する

input type="file"を探して勝手に画像のプレビューを表示するスクリプトです。
画像じゃなくてもプレビューを出そうとしますが、まあそれはちょこっと弄れば直せるはずです。ファイル名をチェックするとかですかね。

(function() {
  if (typeof FileReader == "undefined") return;
  document.addEventListener("DOMContentLoaded", function() {
    var images = [];
    Array.prototype.forEach.apply(
      document.getElementsByTagName("input"), [
        function(input, index) {
          if (input.type != "file") return;
          var image = document.createElement("img");
          image.width = 150;
          input.parentNode.insertBefore(
            image,
            input.nextSibling
          );
          images[index] = image;
          input.addEventListener("change", function() {
            if (!input.files[0]) return;
            var reader = new FileReader();
            reader.addEventListener(
              "load",
              function() {
                images[index].src = this.result;
              },
              false
            );
            reader.readAsDataURL(input.files[0]);
          }, false);
        }
      ]
    );
  }, false);
})();

割と使い所がありそうなのであげておきました。参考までに。
   JavaScript    TB(0)    CM(0)    EDIT    ページ↑

xSVをテーブルにする

近頃は(というほど近くもないですが)、JavaScriptのArrayも色々と拡張されて、forEach()やらmap()やらが使えるようになっています。例えばTSVをTableにするようなスクリプトもこんな感じですっきりと書けます。

var tsv2Table = function(tsv, table) {
  tsv
    .split(/\r\n|\r|\n/)
    .map(
      function(row) {
        return row.split('\t');
      })
    .forEach(function(cols) {
      var tr = table.appendChild(
        document.createElement('tr')
      );
      cols.forEach(function(col) {
        tr.appendChild(
          document.createElement('td')
        ).appendChild(
          document.createTextNode(col)
        );
      });
    });
}

少し変えればCSVや他のxSVにも対応できます。
といっても、もはやこの程度ならググって持ってくるよりも自分で書いたほうがはやいかもしれません。

forEachもmapも一部の古いブラウザでは対応していませんが、CSSや他のAPIの対応状況を考えればどのみち切り捨てざるを得ないので、そんなに気にしなくて良い感じもします。それでももし使いたければ、MDNに互換のコードがあるのでそれをコピペすれば大丈夫です。

Array.prototype.forEach() - JavaScript | MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

#こういうコードってこうやって載せるよりGitHubとかにあげたほうがいいのかな…
   JavaScript    TB(0)    CM(0)    EDIT    ページ↑

Kotlin + Mockitoでany<T>()やeq<T>()を使いたい

今年頭から、APIの開発をMojolicious/PerlからSpring Boot/Kotlinに移行しています。今回は初のKotlinの記事です。

KotlinはJava完全互換を謳っているので、当然Java向けのモックライブラリであるMockitoもきちんと動くということになるはずです。しかし、実際には以下のような状況ではうまく動きません。

java - Is it possible to use Mockito in Kotlin? - Stack Overflow
http://stackoverflow.com/questions/30305217/is-it-possible-to-use-mockito-in-kotlin

まずモック対象のメソッドがこんな感じだとします。
ここでのポイントは引数の`String`がNon-Nullになっていることです。
class UserService{ 
    fun findUserByToken(token: String) {
    // 定義
    }
}

そしてモックを実行します。「特定の値が指定されたとき」であれば次の書き方ができます。
Mockito.doReturn(dummyUser).`when`(userServiceMock)
    .findUserByToken("token string")
Mockito.doReturn(dummyUser).`when`(userServiceMock)
    .findUserByToken(Mockito.eq("token string"))

条件を特に指定しない場合、次の書き方ができます。
Mockito.doReturn(dummyUser).`when`(userServiceMock)
    .findUserByToken(Mockito.anyString())
Mockito.doReturn(dummyUser).`when`(userServiceMock)
    .findUserByToken(Mockito.any())
Mockito.doReturn(dummyUser).`when`(userServiceMock)
    .findUserByToken(Mockito.anyObject())

さて、この記事にたどり着いた人ならお分かりかと思いますが、これらの5つの記法のうち、実際に動くのは最初の一つのみです。
こんな例外が発生します。
java.lang.IllegalStateException: Mockito.any() must not be null

その原因はMockitoの実装にあります。MockitoのSourceを見ればわかるのですが、`any()`や`anyObject()`を呼ぶと何が起きるのかというと、
①内部で条件の登録を処理する
②メソッドの戻り値としては`null`を返す
という具合です。
https://github.com/mockito/mockito/blob/master/src/main/java/org/mockito/ArgumentMatchers.java
public static <T> T any() {
    return anyObject();
}

public static <T> T anyObject() {
    reportMatcher(Any.ANY);
    return null;
}

この戻り値`null`はどこに行くかというと、mockされた`findUserByToken(token: String)`に行きます。が、問題はこのtokenはNon-NullなStringだということです。親切なKotlinは、このようなNon-Nullな引数を持つメソッドを呼び出すときに、事前に「渡す予定の」引数がnullかどうかチェックしてくれます。

つまり、テストコードがKotlinのSourceからJavaのコードにコンパイルされるときに、このようなメソッド呼び出しは
①引数として渡す予定の値がnullかどうかチェックする、nullなら例外を投げる
②実際にメソッドを呼び出す
という2段階の処理として生成されるということです。KotlinのNon-Nullの実装の機構がそうなっている、という話ですね。
そのため、any()の戻り値がmockされたuserServiceのインスタンスに届く前に、Kotlinのnullチェックに引っ掛かってしまい、敢え無く例外で落ちる、ということになるわけです。

解決策は、このnullチェックを何とかしてくぐり抜ければ良いということになりますが、そのための方法が、「総称型扱いでnullを渡す」というものです。この場合だと、「なぜか」上記のコンパイル時の処理で①(渡す引数のnullチェック)が省略されます。Kotlinの実装依存の解決策といえばそう、ということになりますね。
fun <T> nullNotNull(): T {
    return null as T
}

// 落ちる
userServiceMock.findByToken(null);

// 落ちる
userServiceMock.findByToken(null as String);

// 落ちない
userServiceMock.findByToken(nullNotNull());
※Kotlinでは「渡す予定の引数のnullチェック」と「引数としてもらった変数のnullチェック」の両方を行うので、これがmockでなければ三つとも落ちます。ここではMockitoが中身をオーバライドするので、引数としてもらった変数のチェックは実行されません。

一般的な解決策としては、次のようなclassを作っておいて、Mockito.any()やMockito.eq()の代わりに使えばなんとかなります。
class KotlinMockitoHelper {
    companion object {
        fun <T> any(): T {
            return Mockito.any()
                    ?: null as T
        }

        fun <T> eq(value: T): T {
            return if (value != null)
                Mockito.eq(value)
            else
                null
                        ?: null as T
        }
    }
}

なんだかすっきりしない結論ですね…。
とりあえず、Stack Overflowで出ていた解決策でどうして解決できるんだ??と調べてみた次第です。改めてポイントをまとめると、
①Mockito.any()の戻り値はnullである、
②<T>に対してはnullチェックをサボる、というところです。
これだと、今後の実装でまた動かなくなる、ということもあり得ると思います。まあ、モックするというテスト手法は下火になりつつあるという話もあるので、モックせずにうまく書いていく、という方針をとるのも手なのかもしれません。
   Kotlin    TB(0)    CM(0)    EDIT    ページ↑

Picture of the day: しらすのピザ

お久しぶりです。またまた広告が賑やかになっています。

ここ数週間、気分転換にピザのようなものを作っています。ピザとナンの中間のような粉ものといいますか、ピザ風のパンといいますか。ナンとピザって材料はほとんど一緒なんですよね。

ピザというとトマトのイメージがありますが、トマトとというのはアメリカ大陸発祥の食物ですから、使われるようになったのはアメリカが発見されてからということになります。しかも、初めのうちはあしらい・装飾だけで、食用にはしていなかったそうな。それまでは、ピザといえばしらすのような小魚を載せていたそうです。
とイタリア語の先生が言っていました。

ということで、それっぽく、しらすのピザを作ってみました。しらすはイタリア語でbianchettoと言います。それというのも、白はbiancheで、そこに小さい(可愛らしい)もの、という接尾辞のettoをつけた語です。つまり直訳すると「白くてちっちゃいやつ」です。

IMG_20160720_213019.jpg
「しらすのビザ」にあたる「Pizza ai bianchetti」を検索すると、なんか違った感じのものが出てきますが気にしない。

材料はふつうのピザ生地(強力粉、ドライイースト、…)に加えて、しらす、チーズ、塩、粗挽きこしょうです。極めてシンプルですね。調理時間は発酵も含めて2時間といったところです。

味はなかなか悪くなかったです。ずっと食べていると飽きがきますが、その時はなんかスパイスでもかければいいんじゃないでしょうか。

ピザじゃなくても、うどんでもナンでも良いですが、生地をこねるというのはなかなか良いストレス解消になります。外に出て走り回るほどでもないけど何かしたい、というときにはちょうど良いと思います。
   Cooking    TB(0)    CM(0)    EDIT    ページ↑

メモ?コメント?備考?

最近少し疑問に思ったのですが、「メモをする」とか「コメントを書く」とかって、結構ニュアンスが近くてややこしいですよね。もはや使い分けをする必要があるのかも怪しいくらいです。

ということで、一通り辞書を見てみました。メモもコメントも英語由来なので、まずは英和辞書(リーダーズ第3版)から。

memo
memoはmemorandumから来ているとのことでこちらを参照。
覚書、備忘録、回覧

comment: 論評、批評、解説、説明

note: 覚書、メモ、酒器、印象記、草稿


noteとmemoはなかなか近いですが、この辞書を見る限り、noteのほうが中身がある感じがします。memoはパッと書くような感じでしょうか。commentは自分のために書くというより、誰かに意見を伝えるという意味が強いようです。

では国語辞典。(広辞苑)

メモ: 忘れないように簡単に書き留めること。また、その記録。

コメント: 事件・問題について、解説や意見を述べること。

ノート: 書きとめること。また、書きとめたもの。手記。

備忘録: 忘れたときの用心のために書き留めておくノート。手控え。

手記: 体験したことなどを自ら書き綴ったもの。


せっかくなので和英もみてみましょう。(ジーニアス和英第3版)

備忘録: notebook

ノート
帳面: notebook
記録やメモ: notes

メモ: note
彼にメモを残す leave a note for him, メモなしで話す speak without memo notes

コメント: comment

手記:
体験記: memoir
印象記: notes

備考: note
備考欄: remarks column


最後にremarkというのが出てきました。「remarkable(注目すべき)」という形容詞がありますが、動詞のremarkは「述べる、書く、一言する、論評する、感想を言う」という意味だそうです。

日本語では、自分向けの覚え書きは「メモ」と言いますが、英語では「彼にメモを残す」が「leave a note for him」となるように、「note」を使うようです。

英語に合わせるなら、まあ「ノートをとる」と言えば良いんでしょうけど、あんまり言いませんね…。

memoもnoteも覚え書きならどう使い分けるんだ、という話ですが、英英辞典をみると答えがありました。noteは「a short piece of writing to help you remember something」で、「自分が」何かを覚えておくための紙片のことです。

対してmemoは「formal」で、「an official note from one person to another in the same organization」だそうです。つまり、noteのうち、同僚などに渡す公式なものを、memoと呼んでいるようです。

どこまでも発散していきそうなので、ここらでまとめましょう。

まず、英語での使い分け。
自分用ならnote、誰かに渡すためならmemo、誰かに意見を伝えるためならcomment、という具合です。
日本語でふつうメモというものはnoteにあたり、ちょっとした連絡事項はmemo、コメントはほぼそのままcommentです。

日本語では自分のために「コメントを書いておく」という表現もできないではないですが、広辞苑でも「解説や意見を述べること」と出ているので、やはり「誰かに伝えることを前提にした」という意味合いは忘れちゃいけないですね。

ノートは中学校の英語の授業で習ったとおりnotebookですが、「ノート」と同じ意味の「備忘録」もそのままnotebookになります。

ちなみに本文には関係ありませんが、「捻挫」は英語で「sprain」、では「つき指は?」というと「sprain one's finger」、つまり「指を捻挫する」と表現するようです。

カタカナ語はもともとの語とニュアンスが微妙に変わっているものが多く、調べてみると面白いですね。

今日から本格的に梅雨っぽくなってきました。
片頭痛持ちには嫌な季節ですね。水素水でも飲んで体調を整えますか。(?)
   English    TB(0)    CM(0)    EDIT    ページ↑

プロフィール

Author:JDB Luigi
どこにでもいるようなありふれた人間・・・という訳でもなく、かと言って怪しい宗教を信仰する変人という訳でも無い。

基本的に掲載しているコード等は煮ていただいても焼いていただいても結構ですが、利用は自己責任にてお願いいします。
また、バグ・アドバイス等もしあればよろしくお願いします。