JDBな人生  専門的なことから日常的なことまで~ まぁ自由きままに書いていきます。
2016年09月 / 08月<< 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 >>10月

アクセスランキング

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

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

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    ページ↑

順列を書き並べる

お久しぶりです。
突然ですが、今日は訳あって任意の要素数の順列を書き並べるコードを考えていました。

せっかくなので関数型プログラミングっぽく。と思っていたのですが、要素の重複があった場合のことを考えると、indexを使って実装せざるを得ないですね。

[1, 2, 3, 4, 5]から[1, 2, 3]を抽出するコードは別で準備するということで。といってもslice(0, 3)するだけです。

//重複があると動かない
var f = function(a, p, c) {
  if (p.length == a.length) return c(p);
  a.forEach(function(i) {
    if (p.indexOf(i) != -1) return;
    f(a, p.concat([i]), c);
  });
};

//重複があってもいい
var f = function(a, p, c) {
  if (a.length == 0) return c(p);
  a.forEach(function(item, index, a) {
    f(
      a.slice(0, index).concat(
        a.slice(index + 1, a.length)
      ),
      p.concat([item]),
      c
    );
  });
}

f([1, 2, 3], [], function(row) {
  console.log(row);
});


階乗の性質上、どんどんどんどん総数が大きくなっていくので、実際にこの関数が使い物になるのはほんの小さな範囲だけです。JSだとせいぜいn=10ちょっとくらいだと思います。

そんな使い物にならないコードをわざわざ載せるのはどうなんだという気もしつつ、せっかく考えたので載せておきます。
   プログラミング/開発全般    TB(0)    CM(0)    EDIT    ページ↑

Picture of the day: 猿渡公園の芝桜…?

一昨日、刈谷市の猿渡公園(ミササガパーク)というところに行ってきました。

なぜここかって、特に理由もないといいますか…

「蒲郡ほどは遠くない名古屋の東のどこか」ということで刈谷に行こうという話になり、たまたまこれを見つけたからです。

(刈谷市観光協会HP)
160501.png

HPによれば、こんな芝桜が4月下旬に咲きごろだそうです。



実際は…
IMG_20160429_104426.jpg


だいぶ寂しいですね。全然ふっさふっさじゃないです。

まだ満開じゃないのか、しおれてるのか、枯れてるのかよくわかりませんが、まあ近頃は寒暖差がやたらと大きかったですし仕方ない…のでしょうか。そういうことにしておきましょう。はい。

ちなみにこのミササガパークというのはその名の通りですが、刈谷市の姉妹友好都市の、カナダのミササガ市からとっているそうで。そこから贈られたという、こんな熊の置物がありました。

1024500.jpg

説明によれば、作品名は「THE WATER ROAD」で、「カヌーの位置は現在を暗示すると同時に、過去を確認しながら将来へ向かう道を示す」、そうです。
うーん

わかるようなわからないような…


この後、この公園から徒歩45分ほどの場所にある亀城公園というところまで歩いていきました。
合わせて3、4時間ほど。名古屋市内から数十分で行けますし、休日にちょっと散策したい(歩き回りたい?)というときにはちょうど良いと思います。

#刈谷市の魅力のほんの一部なんでしょうが… どこか良いところあったら教えてください

またまた小学生の日記のような記事ですね。
近頃イタリア料理を作っているので、そのうちまたレポートでも載せようかと思います。

そろそろ(数日おきに)本格的に暑くなってきましたが、体調には気を付けていきましょう。
   Photo    TB(0)    CM(0)    EDIT    ページ↑

プロフィール

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

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

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。