プログラミング初心者が苦しみながら確実な基礎力を身につけるための技術書

with コメントはまだありません

確実な基礎力を身につけるために

初学者がいきなりサービス開発をはじめるのも良いと思う。
本をまずは見よう見まねで写経して、少しずつ理解を深めつつ、サンプルコードを改造して自分のサービスを作る。
それができたら一番いいと思うんだけど、そんな事できるのは才能があるやつだなんじゃない?って思う。自分は馬鹿だから無理だった。

というわけで、才能ないけどプログラミングしたい人が泥臭く基礎力を身につけるための技術書を紹介する。

新・明解C言語 入門編

初心者にCはオススメしないとよく言われるが、私はCを学ぶべきだと思う。
Cを一度書いておくと、他の言語に移った時も背後でどういう事が行われているのかを想像する事ができる。

さて、まずは環境を構築して基礎文法を学ばないといけない。そのための本がこれ。
正直この部分に関してはこの本以外でも良い。「苦しんで覚えるC言語」とかも良いかも。

新・解きながら学ぶC言語

文法を理解したところで、初学者はプログラムを書く事ができない。(才能のある人は書けるかもしれないけど)
なので、この本で「最小限のアルゴリズム」を勉強するのが良いと思う。
「最小限のアルゴリズム」とは、例えば

・変数aと変数bの値を交換する
・配列の中の数字で最大or最小のものを発見する
・3つの数字を昇順で並べ替える
・入力された文字列の中に「xxx」という文字列が存在するかを見つける

などが挙げられる。

何故最小限のアルゴリズムを学ぶのが大切かというと、実際のプログラムは最小限のアルゴリズムの組み合わせで出来ているからである。
因みに、これらのアルゴリズムは他の言語だと大体機能としてデフォルトで実装されている。
それを一度自分で実装する事で実装の基礎力が身につく上に、他の言語を書く時、背後で何が行われているか想像する事ができる。
この力はまともにプログラムが書けるようになるためには必須だと思う。

新・明解C言語中級編

解きながら学ぶC言語で最小限のアルゴリズムは理解できるようになると思う。
ただ、それだけではプログラムを書く事ができない。何故ならプログラムは最小限のアルゴリズムの組み合わせで出来ているから。
結局のところそれらを「どう組み合わせて良いか」がわからない。

この本では「じゃんけんゲーム」や「マスターマインド」「記憶力ゲーム」などを実際に作りながら最小限のアルゴリズムを「組み合わせる力」を身につける事ができる。

ここまでやれば、かなり自分で実装ができるようになっているはず。
いきなり便利な言語触ってる奴とは一線を画するアルゴリズム力がついてると思う。

スッキリわかるJava入門

ここまでで最小限のアルゴリズムを組み合わせて、1つのプログラムを実装する力を身につけることができると思う。
ただ、社会に出て扱うプログラムや、世に出ているアプリケーション、Webサービスのプログラムはもっと巨大である。
従って、次は複数のプログラムを構造的に組み合わせて1つの大きなプログラムにする方法、というのを学ばないといけない。

そこで、複数のプログラムを構造的に組み合わせて1つの大きなプログラムにする方法として「オブジェクト指向」というパラダイムが存在する。
この本はそのオブジェクト指向を学ぶのに対して最高の本である。
Webで検索して説明を読んだけどわからない、授業で教わったけどわからない、そんな人もこの本を読めば絶対理解できる。

因みにこの本には「実践編」も存在するが、初学者が基礎力を身につけるためには必要ない。

ここまで理解できたら

Rails入門だとか、iPhoneアプリ作成入門だとかのいわゆる「ハウツー本」に移って良いと思う。 もちろん、ハウツー本は上記の本と平行しながらでも良い。

ここまでやって基礎力を身に着けたら、他の言語、例えばRubyとかPythonも入門サイトで文法を眺めただけである程度書けるようになるし、
技術書はサンプルコードを読むだけでもまあまあ理解できるようになっているはず。

他にオススメな本

以下に紹介する本は私が個人的に読んで良かった!!と思った本。
但し、Railsの使い方!とかそういった本ではない。

