素数を表示してみる_プログラミング
さっそくですが、前章で例示したプログラムをpythonで書いてみます。
- 100までの数を、一時保存できる変数(NaturalNumber)を用意する
- 反復処理の回数を、一時保存できる変数(Counter)を用意する
- 変数(Counter)に1を代入する
- 変数(Counter)が100になるまで、以下の処理を繰り返す
- 変数(NaturalNumber)に、変数(Counter)の値を代入する
- 変数(Counter)の値に1を足す
- 変数(Counter)に変数(Counter)の値を代入する
- #100までの数を、一時保存できる変数(NaturalNumber)を用意する
- NaturalNumber = []
- #反復処理の回数を、一時保存できる変数(Counter)を用意する
- Counter = 0
- #変数(Counter)に1を代入する
- Counter = 1
- #変数(Counter)が100になるまで、以下の処理を繰り返す
- while Counter <= 100:
- #変数(NaturalNumber)に、変数(Counter)の値を代入する
- NaturalNumber.append(Counter)
- #変数(Counter)の値に1を足す
- #変数(Counter)に変数(Counter)の値を代入する
- Counter = Counter + 1
- print (NaturalNumber)
#から始まる行は「コメント」と言って、プログラムの動作に全く影響を及ぼさない行になります。各コメントの下にプログラムが書かれています。
実行結果は以下の通りです。
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
では、1行ずつ見ていきましょう。
配列という変数
まず、1行目の
NaturalNumber = []
ですが、これは、配列というものを宣言します。
実は、変数には「値が入るもの」「オブジェクトが入るもの」の2種類あります。「値」というのは、足す、引く、かける、わる、が直接できるものです。「オブジェクトは足す、引く、かける、わる、が直接できないもの」です。
オブジェクトには「画像」や「動画」などがあります。例えば、画像から緑色だけを抜き出したいという場合は、極小な1点1)ごとに分けて、その1点に光の三原色(赤・緑・青)がどの程度の割合で混ざり合っているかを調べたうえで、赤の割合と青の割合を引きます。このように、オブジェクトを扱う場合でも、四則演算に落とし込むことができるのですが、オブジェクト自体は一時的に保存しないといけません。というわけで、変数の種類には値が入るものと、オブジェクトが入るものの2種類あるわけです。
では、配列とは何か、というと、値やオブジェクトを複数持てるものとなります。配列以外の変数は、値やオブジェクトを1つしか持てません。そして、値やオブジェクトの状態が変わればその都度上書きされます。ですが、配列は何個も値やオブジェクトを持つことが出来ます。
また、配列自体をオブジェクトと捉える場合が多いです。というのは、単に値を持っている配列であっても、目次付きの値であるからです。つまり、1番目の値は○○、2番目の値は△△というように、各値には~番目という位置を表す目次のような情報が付与されます。この目次のことをインデックスもしくは添え字と言います。目次を持っている以上、足す、引く、かける、わる、が直接できないものとなりますので、オブジェクトとして扱われるということです。
で、オブジェクトを表す変数というのは、多くのプログラム言語ではインスタンスを作る必要があります。
インスタンスという難しい話
変数を扱う場合には、メモリを意識する必要があるというのが、一昔前なのか今でも主流なのかわかりませんが常識でした。というのは、変数というのはあくまで一時的に保存できるものですが、大量に宣言してしまうと、コンピュータ内のメモリ(一時保存領域。ハードウェア)がパンクしてしまうからです。メモリがパンクすると、コンピュータはすぐに不能になります。そのため多くのプログラム言語では、メモリを安全に使用するために変数が確保できる領域を決めておきます。例えば、整数という値を扱う変数の場合はは、-2,147,483,647 から 2,147,483,647の間の整数のみ格納できる、という具合に使用するメモリ量の最大値を決めておくのです。そうすれば、プログラム実行時の最大メモリ使用量が計算できたりします。
ですが、画像や動画、先ほどの配列の場合は、可能性が無限大ですので、いくらでもメモリを使用することができてしまいます。
メモリを無限に使用する可能性というのは、非常に良くないので、多くのプログラム言語では、「使用する許可を取る」という宣言と、「メモリ上に必要な領域を確保する」という作成という二段構えをした上で、ようやく使用できる(プログラムコードとして書けるようになる)状態になります。
二段構えをせずに、変数を使用することを「コンパイルエラー」、二段構えをしたのに必要な領域以上の領域を使用してしまうことを「実行時エラー」と言います。 コンパイルエラーは、ソースコードをコンパイル(ビルド・構築など言い方はいっぱいある)する時にわかります。 実行時エラーは、コンパイルした後に実行してみて初めて気付くエラーです。
コンパイル2)
このとき、「使用する許可を取る」ことを宣言と言います。また、「メモリ上に必要な領域を確保する」ことをインスタンスの作成と言います。pythonではインスタンスがわかりにくいので、Javaで同じ実行結果が得られるように書いてみましょう。
- import java.util.*;
- public class Main {
- public static void main(String[] args) throws Exception {
- //100までの数を、一時保存できる変数(NaturalNumber)を用意する
- int[] NaturalNumber;
- //NaturalNumberのインスタンスを作成する
- NaturalNumber = new int[101];
- //反復処理の回数を、一時保存できる変数(Counter)を用意する
- //変数(Counter)に1を代入する
- int Counter = 1;
- //変数(Counter)が100になるまで、以下の処理を繰り返す
- while (Counter <= 100){
- //変数(NaturalNumber)に、変数(Counter)の値を代入する
- NaturalNumber[Counter] = Counter;
- //変数(Counter)の値に1を足す
- //変数(Counter)に変数(Counter)の値を代入する
- Counter = Counter + 1;
- System.out.print(NaturalNumber[Counter - 1]);
- System.out.print(",");
- }
- }
- }
実行結果は以下の通りです。
1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15 ,16 ,17 ,18 ,19 ,20 ,21 ,22 ,23 ,24 ,25 ,26 ,27 ,28 ,29 ,30 ,31 ,32 ,33 ,34 ,35 ,36 ,37 ,38 ,39 ,40 ,41 ,42 ,43 ,44 ,45 ,46 ,47 ,48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 ,58 ,59 ,60 ,61 ,62 ,63 ,64 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 ,73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 ,83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,91 ,92 ,93 ,94 ,95 ,96 ,97 ,98 ,99 ,100 ,
まず、Javaはおまじないを書かないと動かないので、6行目から26行目に注目してください。
9行目の
NaturalNumber = new int[101];
が、インスタンスを作成している部分です。new演算子といって、インスタンスを作成するときに使い、大きさ101個3)の値を格納できるようにしています。インスタンスの作成はメモリの確保ですので、大きさも指定する必要があるのですね。
このように、オブジェクトの扱い方には言語によってクセがあるということを注意しておいた方が良いでしょう。
繰り返し処理
繰り返し処理にはいろいろありますが、最も簡単なのはこの
while Counter <= 100:
を使用することです。使い方はとっても簡単で、while の後ろに繰り返し条件を示す式を書きます。条件を示す式は条件式とも言いますが、式の戻りがBollean型でないといけません。
式の戻りというのは、式を評価した後の結果のことを指します。また、Boolean型というのはTrueもしくはFalseの2つの状態しか持たない変数の型です。つまり、式を評価した結果=真ならtrueが戻り、式を評価した結果=偽ならfalseが戻ります。このようにBoolean型で戻す式に使う演算子を比較演算子と言います。
pythonでは、等価を表す場合は「==」を使います4)。また否定を表す場合は多くのプログラム言語では、「!」を使います。pythonでは異なる場合は「!=」を使います。あとは、<や>を使用して大小を比べます。
下に例を示します。
- print (1==1)
- print (2==1)
- print (1!=1)
- print (2!=1)
- print (1 <1)
- print (1<=1)
- print (2 <1)
- print (2<=1)
実行結果
- True
- False
- False
- True
- False
- True
- False
- False
詳しくは、演算子で遊んでみるでまとめます。
とにもかくにも、繰り返し処理は条件式の戻りがtrueである限り何度も何度も実行するということです。サンプルでは、「Counter ⇐ 100」となっているので、Counterの値をインクリメント5)していかないと、無限に繰り返し処理が実行されます。Counterの値をインクリメントせずに、繰り返し処理を何度実行してもCounterの値が1のままだと、「Counter ⇐ 100」の評価がずっとtrueになってしまいますね。
配列へ値を追加する
14行目
NaturalNumber.append(Counter)
では、NaturalNumberにCounterの値を追加しています。pythonでは配列を扱うときに、インスタンスの作成を明記しない=大きさを決めない=使用するメモリを確保しないので、新しいインデックスに値を追加するという作業をします。
これがappendメソッドです。メソッドというのは、オブジェクトに付随した機能のことです。NaturalNumberは配列というオブジェクトですから、いろんな機能を持っています。写真データも位置情報を持っていたりするでしょ。そんな感じで、オブジェクトにはよく使う機能がメソッドという形で提供されています。
NaturalNumber.append
の「.」は「の」と訳すと理解が早くなると思います。ここでは「オブジェクトNaturalNumberのappendメソッド」を使うぞということです。
メソッドには通常引数が必要です。引数というのは( )の中に書くものですが、ここでは「Counter」を書いていますので、メソッドには「Counter」が渡されます。メソッドは引数を元になんらかの処理を実行するものと捉えても良いと思います。
ここまでで、ようやく100までの数を用意することができました。次回はもっと進みます。