自炊ツールを買った

背景

昨年度年末に引っ越しをしたときに、ダンボールの数が20個近くになったのだが、
そのうち5箱が本だった。また多いだけではなく、重いので運ぶのも大変だった。
これからも本は増えていくだろうと考えると次なる引っ越しもつらいと思い、
所有している全書籍の電子化計画を決行することにした。

f:id:poppon555:20180115222307j:plain
自炊ツール

ツール

  1. 裁断機
    インターネットで検索して、おすすめの裁断機を調べた。ダンボール5箱分を裁断するので、 厚い本でも裁断でき、刃こぼれしてもメンテナンスが楽にできる裁断機を重視して選択した。

プラス 断裁機 かんたん替刃交換 PK-513LN 裁断幅A4タテ 26-309

プラス 断裁機 かんたん替刃交換 PK-513LN 裁断幅A4タテ 26-309

  1. スキャナー
    スキャナーは迷うこと来なく、ScanSnapを選択した。
    大学院時代に使っていて慣れていたし、機能も満足いくものだったので。

富士通 ScanSnap iX500 (A4/両面)

富士通 ScanSnap iX500 (A4/両面)

自炊を初めて

思った以上に電子化までの時間は遠い。
20冊電子化するのに、3時間くらいかかるので、ほとんど休日はなくなってしまう。
しかも、裁断しても裁断しきれていないページがあり、スキャナーで読み込んだときに失敗することもある。特に最初と最後のページで起こりやすいことも分かった。
でも少しでも片付き部屋のスペースが確保されると少しだけモチベーションは上がる。
まだまだ電子化計画は長そうだが、地道にやっていこうと思う。

f:id:poppon555:20180115222435j:plain
裁断済書籍

Promiseでループ処理

javascriptで通信処理を記述するときに使用するPromiseオブジェクト。
だいぶ慣れてきたが、ループ処理についてはよくわからず立ち止まってしまったので解決を考えてみたいと思う。

満たしたい要件

  1. ループ内の処理はPromiseを返却する
  2. ループ回数を指定できる
  3. ループ内処理に、異なるパラメータを渡せる(1)
  4. ループ内でエラーが起きた場合、catchできる

単純にループを

まず1,2を満たすコードを書いてみる。

// ループ内処理
// @param {Number} i - ループカウンター
function action(i) {
  return new Promise( (res, rej) => {
    setTimeout( () => {
      console.log(i + '回目です')
      res();
    },500)
  })
}

// ループ関数
// @param {Function} fn - 個々の処理
// @param {Number} i - カウント初期値
// @param {Number} end - カウント終了値
function loop( fn, i, end) {

  return fn(i)
  .then( () => {
    if ( i < end ) {
      return loop( fn, i+1, end)
    }
    else {
      return Promise.resolve('end');
    }
  })

}

// 実行
loop(action, 0, 3 );

// console
< 1回目です
< 2回目です
< 3回目です
< 4回目です
< end

ループ内処理では、setTimeoutを使用して擬似的に遅延させてPromiseを返却している。
Promiseでのループ関数のポイントは再帰処理だと思ってる。ループ内処理を呼び出して、thenでPromiseをチェーンさせる2。then内で引数の値からloopを終了させるかどうか判定し、続けるならばloopを再帰的に呼び出し、終了ならばPromiseを返すようにした。

エラー処理の追加

続いて、ループない処理でエラーが生じた場合それ以降の処理を中断するように改良する。

function action(i) {
  return new Promise( (res, rej) => {
    setTimeout( () => {
      // 修正
      if ( i === 5 ) {
        rej('5は処理できません');
      }
      else {
        console.log(i + '回目です')
        res();
      }
    },500)
  })
}

function loop( fn, i, end) {

  return fn(i)
  .then( () => {
    if ( i < end ) {
      return loop( fn, i+1, end)
    }
    else {
      return Promise.resolve('end');
    }
  })
  // 追加
  .catch( (err) => {
    console.log(err);
  })

}

// 実行
loop( action, 0, 6);
// console
< 0回目です
< 1回目です
< 2回目です
< 3回目です
< 4回目です
< 5回は処理できません

ループ内処理では、5だとrejectするように擬似的に設定。 ループ関数では、最後にcatchを追加するだけでよい。

任意のパラメータ指定

最後に3.の指定した任意のパラメータを実行させるように改良してみる

// ループ内処理
// 引数を追加
function action(i, second) {
  return new Promise( (res, rej) => {
    setTimeout( () => {
      if ( i === 5 ) {
        rej('5回は処理できません');
      }
      else {
      console.log(i + '回目です');
      // 追加
      console.log('パラメータ合計:' +  Number(i + second) ); 
      res();
      }
    },500)
  })
}

// ループ関数
// params引数を追加
function loop( fn, params, i, end) {

  // applyを使って、個々のparamを渡す
  return fn.apply(null, params[i])
  .then( () => {
    if ( i < end ) {
      return loop( fn, params, i+1, end)
    }
    else {
      return Promise.resolve('end');
    }
  })
  .catch( (err) => {
    console.log(err);
  })

}

// 個々のパラメータを用意
var params = [
  [1,10],
  [2,20],
  [3,30],
  [4,40]
]

// 実行
loop(action, params, 0, 3 )
// console
< 1回目です
< パラメータ合計:11
< 2回目です
< パラメータ合計:22
< 3回目です
< パラメータ合計:33
< 4回目です
< パラメータ合計:44
< end

修正はループ関数だけでよい。
むしろ、ループを回すために内部処理に微修正させるとかしたくない。 fnを直接呼び出すのではなく、applyメソッドでparamsをfnの引数として 利用するように指定する。applyめっちゃ便利。


  1. ループ内処理は同じ処理である

  2. チェーンさせて処理をつなげるため、whileやfor文ではループ処理ができないのだと思っている。

underscore.jsを使って特定のvalueをもつkeyのみ取得する方法

最近jsを書いているとき、可能であれば関数型プログラミングを心がけている。
そのほうが一時的な変数を書かなくてい済ませるし、
やはり書いていて気持ちがよい笑

今回は、 underscore.jsを使ってオブジェクト内の 特定のvalueをもつkeyのみを取得する方法がわかったので記録しておく

特定のvalueをもつもののみ取得する

var obj = {
  A : '1',
  B : '1',
  C : '0',
  D : '1'
};

_.pick( obj, function (v) {
  return v === '1'
})

// console
> { A : '1', B : '1', D : '1' }

keyだけがほしい場合

_.chain(obj)
 .pick( function (v) {
    return v === '1'
 })
 .keys()
 .value()

// console
> ["A", "B", "D"]

アロー関数を使うともっと短くなる

_.chain(obj)
 .pick( v =>  v === '1' )
 .keys()
 .value()

CPUの創り方 クロック回路

半年前くらい前に購入した「CPUの創りかた
とてもわかりやすく楽しく読めたものの、実際に自作までには至らなかった。

CPUの創りかた

CPUの創りかた

久しぶりに手を取ってみると、今度は実際に手を動かしてみたいと思ったので、
少しずつできるところからやってみようと思う。

今回は、Chapter4で登場するクロック回路に挑戦。
ブレッドボードで気軽に始めてみる。

まずは、手動クロック。
スイッチのON、OFFを切り替えることで青色LEDを点灯させるが、
抵抗とコンデンサを利用して、点灯タイミングをずらしている。



次は、通常のクロック回路。
書籍と同じ3.3KΩの抵抗が手元になかったので、
代わりに4.7KΩを使用しているが、動作確認できたのでよしとする。