プログラマのススメ

・はじめに

プログラマーになるなら覚悟を決めよ、と迫るリストが増えてきたので、少し気になって。
凄く具体的に言うと、 プログラミングの入門 を読んだ人から「そんな面倒なのか、イヤだな」と直接言われたからだ。

プログラマーには、10種類しかいない。2進数が読めるヤツと、読めないヤツだ。
なんて、ジョークを飛ばす時代でも無くなった。
個人的には11種類、おっと、3種類に分類できると思ってる。

  1. 職業としてのプログラマ
  2. ホビーとしてのプログラマ
  3. ハッカーとしてのプログラマ

考えてもみよう。
プログラミング言語といわれるように、これは"言葉"の一種だ。
英語なんかと同じ。
勿論、英語で飯を食っていこうともなれば、それは高度な技術職であって、特殊な職能が要求される。
例えば、通訳とか、翻訳家とか、企業の所謂"英語屋"さんなんかは、英語を使えるだけではなく様々な能力を期待されるし、それを発揮しなければ食っていけない。
でも、じゃあ、辞書を丸呑みするような血の滲むような努力がなければ、英語を使えないのだろうか。
例えば、字幕なしで洋画を見たいとか、世界一周旅行に行きたいとか、もっと言えばロサンゼルスに憧れている人は、そうまでしなければ英語を使って楽しめないだろうか?

僕は違うと思う。
指差し会話帳を使ってアメリカ旅行だって、悪くはないはずだ。
バックパッカーは辞書を片手に、それこそ英語やスペイン語で楽しめば良い。
LとRの発音を聞き分けられなくたって、カタコトを笑われたって、旅行が出来ないことはない。
プログラミングだって同じはずだ。

どのプログラマになるんであっても、最初の一歩はそんなに難しいことじゃない。
だから、気楽に始めてみようよ。

・プログラミング入門

  • 0. なにをやるか
  • 1. まずは簡単な入門
  • 2. そうは言っても動かしたい
  • 3. 次から何をしていけば良いか

0. なにをやるか

プログラミングとはなんだろうか。プログラムを作ることだ。
じゃあ、プログラムとは?卒業式で見ただろう。式次第のことだ。
つまり、ヤルべきことが書かれている日程表だ。

じゃあ、プログラミングで最も大切なことがなにか解るだろうか。
"なにをやるか"、だ。

素敵な会場の選び方も、椅子の素早い並べ方も、効率の良いアナウンスも、使い回しできる組織表も、それぞれ勿論大切だろうけど、まず"卒業式をやる"という目的があってのことだ。

だからまず最初の一歩としての心構えは、次のようになる。
「本を最初から読むのを止める」
分厚い文法書を頭から読むのは止めよう。
そういうのは、慣れた人が新しい言語を学ぶときにやるやり方だ。
やりたいことがあって、それをやるために必要な部分だけ読んで、まずやってみる。
そういう癖をつけよう。
(どうせ読まなきゃならないときには、読まなきゃならないんだから)

1. まずは簡単な入門

大切なことは分かった。次は入門だ。
なんでもいいんだけど、とりあえず、キミの生まれた曜日を調べてみよう。
プログラミングの始まりだ。

やること:生まれた曜日を調べる。

わかってることを並べてみよう。
曜日は7つある。月火水木金土日。
一週間は7日で、曜日が一巡する。
一年はたいてい365日だ。つまり、7日で割ると、52あまり1。
2013年1月1日は火曜で始まったから、2014年1月1日は水曜から始まる。

よし、じゃあこのへんで誕生日を2000年の3月27日だったとおいてみよう。
ちょっとズルして、2013年3月27日の曜日を調べてしまおう。水曜日だ。
てことは、ちょうど一年前の2012年3月27日は、火曜日だろう。
これを誕生の年まで繰り返せば良いから……

2013 - 2000 = 13

で、13回さかのぼれば良いかな?

13 ÷ 7 = 1あまり6

1はつまり1順、同じ水曜日。
さらにあまった6日位分はさかのぼるから、火、月、日、土、金、木。
13回さかのぼると、木曜日だ!

