対象読者
- プログラミング未経験者 or 初学者 の方
- プログラミング学習の指針を得たい方
結論
プログラミング言語にはたくさんの種類があるし、書き方も異なる。プログラミングできるようになるにはどうすればよいだろうか。途方に暮れてしまうだろう。
だが、悩むことはない。兎に角、プログラミングを実践してみることがプログラミング習得の近道になる。コードも書かずに教材を読みまくっても、プログラミングができるようにはならない。本記事を読むよりも、コードを1行でも書くことに時間を割いた方がよいだろう。
しかし、簡単なプログラムを書くにしても、最低限の基礎が必要だ。
そこで、本記事では、少しでも早くプログラミングを行うために最低限押さえるべき基礎を以下に示す。
- 関数
- データ型
- 変数
- コンテナ
- 制御構文
以上!。
progateや書籍などで勉強されたことがある方ならば、他にもクラスや例外などの文法を勉強された方もいるだろう。しかし、これらの発展的な機能を初学者のうちに覚える必要はない。中学英語の簡単な文法と基本的な単語さえ押さえていれば、稚拙ながらも英会話ができることと同じだ。
必要なのは、知識が不完全であることを承知しながらも、アウトプットする勇気だ。
アウトプットしなければ身に付かない
プログラミングと英語の学習は似ている。両者とも、以下の学習ループを回す必要がある。
- 基礎(単語や文法、イディオムなど)を学び、
- それを元にアウトプットし、
- そのフィードバックから学び、
- 基礎を学び直し、…
日本人で英会話ができる人は少ない。私も例外ではなく、職場にいる外国人と顔を合わせることに恐々としてしまう汗。これは、日本の英語教育がライティングに偏重しているからだ!(言い訳)。
私は英語の読み書きなら、英会話に比べればマシにこなせる。プログラミング関連の英語ドキュメントを読むことができる。学校での英語学習を通して、リーディングに関するアウトプットとそのフィードバックを受けた経験があるからだ。
プログラミングの学習でも英語と同じように学ばなければならない。しかし、幸いなことに、プログラミングは英語と比べて学習が容易だ。英語ができない私でも、プログラミングを身に付けることができたのだから。
英語よりもプログラミングの学習の方が有利
学校の英語学習の肝は、テストや問題集を解くことだ。参考書を読むだけではなく、例題などを解いて、理解を確認していくことが必要だ。これがアウトプットとフィードバックを得る手段となる。
テスト勉強は、ひとりで行える部分が多く、比較的容易だが、ライティングや英会話の学習は難易度が高い。英作文ならば、添削してくれる先生が必要だし、英会話なら、話相手が必要となる。他人の協力なしには英語学習を進めることは難しい。
対して、プログラミングは英語に比べて、アウトプットのフィードバックを得ることが容易だ。コードを書くのは独りでできるし、そのコードが正しいかどうかは、プログラムがエラーを吐かずに実行できるかどうかでチェックできる。早朝でも深夜であっても、コンピュータは飽きもせずフィードバックを返してくれる。
このように、プログラミングの学習環境は恵まれている。とはいっても、プログラミング言語はたくさんあるし、書き方もそれぞれ違う、という点で英語という単一の言語を学ぶことに比べてハードルが高い。
しかし、気負いする必要はない。言語間で共通する部分は多いので、そこさえ押さえれば、別の言語に対しても、スムーズに習得することができる。
具体的な書き方は覚えなくていい
以下で、簡単なプログラムを2つの言語で比較することで、プログラミング学習における重要な点と覚えなくてもよい些末な点の区別の仕方を示す。
重要な点とは様々な言語間で共通する考え方であり、些細な点とは、言語特有の書き方のことだ。重要な点さえ押さえれば、些細な点を忘れても、その都度ググって解決できるようになる。
PHPとPythonによる文字列の分割の比較
プログラミングにおいて、文字を並べたものを文字列と呼ぶ。
フォルダの場所を示すような文字列をパスといい、”aaa/bbb/ccc”のように”/”で区切られた文字列で表される(windowsでは”/”ではなく”\”)。
以下に、パスを分割し、その結果を出力するプログラムをPHPとPythonで示す。
<?php
$split = explode("/", "aaa/bbb/ccc");
print_r($split);
Array
(
[0] => aaa
[1] => bbb
[2] => ccc
)
split = "aaa/bbb/ccc".split("/")
print(split)
['aaa', 'bbb', 'ccc']
覚えなくてよい点
文字列の分割には、PHPではexplode、Pythonではsplitという関数(後述)を使っていて、
- explodeでは2つの文字列の情報を引数(後述)として渡しているが、
- splitでは、引数は1つしか与えていない。
出力の仕方も、大体の言語にはprintみたいな出力用の関数が容易されていて、
- Pythonでは普通にprintを使っているが、
- PHPでは、単純なprintではなく、print_rという変種を使っている。
出力するためには、文字による表現(データ型の項目で後述)が必要となる。文字列の分割結果は単純な文字列ではなく、複数の文字列の集まり(コンテナの項目で後述)となる。なので、特殊なデータを出力するためのprint_rを使わなければならなかったのだ。Pythonでは、文字列の集まりをそのまま出力する機能が備わっているので、出力を文字列の場合と同様に行えた。
しかし、explode、splitやら、print、print_rやら、これらの詳細は覚えなくてよい。出力する機能や文字列を分割する機能は標準で準備されている、という点だけ覚えておいて、詳細はその都度ググればよい。
実際、動作するプログラムを作るためには、言語特有の書き方を覚える必要がある。しかし、別言語では通用しないかもしれない、と念頭に置いておくと、全て覚えきらなければならない、と力まなくても良いと分かって楽だ。
覚えるべき点
両者でまるで書き方が異なるが、
- 文字列”aaa/bbb/ccc”と区切り文字”/”を元に、”aaa”と”bbb”と”ccc”に分割し、
- 1.の分割結果を保存し、
- 2.を出力する
という構造はPHPでもPythonでも同じだ。異なる言語でも、大体似たような感じで書けるんじゃね?、という雰囲気を感じて欲しい。覚えべるべき点は、言語が異なっても共通する普遍的な知識だ。
私はPythonを業務で使っているが、PHPは少しかじったことしかない。でも、Pythonの経験から、当たりをつけてピンポイントに検索することにより、split.phpのコードをググって速攻で書くことができた(クソ簡単なコードだが)。
以下で、検索で当たりをつけるための必要最小限の基礎知識を順に紹介する。
- 関数
- データ型
- 変数
- コンテナ
- 制御構文
関数とは
関数とは、特定の目的に従った処理をまとめたもので、受け取った情報(引数と呼ぶ)を処理し、目的に応じた結果を得ることができる。
上の例で、explodeやsplitという「文字列を分割する」機能が登場しているが、これらは関数の一例だ。分割したい文字列と区切り文字という2つの情報から、分割された文字列の集まりを返している。
「文字列を分割する」みたいな関数はよく使われる。なので、そのような機能をプログラミング言語が予め準備していて、便宜を図ってくれる。これを標準ライブラリ(標準モジュール、組み込み関数とも)という。
しかし、上述の通り、具体的な書き方は言語ごとに異なる。なので具体的な書き方を覚えるよりも、「こういう良く使われそうで汎用的な機能は標準ライブラリとして用意してくれてるだろう」、と勘を働かせられることが大事だ。
データ型とは
元々、コンピュータは0か1かの情報しか扱えない。アルファベットの文字などを直に操っているわけではない。データ型とは、0と1の並び(ビット列)を意味のある値に解釈するための付加情報だ。
ほとんどの言語では、以下のようなデータ型が標準で用意されている。
- 文字(char型、 string型など)
- 整数(int型など)
- 実数(float型、double型など)
- 真偽値(真か偽かを表す、logical型、bool型など)
上の例で文字列を分割できたのは、文字列というデータ型の情報があったからだ。誤って、数値や真偽値を分割しようとしても、エラーになるはずだ。データ型があるおかげで、ビット列に対して適切な処理を人間のチェックなしに行うことができるのだ。
上記コードにおいて、print関数による出力が可能なのは、無味乾燥なビット列がデータ型の助けによって解釈できるためだ。
プログラミングとは、データを処理する方法をコンピュータに教えることだ。なので、データ型を意識することが重要になる。
文字列分割の例と同様に、データ型の書き方は言語によって異なる。真偽値の真の書き方ひとつをとっても、
- 1(C言語)
- 0など(Ruby)
- True(Python)
- true(PHP, Javaなど)
- .true.または.TRUE.など(fortran ∵大文字と小文字を区別しない)
という風に書き方が言語ごとに異なる。しかし、そんな違いはどうでもいい。私も慣れた言語のものしか覚えてない。重要なのは、ググるための当たりがつけられるかどうかだ。データ型とは何かさえ知っていれば、具体的な書き方は忘れても調べることができるので、詳細を覚える必要はない。
変数とは
変数とは、値を格納する入れ物のことだ(※1)。
これも書き方が言語によって異なる。”=”は数学の等号と同じで紛らわしいが、右辺を左辺に代入することを意味する記号だ。
- PHPなら、$変数名 = 値
- Pythonでは$なしで、変数名 = 値
でも、書き方の違いなんて些細なことだ。処理の結果を保持して、他の処理に受け渡すために変数は使われることが主だ。色んな処理を組み合わせてプログラムを作成する場合に、変数は重宝することになるだろう。
※1: 2種類の格納方法(発展的内容)
2つの格納方法を把握していないと、なぜか意図しない動作が発生して、プログラミングに苦戦する可能性がある。しかし、問題にぶち当たってから理解を深めればよい内容だ。実践を優先しよう。
値渡しと参照渡しの2種類がある。値渡しは、値のコピーを変数に格納する。参照渡しは、値のポインタを変数に格納する。ポインタとは、値を指し示す場所のことだ。直接値を渡すのではなく、ポインタという間接的なものを変数に格納する。
絵を描くべきか?
両者の違いは、変数の値を変更したときの元となった値への影響に現れる。値渡しの場合、変数を変更しても、元の値に影響はない。一方、参照渡しの場合、変数の変更は元の値はポインタを通して連動しているため、片方の変更によって、もう片方の変更も変更される。
コンテナとは
コンテナとは、複数の値をまとめるための入れ物だ。コンテナは主に以下の2種類ある(※1)。
- 配列(リストとも)
- 連想配列(辞書、ディクショナリ、ハッシュテーブルとも)
(1次元)配列とは、直線状に並んだ値の集まりだ。同種の値の集まりを表現することに適している。分割によってパスは複数の文字列になった。配列の登場にふさわしい場面だ。
連想配列とは、文字列と値の対応関係の集まりだ。人間に、性別や血液型、年齢などの異なる意味合いの値の集まりを表現することに適している。
値をまとめたからって何が嬉しいの?って感じだが、コンテナは制御構文(後述)と組み合わせることで真価を発揮する。
※1: 他のコンテナ(発展的内容)
配列にもいろんな変種がある、ということを頭の片隅においておけば、より効率的にプログラムが書ける場合があるが、初学者の内は無視してもよい。
配列の別種とは、タプルとセット(集合)だ。両者ともに、とある制約を持たせた配列だ。
タプルは変更が禁止された配列であり、平面上の座標を示したりするのに有効だ。
セットは数学的な集合を扱うためのコンテナだ。順序がなく、重複した値を追加することができないなどの制約がある。複数のデータの中で、重複した値を除去したいときなどに便利だ。
制御構文とは
通常、プログラムは上から下に向かって順に1行ずつ解釈し、実行する。制御構文は実行する行の順番を制御する。制御構文とは2種類ある。
- 条件分岐(if文やcase文など)
- 繰り返し(for文、while文など)
ぞれぞれは名前から想像できる通りの処理を記述するための文法だ。条件分岐によって、条件ごとに処理を分けることができる。繰り返しは同じ処理を複数回呼び出すことができる。
これら制御構文は実用的なプログラムを書く上で頻出だ。以下の例題を通して、制御構文の挙動のイメージを見る。
FizzBuzz問題[2]
最初のプレイヤーは「1」と数字を発言する。次のプレイヤーは直前のプレイヤーの次の数字を発言していく。ただし、3で割り切れる場合は「Fizz」、5で割り切れる場合は「Buzz」、両者で割り切れる場合(すなわち15で割り切れる場合)は「Fizz Buzz」(Bizz Buzzの場合は「Bizz Buzz」)を数の代わりに発言しなければならない。(wikipdia)
お笑い芸人の世界のナベアツ「3と5の倍数の時だけアホになる」ネタと同じ感じだ。コードとその出力は以下だ。
1から30までの連番をそれぞれ繰り返し条件分岐することによって、「FizzBuzz」、「Fizz」、「Buzz」、連番そのままのうちどれか出力する。
<?php
# range(1, 30)は1から30までの連番の配列
$numbers = range(1, 30)
foreach ($numbers as $i) {
if ($i % 15 === 0) {
echo 'FizzBuzz';
} elseif ($i % 3 === 0) {
echo 'Fizz';
} elseif ($i % 5 === 0) {
echo 'Buzz';
} else {
echo $i;
}
echo PHP_EOL;
}
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
繰り返し、配列から連番を順に取り出しながら、条件分岐を行っている。コンテナと制御構文の共演だ。値すべてを処理できなければ、コンテナで値をまとめてもメリットはない。
foreachは配列から順に値を取り出して繰り返し処理を行うものだ。一方、Pythonにはforeach文はなく、for文しかない。しかし、それは些末なことだ。重要なことは、繰り返し処理するための書き方があるはずだ、という予測ができるかどうかだ。
準備は整った!レッツ コーディング!
以上で、プログラミングを実践するための基礎知識は揃った。具体的な書き方はその都度調べつつ、兎に角コードを書いてみるべきだ。いきなり文法を網羅し、暗記しても、50~100行くらいの規模のコードを何度か書いた経験がないと、英会話できない日本人と同じように、プログラミングを身に付けることはできない。その経験を積むことによって、
- 発展的な文法だったり、
- 関数によって処理をまとめることの大切さ
など、次のステップへ進むための土台を固めることができる。何よりも、自分でコードを書いて動かすことは、楽しいし、モチベーションを上げることにも繋がる。
さあ、不完全な知識を承知しつつ、プログラムを書こう!
コメント