Head Firstデザインパターン

オブジェクト指向を理解しても、オブジェクト指向を効果的に使うことは難しい。
その為に先人たちが蓄積した設計のノウハウをデザインパターンという。
この本はそのデザインパターンを最高にわかりやすく解説している。

因みに私は初学者の頃、Java言語で学ぶデザインパターン入門という本も読んだが意味がわからなかった。
初学者にはHead Firstデザインパターンがオススメである。

マスタリングTCP/IP 入門編

ネットワークの知識は何かとあった方が良い。業務で必要とかそういうの関係なしに。
これはC言語を学ぶのと同じ理由で、背後で何が起こっているのかを想像する事ができるようになるからである。

あと、最近は個人レベルでもインフラをクラウドサービスを使って構築することが多い。
その時に威力を発揮する。ドキュメントが理解できるのを実感できると思う。

達人に学ぶDB設計 徹底指南書

DB設計は我流でやっている人が多く、実際に業務レベルのアプリケーションを開発する時に困る人が結構居る。
個人レベルで開発する時もこの本の知識は間違いなく役に立つ。
自分の力になっていることが実感できる一冊。

あと「基礎からのデータベース設計(http://amzn.to/2deIUuZ)」も正規化に関してかなりわかりやすいのでコチラもオススメ。

リーダブルコード

言わずと知れた名著。ただ初学者がいきなりこの本でキレイなソースコードは何か、を学ぶべきではないと思っている。
美的感覚は実務やOSSのコードなどを読んで自然と身につける方が良いと思う。美的感覚といった抽象的な概念は初学者が本を読んでも理解が難しい。
この本は自分の美的感覚がズレていないかを確認する、もしくはたまに読んで自分の姿勢を正す、といった用途にかなり良い。

プログラマ脳を鍛える数学パズル

理屈抜きにアルゴリズム力を鍛えるのに良い本。
ポップな見た目な癖に、結構難しい問題も収録されている。

大規模サービス技術入門

独学では絶対に身につくことのないノウハウが詰まっている。
個人レベルで必要になる機会はほぼないが、読み物としても非常に面白いのでオススメ。
大規模サービスに携わる機会があるなら、事前に読んでおくととても役に立つと思う。

ハイブリッドOCR

with コメントはまだありません

これまでの流れを汲んでOCRかけるクラスを完成させるで。
まだまだ改良の余地はあるけど、いつまでもこんなことばっかりやってられへんから一旦これでOCRは完結や。

流れは

1)白紙のセル判定 ->白紙なら終了
2)文字の部分だけ切り取る
3)tesseractにかける
4)数字ならそれで終了,数字以外ならvisionAPIにかける

簡単に実装するとこんな感じやで。

(input)
f:id:deeptoneworks:20160930050552p:plain
(output)
DetectText(kind=<CellKind.number: 3>, text=42.1)

(input)
f:id:deeptoneworks:20160930050600p:plain
(output)
DetectText(kind=<CellKind.string: 2>, text=’住宅の所有の関係(6区分)’)

(input)
f:id:deeptoneworks:20160930050606p:plain

(output)
DetectText(kind=<CellKind.empty: 1>, text=”)

ええ感じやな!次は素性作成器の実装や!

再びtesseractでOCR

with コメントはまだありません

前回、高解像度の綺麗なデータを作る事ができたんや。
せやったらtesseract、結構いけるんちゃうか?って話やで。

(1)
f:id:deeptoneworks:20160927110906p:plain

(2)
f:id:deeptoneworks:20160927111006p:plain

(3)
f:id:deeptoneworks:20160927111010p:plain

(4)
f:id:deeptoneworks:20160927111030p:plain

(5)
f:id:deeptoneworks:20160927111035p:plain

(6)
f:id:deeptoneworks:20160927111043p:plain

(7)
f:id:deeptoneworks:20160927111047p:plain

(8)
f:id:deeptoneworks:20160927111101p:plain

(9)
f:id:deeptoneworks:20160927111106p:plain

(10)
f:id:deeptoneworks:20160927111114p:plain

