コンピュータとは
そもそもコンピュータとは何なのでしょうか?コンピュータは電子回路を利用して計算を行う機械です。コンピュータ内の様々な情報処理は、大元に行きつけば電圧のon offの組み合わせや電流の流れで物理的に実行されています。イメージを持ってもらうためにショートカットキーの例で説明します。
ショートカットキーとは、キーボードのある二つのキーを同時に押したとき、特定の処理が実行される機能です。例えば「Ctrl」 と 「S」を同時に押すと「保存」行われます。Macの場合「Command」+「S」です。この命令は以下のような電気回路で表すことができます。
この回路は、2つの入力の両方の電流がonのときのみ出力側に電流を通過させるような回路です。それぞれの入力端子が直列に出力方向につながれているような構造になっていて、ANDゲートと呼ばれます。
「Ctrl」を押している信号と「S」を押している信号、両方の電気信号が回路に入って通過したときのみ出力側に電気が流れ、「保存」する命令が実行されます。上記のような電流のon offで表現されるのですね。数字に置き換えれば、1,0 と対応付けることができます。この0,1の一つのペアはコンピュータの情報量の基本単位として1bitと表現されます。8bit = 1byteです。日常生活においてもスマホの容量は128GB(ギガバイト)のように見かけるかと思います。数学的には2進法で計算されていきます。このような原理を基にして、コンピュータは命令を実行しているのだと理解しておきましょう。
他にもORゲートやNANDゲートなどの回路が存在します。より詳しく知りたい方は、「論理回路」のようなワードでググってみてください。
上記の原理を基にして、CPUと呼ばれる中央処理装置やメモリと呼ばれる記憶装置、マウスなどの入力装置、ディスプレイなどの出力装置を組み合わせたものが所謂今日のコンピュータです。
プログラミングとは
「プログラミング」はコンピュータを動かすための指令を書くことを言います。指令のことを「プログラム」と言います。コンピュータはそれらの指令を最終的には電気信号に落とし込んで処理を行います。しかし、電気信号の命令を直接私たちが書き下すことは困難です。そこで、人間が理解しやすく、言葉のように命令を記述できる様々なプログラミング言語が開発されてきました。(C言語, HTML, CSS, Ruby, Java script, Python etc...)私たちはそれらのプログラミング言語を利用することで、簡単にコンピュータに命令を与えることができるというわけです。
それぞれの言語には設計思想があり、定められた規則、文法に厳格に従わなければいけません。また、コンピュータは最終的には物理的な電気信号によって処理が行われるため、一つでもミスがあれば思うように動いてくれません。これを「エラー」とか「バグ」と言ったりします。一般的にプログラミングを用いたアプリ開発においては、たくさんのエラーを経験することになります。
次に、Pythonの基本文法を通して、プログラミングの概要について触れていきます。
Pythonの基本文法
Pythonは人気言語であり、AIをはじめとした多くの分野でよく用いられています。Pythonの文法を簡単に触れていきましょう。これを通してプログラミングの基本的な考え方の理解に役立てて頂ければと思います。
※以下のコードは実行する必要はありません。読み物として読んでいって軽く頭に入れておいてもらえれば大丈夫です。
計算処理
簡単な計算処理は、算数と同じように書くことができます。
1+1
=> 2
2*3
=> 6
15%4
=> 3
変数
変数とは、データにアクセスするためにつける名前のことです。
変数名 = データ
のように記述します。ここで用いる「=」は数学の等号の意味は無く、代入の意味で用いられます。
x = 3
y = 4
x * y
=> 12
これはどのようなときに役立つのでしょうか?
例えば、Webアプリを利用する際、ログインするときにメールアドレスを入力しますよね。このメールアドレスそのものは「データ」ですが、これをemailという変数に代入することで、後から参照したり利用するときにとても便利になります。
email = ユーザーが入力したメールアドレス
password = ユーザーが入力したパスワード
# 上記で定義された変数、email, passwordを用いて以下のプログラムを実行することができます。
1 : emailがデータベースの中に存在するか調べる
2 : もし、存在したらpasswordが合っているか照合する
3 : 合っていればユーザーの閲覧を許可する
データ型
コンピュータ内で扱われる情報は、最終的には電気信号に落とし込まれます。電気信号は2進法として計算されるため、数字のように考えることができます。普段私たちが入力する文字も実はすべての文字に番号が割り振られています。文字化けという現象に遭遇したことはありますか?日本語の番号対応付けにはいくつかの規格化されたものが存在します。(UTF-8, Shift-JISなど) これらをごちゃ混ぜにしてしまうと、異なる番号に対応した文字が呼び出されてしまうため文字化けが起きるのですね。ここで、「文字には番号が振られている」と言いました。この番号は、数値計算されてしまっては全く意味を持たないものです。そのため、コンピュータ内で情報を扱う際は、数値と文字を区別して扱わないと、筋が通らなくなりバグの温床になってしまいます。
そこで、データ型という概念が出てきます。意味のある適切な演算を実行するために、情報をいくつかグルーピングしておくことで、違法な演算を未然に防ぐことができるのです。またデータはもちろん全て物理的な領域上に保存されているので、確保すべきメモリ領域を事前に決めておければ、効率的に利用することもできます。
データ型はいくつか存在するのですが、ここではおおまかに数字と文字列を例にして以下を実行してみます。
文字列はダブルクオーテーション「""」で囲うことで表現できます。
文字列同士の足し算は、連結されます。
x = "おはよう"
y = "ございます"
x + y
=> "おはようございます"
"文字列としての数値"を足し算してみましょう。
x = "12"
y = "3"
x + y
=> "123"
このように足し算の記号を用いた場合、数値計算されて15になるのではなく、文字列としての連結が行われます。
では、数値と文字列同士の足し算ではどうなるのでしょうか?
x = 12
y = "3"
x + y
=> TypeError: unsupported operand type(s) for +: 'int' and 'str'
エラーが出力されました。Integer=整数, String=文字列を意味します。TypeError(種類のエラー)とあるので、データ型が一致しないために足し算の演算は行えないといったことがエラー文から読み取れるかと思います。
このようにコンピュータは、データの種類を区別して扱う必要があるのだと覚えておきましょう。
比較演算子
比較演算子は、データ同士を比較する際に用いる演算です。例えば、値同士が一致しているかどうかを調べたり、値の大小関係を調べたりするときに用います。Webアプリでは、検索機能や、投稿の並べ替えなどに利用されます。
ここでも注意が必要で、比較する値同士のデータ型は揃えなければ意味を持たなくなるためエラーが出力されてしまいます。
例として同値かどうかを調べる「==」演算子を取り上げます。
※変数を代入するときは「=」、同値かどうかを調べる比較演算子は「==」です。数学的な意味とは異なりプログラミング特有の概念なので区別して理解しましょう。
x = "佐藤"
y = "佐藤"
x == y
=> True
x = "佐藤"
y = "田中"
x == y
=> False
同値である場合はTrue、異なる場合はFalseが出力されました。この比較演算子は以下の条件分岐を表現する際に大いに役立ちます。
条件分岐
条件分岐とは、呼び名の通り「もしこうだった場合はこうする、そうでなかった場合はこうする」のように条件によって分岐されることを表現する際に用います。これも物理的には電気回路によって実現され、電流が流れるor流れないで考えることができます。
これはif文を用いて記述されます。以下の具体例を見てみてください。
age = 23
if age >= 20:
"adult"
else:
"child"
=> "adult"
英語の意味のまま素直に読解することができます。もし年齢が20歳以上であれば大人、そうでなければ子供、という条件を表現しています。
age変数は23という数値が代入されていて、age変数をif文の中で用いています。結果として"adult"が出力されました。
このような条件分岐はプログラミングの世界では非常によく使われるものです。変数の章でも出てきたように、Webアプリにログインする際、メールが存在し、パスワードが一致した場合はログインを許可する、といったような動作を書くことができます。
繰り返し処理
コンピュータは情報をメモリという場所に物理的に保存しています。それぞれの情報には住所に当たる番地が割り振られていて、特定の情報にアクセスするときはその番地を参照しています。
また、複数の同じ性質の情報はひとまとまりの集合体として扱うことができ、この集合体のことを配列と言います。ここでは例として、ある生徒の国語、数学、英語3科目のテストの点数が順にまとまったものを考えます。
配列は大かっこ[]を用いて以下のように記述されます。
scores = [80, 85, 94]
配列の中にある複数の情報も、物理的にはメモリ上に番地が割り当てられています。もし、配列の各要素を順に取り出して何らかの処理をしたい場合、各要素ごとに毎回処理を記述していては同じコードを何度も書くことになってしまいます。そこでプログラムの醍醐味、繰り返し処理の登場です。
例として、それぞれの点数が90点以上であればA, それ以外であればBをつけるということを実装していきます。繰り返し処理は主にfor文を用いて記述されます。また、if文を用いて条件分岐処理を記述します。
scores = [80, 85, 94]
for score in scores:
if score >= 90:
"A"
else:
"B"
=> B B A
上記のfor文も素直に読解することができます。scores配列に入っている各要素が順にscore変数に代入されて、各要素に対しif文の条件処理が行われています。例えば1回目はscore = 80となり、if文で用いられます。scores配列は3つの要素を持っているので、2回目、3回目も同様にscoreに85, 94が順に代入されて実行されています。
上記のように、配列を用いてその要素を順に取り出して繰り返し処理を行うといった実装は、機械学習においても頻繁に登場してきます。例えば、学習用の画像セットが配列の中に入っていて、それを一枚ずつ取り出して検証するといった具合です。
この考え方は今後もよく扱うのでぜひ押さえておきましょう。
関数
関数は、数学的にはy=f(x)のような表記で馴染み深い?かと思います。中学数学で数学的な関数の定義を学びました。覚えていますか?それは「xが決まったらyも一意に定まる」というものでした。y=2x という関数では、x=5だったときxが2倍されてy=10となります。プログラミングの世界でも同様に「ある入力を受けたら、特定の処理を行い、ある結果を出力する」といったものを関数と呼びます。
変数の章でデータを扱う際、名前を付けると後で利用するときに便利だと書かれていましたね。関数もこれと同じ考え方で、「処理」に名前を付けます。そうすることで、特定の処理を後で簡単に再利用することができるようになります。また、処理ごとにグルーピングすることで、プログラミングの全体像を構造化でき、全体像が理解しやすくなります。
例として、3つの変数を受けたら、その平均値を返す関数を定義します。関数の記述にはdefを用います。
def average(a,b,c):
sum = a+b+c
average_value = sum / 3
return average_value
上記のようにして定義できました。average(a,b,c)の()の中は引数と言い、入力を表します。変数を用いて計算を行い、return average_valueによって平均値が出力されます。
上記は、ただ定義しただけなので、次に具体的な数字を入れてこれを実行してみます。
average(3,5,7)
=> 5.0
このようにして実行することができました。平均値を求める作業を繰り返し行いたいとき、毎回平均値の数値計算を書き下していては、読みにくく分かりにくいコードになってしまいます。そのため、関数化してしまえれば1行で処理してくれるのでとても便利です。
機械学習では、ある処理を行う一連の流れがいたるところで用いられることがあります。例えば、正解と予測の乖離を計算する損失関数を定義して、この関数をモデル中で利用したりしています。
最後にもう一つPythonの文法を扱う際に留意しておかなければいけないことがあります。if文, for文, 関数に共通していることは、各ブロックのカタマリはインデントで認識されるというものです。
for score in scores:
if score >= 90:
"A"
else:
"B"
入れ子構造が深くなってくると、インデントで視覚的に読解できるのでとても便利なしくみですね。しかし、同じブロックのインデントを揃えないとIndentationError: unexpected indent
のようなエラーが出力されてしまいます。頭の片隅に入れておきましょう。
まとめ
コンピュータとは何か?から始まってPythonを用いてプログラミングについて解説してみました。皆さんのお役に立てると幸いです。