なにか忘れてないかな。
そう、「一年はたいてい365日」だ。たまに2月29日が出て、366日になる。うるう年だ。

366 ÷ 7 = 52あまり2

ややこしいけど、うるう年の年は、2つ曜日が進むってことさえ判ればいい。

はてなキーワードにも書いてあるけど、うるう年の判定方法は簡単だ。
4で割り切れる年は、うるう年だ。
でも、100で割り切れる年は、うるう年じゃない。
でもでも400で割り切れる年は、やっぱりうるう年だ。

てことは、2013年から2000年の間に何回うるう年があるか調べて、その分だけ追加でさかのぼれば良いってことだ。
2013年は?4で割り切れないから違う。2012年は?4で割り切れるから……めんどうだね。
例えば、2013年までのうるう年の数って数えられないかな。

2013 ÷ 4 = 503あまり1 …うるう年
2013 ÷ 100 = 20あまり13 …うるう年じゃない
2013 ÷ 400 = 5あまり13 …やっぱりうるう年
4で割った503回 - 100で割った20回 + 400で割った5回 = 2013年までに、488回

じゃあ、2000年も同じように数えてみると、

4で割った500回 - 100で割った20回 + 400で割った5回 = 2010年までに、485回

てことは、3月27日を調べたいんだから、2000年までのうるう年は無視していいはずだ。

2013年までのうるう年488回 - 2010年までのうるう年485回 = その間のうるう年3回

つまり3回だ!

整理しよう。
2000年3月27日の曜日を調べたい。
2013年3月27日は水曜日。
2013 - 2000 = 13。13 ÷ 7 = 1あまり6。
1順して、さらにあまった6日位分はさかのぼるから、火、月、日、土、金、木。
うるう年が3回あったから、水、火、月。
つまり、2000年3月27日は、月曜日だ!
ググって答え合わせをしてみると、どうやら正しそうだ。

さあ、できたぞ。
なにがって?これがプログラミングだ。
キミはコレで、過去の3月27日なら、どんな年の曜日だって解る。*1

つまり、プログラムは、こうなる。

やること:X年3月27日の曜日を調べたい
1. (2013 - X) ÷ 7 = 答えのうち、余りを覚えておく
2. 488 - ( (X ÷ 4の商) - (X ÷ 100の商) + (X ÷400の商) ) = 答えを覚えておく
3. ( (1.で覚えておいた"余り") + (2.で覚えておいた"答え") ) ÷ 7 = 答えのうち、余りを覚えておく
4. 水曜日から、3.で覚えておいた"余り"分、さかのぼる。

3.に少しだけ新しいことを入れたけど解るかな?
一週間で曜日は一巡するから、7で割り切れたら同じ曜日になる。だから商は無視していいんだ。

このプログラムを作るために、ここまで長々と試行錯誤してきた。
これこそがプログラミングだ。
ね、簡単でしょ?

2. そうは言っても動かしたい

何をやるかが大事なのかは分かった。
だから、誕生日の曜日を調べてみた。
でも、プログラミングってもっとコンピュータを使うハズだ、いちいち電卓叩きたくない、というのもまあ解る。

じゃあやってみよう。
好きなプログラミング言語、好きなコンピュータを使って良い。
Googleで調べれば、いまは無料でたくさん情報がある良い時代だ。
自分で調べてやることが、大切だ。

とはいえ、これはガイドなので、少しだけやってみよう。
http://codepad.org/ に行って、左側のLanguage:でPythonを選んでみよう。

そして、さっき書いたプログラムをテキストエリアに貼り付けて、右下のRun codeチェックボックスにチェックが入っているか確かめて、Submitボタンを押してみよう。

Python, pasted just now: 
1 1. (2013 - X) ÷ 7 = 答えのうち、余りを覚えておく
2 2. 488 - ( (X ÷ 4の商) - (X ÷ 100の商) + (X ÷400の商) ) = 答えを覚えておく
3 3. ( (1.で覚えておいた"余り") + (2.で覚えておいた"答え") ) ÷ 7 = 答えのうち、余りを覚えておく
4 4. 水曜日から、3.で覚えておいた"余り"分、さかのぼる。