(11)
f:id:deeptoneworks:20160927111136p:plain

(12)
f:id:deeptoneworks:20160927111141p:plain

(13)
f:id:deeptoneworks:20160927111200p:plain

番号 解答 正負
(1) 持 ち 家 o
(2) ー 0 3 1 113 x
(3) ー 773 0 53 5 3 x
(4) 5 o
(5) 252 o
(6) 27 o
(7) 230 o
(8) 257 o
(9) 285 o
(10) 453 788 x
(11) 1 o
(12) 98 o
(13) 6 o

やっぱ日本語は微妙やな。
数字はええ感じや!このサイズやったら問題ないっぽいな。
ただ「,」が認識できとらん。
小数点は認識できるんやろか?試してみよか。

(1)
f:id:deeptoneworks:20160927123411p:plain
(2)
f:id:deeptoneworks:20160927123412p:plain
(3)
f:id:deeptoneworks:20160927123413p:plain
(4)
f:id:deeptoneworks:20160927123414p:plain
(5)
f:id:deeptoneworks:20160927123415p:plain
(6)
f:id:deeptoneworks:20160927123416p:plain
(7)
f:id:deeptoneworks:20160927123417p:plain
(8)
f:id:deeptoneworks:20160927123418p:plain
(9)
f:id:deeptoneworks:20160927123419p:plain
(10)
f:id:deeptoneworks:20160927123420p:plain

番号 解答 正負
(1) 2,990 o
(2) ー 906 x
(3) 31. 5 o
(4) 33. 4 o
(5) 23. 8 o
(6) 23. 3 o
(7) 34. 6 o
(8) 30. 2 o
(9) 22. 9 o
(10) 24. 6 o

小数点もとれるっぽいな!ええ感じやん。
ただ1個取れてないのがあるなあ。

・・・お、こんな感じで数字の部分だけ切り取ったらちゃんと読み込んだわ!
f:id:deeptoneworks:20160927125357p:plain

やっぱ数字の部分だけ切り取る処理を挟む必要がありそうやな。
さて、どう実装しよか。

凸包使うとかあるみたいやけど、数字は離れてるしなあ。
まあ、セルの一番左端と右端の白以外の画素の部分で切り取ったらええやろ!!
一応事前に2値画像に変えとるで!

こんなんでええか。2重ループ嫌やけど、flatにしたらあかんからな。
で、実際には20pxくらいマージンを入れて切り取ったらこんな感じなるで。

f:id:deeptoneworks:20160928052939p:plain

ええ感じやな! 次は日本語はgoogleVisionAPIに、数字はこっちのOCRで振り分ける処理を書いて実験しなな。

pdf->pngを変換を高画質に行いたい

with コメントはまだありません

初回あたりからずっと使ってる画質が粗いセルの画像やけど、そもそもpdf->png変換を高画質に出力できたらええんちゃうか?っていう話。
最初からこうしたらよかったんや、迷走しすぎやなあ。

さて、pdf->png変換を綺麗に行う為にはImageMagickを使うで。
convertコマンドに-densityオプションがあるんやけど、これで解像度を指定できるみたいや。
さっそくやってみよか。

出力は・・

・・・あかんやんけ!原因を探るで。

軽くググると、brewじゃなくてwebサイトからpkgをインストールしろとか、–build-from-sourceオプションつけてinstallしたら治るで!とか書いてあったわ。

ちなみにあかんかったで。書くまでもないような解決方法やってんけど、一応日本語ではないっぽいし書いとくわ。

解決方法はやっぱstackoverflowにのっとったわ。
superuser.com

gsに依存しとるんやなあ。installしとこ!

インストールしとったわ。 it’s just not linkedやて?ほなリンク貼っとこか。

よっしゃ!これで動くようになったで!!試すで!!

・・・

f:id:deeptoneworks:20160926200520p:plain

・・・!!

f:id:deeptoneworks:20160926200541p:plain

・・・!?!?

f:id:deeptoneworks:20160926200611p:plain

やばい!!めっちゃ綺麗や!!これは多分いけるで!!
というわけで次回はこれで数字認識を試してみるで!!!

(追記)
実際には背景透明化したくなかったのでalpha offオプションをつけています

俺が求めてるボタンはTouchableHighlightじゃない

with コメントはまだありません

ReactNativeではボタンを作る時にTouchableHighlightを使う。
デフォルトでは押した時にunderlayColorで指定した色が背景に表示される。
こんな感じ。
f:id:deeptoneworks:20160923205340g:plain

おかしいやん。誰が求めてるの?テキストじゃなくて画像のボタンだったらいいんだけどね。

求めてるのはiOSのデフォルトのボタンみたいに、テキストがハイライトするやつ。
こんなやつ。
f:id:deeptoneworks:20160923205747g:plain

これを作るのが若干めんどい・・・。
TouchableHighlightコンポーネントじゃ実装できないので、TouchableWithoutFeedbackコンポーネントを使う。
これは名前の通り、デフォルトのままでは押しても何の反応も示さない。
このコンポーネントのonPressInとonPressOut propsをいじってテキストがハイライトするように実装する。

f:id:deeptoneworks:20160923210513g:plain

でーきた。
ほんまにこんな実装でええんか・・?

やってる事は単純で、ボタンを押した時と離した時でisHighlight statusを切り替えて、this._textColor()で渡されるスタイルを切り替えている。
やりたい事は凄いシンプルなのに、若干めんどいなあ。。

ちなみに、TouchableHighlightコンポーネントは直下の子にTextとかImageコンポーネントを持ってこれるけど、TouchableWithoutFeedbackはダメっぽい。
Viewでラップしてあげましょう。

(追記)
こんな感じのコンポーネントにしたよ

ReactNative Flexboxまとめ(殴り書き)

with コメントはまだありません

React-Nativeを使ったアプリケーション開発にはFlexboxの理解が不可欠。
だから適当にまとめる。

flex

これで画面いっぱいにコンポーネントが表示される。
同じレベルにflex:1を指定しているコンポーネントが2個あったとしたら1:1の割合で表示される。
片方が1で片方が2なら1:2の割合。

flexDirection

縦並び(=column)か横並び(=row)か。デフォルトはcolumn。
あと、ReactNativeではcolumn-reverseとかrow-reverseは効かんっぽいなあ。

flexWrap

nowrapで単一行、wrapで複数行。デフォルトはnowrap。
nowrapの時は要素がはみ出ても横一行or縦一行で表示しようとする。
wrapの時は折り返す。

justifyContent

コンポーネントの配置方法を指定。

flex-start
縦並びの場合は上から、横並びの場合は左から子コンポーネントを配置する。 (デフォルト)

flex-end
縦並びの場合は下から、横並びの場合は右から子コンポーネントを配置する。

・center
中央に子コンポーネントを配置する

・space-between
一番左と一番右(or一番上と一番下)に子コンポーネントを配置して、
残りの子コンポーネントを均一のスペースが空くように配置する。

・space-around
space-betweenと同様均一のスペースを空けて子コンポーネントを配置する。
ただし、一番左と一番右(or一番上と一番下)のコンポーネントにも隙間が出来る。

alignItems

縦並びなら「左」、横並びなら「上」を基準に子コンポーネントを揃える。
(justifyContentとは軸が逆)

・stretch(デフォルト)
コンポーネントを表示範囲に伸ばして配置する。

flex-start
縦並びなら左、横並びなら上に子コンポーネントを揃える

flex-end
縦並びなら右、横並びなら下に子コンポーネントを揃える

・center
中央に子コンポーネントを揃える。

alignSelf

コンポーネントで指定した「alignItems」を子コンポーネントで上書きする。
指定できる値はalignItemsと同じ。

flexを使用せず画面一杯に表示

こんな感じで画面サイズが取れる。

めっちゃ粗い画像の数字を認識したい-試行錯誤編-

with コメントはまだありません

この画像↓を鮮鋭化するために試行錯誤するで。粗いなあ・・5か6かわからんで・・。
f:id:deeptoneworks:20160920003646p:plain
知り合いの人に色々なフィルタリング方法を教えてもらったんや。それをほぼそのまま貼るで。