Output:
1  Line 1
2 SyntaxError: Non-ASCII character '\xc3' in file t.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

おめでとう!キミの初めてのプログラム実行だ!
残念ながら、1行目にNon-ASCII characterが入っていると怒られてしまった。

当然じゃないか!とキミが怒らないで欲しい。
プログラミング言語で書かないといけないというのを体験してもらうとともに、Errorと言って間違っていたらちゃんとコンピュータ側が教えてくれるというのを見せたかったんだ。

でも大丈夫。
Python言語に変換していけば良いだけだから。

Pythonでは、覚えておきたい数字を、"X"などの好きな言葉でおける。*2
あと、その覚えておきたい数字に、覚えておきたい数を入れるときには、

X = 2000

などのように、左側に使おうとする言葉、右側に覚えておきたい数を置く。

日本語は使わずに全部半角英数字にしよう。"ASCII"とかで調べてみよう。

他につかう記号一覧を出しておこう。

加減乗除は、+ - * / 
余りだけ知りたいときには、%
商だけ知りたいときには、 //

答えを表示したいときには、覚えておきたい数の前に print と入れるといい。

さ、書き換えてみよう。

X = 2000
amari = (2013 - X) % 7
kotae = 488 - ( (X // 4) - (X // 100) + (X // 400) )
amari2 = ( (amari) + (kotae) ) % 7
水曜日から、3.で覚えておいた"余り"分、さかのぼる。
print amari2

なんだかかなりそれっぽくなったね。
先頭の数字はとってしまった。Pythonは数字を付けなくても上から順に見てくれる。
とりあえず例題と同じく2000年を調べるようにしてみた。

最後の"さかのぼる"ところだけ、数式じゃないから上手く行かなかった。
じゃあ、とりあえず「水曜日から、3.で覚えておいた"余り"分、さかのぼる。」だけ除いて、New pasteに貼り付けて、動かしてみよう。

Outputに"2"と無骨に出るはずだ。水曜から2日さかのぼると、月曜日。あってそうだ。
おめでとう!
プログラミング言語を使って、プログラムを書いて、そして動かして、結果が出た。
もう後はなんだって出来る。

最後に、「水曜日から、3.で覚えておいた"余り"分、さかのぼる。」のひとつのやり方と、少し変な表示の仕方だけ示しておこう。

youbi = ("Wed", "Tue", "Mon", "Sun", "Sat", "Fri", "Thurs")
X = 2000
amari = (2013 - X) % 7
kotae = 488 - ( (X // 4) - (X // 100) + (X // 400) )
amari2 = ( (amari) + (kotae) ) % 7
print "%d/3/27(%s)" % (X, youbi[amari2])

Pythonでコレがどんな意味を持つかは、"タプル"、"文字列フォーマット操作"を調べてみると良い。
(ほんのちょっとの差だし、単なる見栄えの問題でしか無いよ)

3. 次から何をしていけば良いか

一番大切な、"なにをやるか"を理解した。
本も最初から読まないように心がけた。
プログラミングも体験したし、実際にPython言語で実行もしてみた。
次はどうするか?
まず、さっきの例題を改良してみよう。世の中には3月27日生まれ以外の人も居る。
ぴったりうるう年に生まれた人も忘れないようにしたり、1873年以前を調べるとエラーが出るようにしても良いと思う。*3

他にも、次のような問題がある。

  • Fizz Buzz
  • 誕生日から1万日目
  • 札幌と那覇の正確な時差
  • 数独のソルバー(自動解答ツール)

思いつくままに、気になったものを解いていけば良い。
解き方を"アルゴリズム"と呼んだりする。
「1. まずは簡単な入門」でやったことが、アルゴリズムを自分で組み立てることだ。

いまは調べれば、問題を解くのに効率の良いアルゴリズムを見つけることが出来るだろう。*4
でも、せっかく楽しい部分なんだから、自分でやってみると良いと思う。

そうして小さなホビーを積み重ねていって、自分の「コレがやってみたい!」というものがみつかったら、それを実現するために調べながら作ってみると良いと思う。
文法書を読み始めるのは、それからでも遅くない。

プログラマになるのは難しくない。
ここまで手を動かしてやってみたなら、立派なプログラマだ。
やりたいことをやりたいようにやろう。

      • -

ここまで平易に書いても、きっと「職場にそんな安易なプログラマがやってこられたら困る」と思ってしまう人が居ると思う。
だから、そういう人にも満足してもらえるような本のリストを張って、このポストを締めたいと思う。
きっと、覚悟のある職業プログラマの先輩は以下の本を全部読んでるだろうし、ホビーで楽しくやってきたプログラマにプレゼントするには最適だってことには、賛成してもらえるだろうから。

繰り返しになるけど、初心者は本を買って読む必要はないよ。ググれ。
いずれ自分で読みたくなった時に、読めばいい。*5
「困ったときに調べて解決する」という"癖"は、陳腐化することが無いよ。

Head First JavaScript


このプログラミング入門を全部やって達成感を感じるような完全な初心者が一冊だけ買ってもらうなら、という本。
ヘッドファーストシリーズはゴリゴリ書き込んで実際にやってみるドリルなので、終えると達成感がある。*6
なお、ドリルなのでよくわからないところは自分でちゃんと調べる必要があります。文法書だと思って読むと期待はずれになるので、あくまでも演習問題集だと思ってやりましょう。

珠玉のプログラミング


封筒裏の計算ってヤツが、ほとんどすべての場合で重要だということを説明した本。
言語のチュートリアルを終えた初心者が読むと、かなり力がつくと思う。
演習問題は全部解いて見ることをオススメする。社内勉強会向けかも。
古臭い例題を解くパズル本といったところ。

ライト、ついてますか


解こうとする"問題"とは何なのかを分り易く説明した、まあ、エッセイ集のような本。
気楽に読めるし、大人って面倒だなーとか、コンサルタントって良いなあと思える良書。
箸休めに。

プログラミング言語C


古典。演習問題は全部やろう。
特に、第1章のやさしい入門の24問を全部解ければ、普段のちょっとしたスクリプトを書くのに困ることはなくなると思う。
小さくてコンパクト、そして何より、そのへんのオッサンに聞けば必ず持ってるので借りやすい。*7
これをひと通りやると「仕事でXXXという言語を使うことになったから」と言われた時に、ハイハイとその言語の入門書を読むのが楽になる。

計算機プログラムの構造と解釈


SICPと略される古典。
ハッキリ言って、Scheme上でScheme作る4章をやり遂げるのは、オッサンになってからだと辛い。
あと、原著はCCライセンスでネット上で読めるけど、日本語訳に?ってなった時に読むぐらいにした方が良いと思う。
ごく個人的には、プログラミング言語Cの練習問題を自力で解いていると読みこむのが楽かな、という印象。
プログラミングと言うよりは、"プログラミング言語"ってのはどういうものなのか、という本。どっちかというとホビープログラマ向け。

おまけ

初めてのPython


Pythonで一冊持っておくとするなら、コレ。
Python3.xが載ってないから古いけど、十分。
ぐぐってもイマイチよく判らんときに読むべし。

入門 自然言語処理


Pythonでなにかやってみたいな、と思った人が読むと面白いかもしれない本。
ちょろちょろ試して見ながら、12章と青空文庫で色々やると面白い。
高価な上に初めてのPython持ってると前半微妙なので、図書館に入れてもらおう。
集合知プログラミングよりは、こっちの方が面白かったけど、逆の人も居るかも)

*1:ホントのところを言えば、日本では1873年以前は調べられないけど、これはまた別の話

*2:中学校で習った、代数方程式のxと同じようなものだ。"変数"とか"代入"とか、調べてみよう。

*3:明治5年12月4日が存在しないのは結構有名だ

*4:例えば、曜日を調べるにはツェラーの公式というアルゴリズムがある

*5:「Head First JavaScript」みたいなゴリゴリ書き込んで使うタイプの本以外は借りれば良いと思う。

*6:来週からデータベースね、と言われた時に慌てて読んだHead First SQLには大変お世話になりました。

*7:付録の予約語一覧がなぜか縦向きで2ページにまたがっているのは未だに覚えてるくらい納得がいかない。