アンシャープマスキング

f:id:deeptoneworks:20160920033250p:plain

ソーベルフィルタ

f:id:deeptoneworks:20160920034412p:plain

色々な2値化

f:id:deeptoneworks:20160920034752p:plain

ヒストグラム平滑化

f:id:deeptoneworks:20160920034916p:plain

モルフォロジー演算(収縮・膨張)

f:id:deeptoneworks:20160920035209p:plain

モルフォロジー演算、もっといい線いくと思ったんやけどなあ・・。あかんかったわ。
ヒストグラム平滑化は1つの数字の範囲を算出するのに使えそうや。自分で数字認識させるんやったらまず各数字の分離をせんとあかんからなあ。

Google Cloud Vision APIでOCRを試してみる

with コメントはまだありません

なんか前回か前々回か忘れたけど、日本語全然認識できひんかったから、Google様の力を借りるで・・。

毎月1000回以上のリクエストやったら無料や。
あ、正確には1000unitやな。例えば文字認識と物体認識を同時にやったら1リクエスト2unitsや。
1000unitsを超えたら1000units毎に2.5ドルとかするんや、たっかいなあ・・・。俺何万毎とOCRかけたいんやけどなあ・・。

使い方はめっちゃ簡単や!
Cloud Vision API Requests and Responses  |  Google Cloud Vision API Documentation  |  Google Cloud Platformソースコードも含めて全部書いてあるわ!!

ちなみに、特定の画像に対してリクエストを送ってレスポンスを受け取るのはこんな感じでできるで。

type:のところにTEXT_DETECTIONってしてるから文字認識やな。
他には顔認識とかランドマーク認識とかいろいろあるんやなあ。。。

さて、色々試していくで。
あ、その前にさっきのコードのまんまやったら、json形式のresponseがそのまま表示されて見にくいからちょっと修正せんとな。
responseのtextAnnotations->descriptionっていうとこに文字が入ってるっぽいし、こことlocaleだけ表示するようにしとこか。

こんなんでええか。実験するで。
今回は以下の21種類の画像でやるわ。

(1)
f:id:deeptoneworks:20160919233235p:plain
(2)
f:id:deeptoneworks:20160919233236p:plain
(3)
f:id:deeptoneworks:20160919233237p:plain
(4)
f:id:deeptoneworks:20160919233238p:plain
(5)
f:id:deeptoneworks:20160919233240p:plain
(6)
f:id:deeptoneworks:20160919233241p:plain
(7)
f:id:deeptoneworks:20160919233242p:plain
(8)
f:id:deeptoneworks:20160919233243p:plain
(9)
f:id:deeptoneworks:20160919233244p:plain
(10)
f:id:deeptoneworks:20160919233245p:plain
(11)
f:id:deeptoneworks:20160919233246p:plain
(12)
f:id:deeptoneworks:20160919233247p:plain
(13)
f:id:deeptoneworks:20160919233248p:plain
(14)
f:id:deeptoneworks:20160919233249p:plain
(15)
f:id:deeptoneworks:20160919233250p:plain
(16)
f:id:deeptoneworks:20160919233251p:plain
(17)
f:id:deeptoneworks:20160919233252p:plain
(18)
f:id:deeptoneworks:20160919233253p:plain
(19)
f:id:deeptoneworks:20160919233254p:plain
(20)
f:id:deeptoneworks:20160919233255p:plain
(21)
f:id:deeptoneworks:20160919233256p:plain

結果

画像番号 認識結果-言語 認識結果-文字 正負
1 x
2 x
3 x
4 ja 持家う x
5 ja 公営の借家 o
6 ja 公団·公社の借家 o
7 zh-Hant 長屋建 o
8 ja 一戸建 o
9 ja 総数 o
10 ja その他 o
11 ja 間借 x
12 ja (再掲) 世帯が住んでいる階 o
13 ja 全体の階数 o
14 ja 住宅の所有の関係(6区分) o
15 en 38 o
16 x
17 en 31.4 o
18 en 36.0 o
19 en Rented rooms o
20 en Owned houses o
21 pt-PT Principal households o

ええ感じやん!!日本語もかなりの精度でとれてると思うで!
間借りと間借とかもう正解でええしな。
さすがgoogle様や!
zh-Hantは中国語、pt-PTはポルトガル語やな!ここがあってるかどうかはどうでもええわ!!

ただなあ、数字のセルを全部このAPIにかけてたら金がいくらあっても足りひんで・・ 。何万とデータがあるからな・・・。
文字のセルはともかく、数字のセルだけでもこっちで認識させてあげられへんかなあ??

tesseractでOCR〜数字だけでも〜

with コメントはまだありません

前回全然日本語や数字認識ができなかったtesseract、せめて数字だけでも認識できひんか?と思って再チャレンジ。
前回はあまりに工夫がなさすぎた。

今回実験に使うセルはこれ。
f:id:deeptoneworks:20160916041755p:plain

pyocrのbuilderを変えてみる

どうやら、数字だけの認識に対応したbuilderがあったらしいのでそれを使う。

(before)

(after)

結果
あかん!どっちも何もでえへん!!

数字の部分だけを切り取る

多分、隅っこに数字があるからあかんのや!!
せや!!いい感じに切り取ったろ!!

f:id:deeptoneworks:20160916050627p:plain

結果
(テキスト)鵬
(数字)何も出ない

あかんやん!

数字の部分を拡大する

いい感じに数字だけ抜き取れたけど、やっぱり画像が小さすぎるんや!
拡大したろ!!

f:id:deeptoneworks:20160916050846p:plain

(結果)
(テキスト)38
(数字)何も出ない

おおおおおお!!!!うまくいっとる!
こんなぼやけた数字でもうまくいくんやなあ・・。でもDigitBuilderあかんやん!まあええか。

他の数字でも実験

38が偶然うまくいっただけかもしれん。他の数字でも試してみるで。
画像は貼るのだるいから結果だけ書いとくわ。

正解 結果
5
252 252
27
230 230
257 257
285 285
1
98
6
93
99
2
102 102

・・・あかんやん!!
3桁の数字は良好やな!問題は1桁と2桁や!!
っていうか38はやっぱ偶然やったんか!!!!

画像をもっとはっきりさせる

やっぱ拡大してボヤけてるんがまずいんちゃうか?
次は「5」の画像でテストするで。

f:id:deeptoneworks:20160916053148p:plain

ちなみに先の実験に使った5の画像はこれや。ぼやけすぎやな。何がなにかわからん。

はっきりさせてみるで。閾値を定めて2値化や!

f:id:deeptoneworks:20160916053729p:plain

なんか微妙やな・・でもこれが限界やったわ。

(結果)
5

おおお!うまくいっとる!さて、先と同じように他のデータでも実験してみるで。

正解 結果
5 5
252
27
230
257 0
285
1
98
6
93
99
2
102 102

悪化しとるやん!!!!
2値化した画像を1つずつ見ていくと、なんか2つの数字がくっついたりしとった!!
でもチューニングも限界なんや・・・。

ちなみに

とかでいい感じに先鋭化して2値化しようとしたけどこれもダメやった・・。

結論

多分、1個1個チューニングしていったら全部判別はできるんやろうな・・。
そんなんやったら全部自分でラベリングするわ!!!

あと自分のチューニング方法も悪いんやろな・・。
正直俺でも5か6かわからんわ!って感じやしな。
ボヤけた画像をシャープにする方法、もっと他にあるはずや。
DeepLearningで画像を高画質にするやつとかあったやろ?俺にはよくわからんわ・・・。

mnistとかを元に自分で分類器作るか・・?でもmnistの数字は綺麗すぎるし、だめそうやなあ・・。
だから、自分でボヤけた数字データセットを作って分類器つくるんかな。

方針としては以下のどっちかかな。

1)ボヤけた画像をDeepLearningにより高画質化(どうすんねん)
2)ボヤけた画像を教師データとして分類器を作成(データセットつくるのだっるいなあ・・)

でもその前に試してみたいやつがあるんや、それは次回やるで。

1 2