第2回 - コンピュータの原理、数値の比較と条件式、繰り返し処理

オフィスアワー (質問の時間) は、毎週 金曜日 9-10限 (18:05-19:45) とします。 NesrineさんとChenさんが交替で Discord 上の質問にお答えします。
  1. 前回の復習
  2. コンピュータの原理
  3. Python - 前回までのあらすじ
  4. Pythonで数値を表示・入力する
  5. 数値を計算する
  6. 数値を比較する
  7. 繰り返し処理をおこなう
  8. 足し算・掛け算を実現する
  9. 本日のまとめ・小課題

雑談

0. 前回の復習

0.1. パソコンの基礎

演習 2-1. ファイルとフォルダのパス名 (復習)

以下のようなフォルダ構造を考える。

ディスク A B C B E C K H K X /

以下の問に答えよ。 パスの区切り文字は「/ (スラッシュ)」とする。

  1. フォルダ X へのパス名 を答えよ。
  2. ファイル H へのパス名を答えよ。
  3. ファイル C へのパス名 (複数) をすべて答えよ。

0.2. Python プログラミングの基礎

  1. コマンド プロンプト (ターミナル) を起動する。
  2. デスクトップ上に "cs1" という名前のフォルダをひとつ作成し、 そこに hello.py というテキスト形式のファイルを新規作成する。 ここでは Windows であれば「メモ帳 (notepad)」、 Mac であれば「IDLE」を使う。 このようなアプリを以後テキストエディタ (あるいは単にエディタ) と呼ぶ。
  3. 以下のプログラムを入力する。
    greetings.py
    print("What is your name?")
    x = input("name:")
    print(f"Good morning {x}!")
    
  4. 完成したプログラム greetings.py を実行する。
演習 2-2. 変数の内容の交換 (復習)

以下のプログラムで、変数 x と変数 y の値を交換するにはどうするか。 ??? の部分を埋めよ。

p = 2
q = 3
??? ??? ???

1. コンピュータの原理

コンピュータ = おそろしく単純な動作 (後述) を大量に組み合わせて、複雑な処理をおこなう。

1.1. コンピュータの4大要素

すべてのコンピュータは 以下の4つの部分から成り立っている。

入力装置 演算装置 出力装置 記憶装置
  1. 入力装置 … マウス、キーボードなど
  2. 出力装置 … 画面、スピーカなど
  3. 記憶装置 … メモリ、ハードディスクなど
  4. 演算装置

スマートフォンも炊飯器もエレベータも、 コンピュータにしてみれば、やっていることは一緒。 入力装置から来た情報を演算装置であれこれ処理して、出力装置に渡しているにすぎない。 (人間さえ、コンピュータからみれば単なる外部装置のひとつにすぎない。)

演習 2-3. 入力装置と出力装置
  1. 炊飯器をコンピュータで制御する場合、その入力装置・出力装置を答えよ。
  2. エレベータをコンピュータで制御する場合、その入力装置・出力装置を答えよ。

1.2. 情報とは何か?

コンピュータ上の情報は、 2種類の異なる状態の組み合わせで表される。

数字、文字、画像、音声などをコンピュータで扱うためには、 これらの情報をすべて 01 だけで表す必要がある。

プログラムとは何か

プログラムも情報である。 コンピュータ・プログラムとは、 コンピュータがおこなう処理 (計算過程、プロセス) を いくつかの命令の列によって表現し、 それを実行することにより処理する。 プログラムは、記憶装置に入っている。

(注意: これは実際には数値の列なのだが、 現代は文字によって表せるようになっているので、 この授業ではもっぱらプログラミング言語を使って表現する)

演算装置 メモリ プログラム データ

1.3. 数値を 0 と 1 であらわす

我々がふだん使っている数 (10進数) は 「12345」を表すのに 1万文字を書いたりする必要はない。
「桁上がり」の考え方。

 

なぜ人間は10進数を使っているのか? → 5進数を使っている言語もあるらしい。

10進数と2進数の変換

10進数2進数
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
演習 2-4. 2進数と10進数の変換
  1. 上の表を完成させよ。
  2. 20 (10進数) を 2進数であらわせ。
  3. 10001 (2進数) を 10進数であらわせ。

重要な用語

1.4. 文字を 0 と 1 であらわす

1文字 = 1つの数値と考え、 数値の列を文字列とする。

1.5. 画像を 0 と 1 であらわす

ひとつの点 = 「ピクセル

00000000 00011000 00100100 01000010 01111110 01000010 01000010 01000010

ここでは、0 と 1 を数字でなく、ただ単に点の羅列として扱っている。 このように2進数以外の目的で 0 と 1 を並べたものを ビットマップという。

色を 0 と 1 であらわす

そもそも、色とは何か?

文字と画像の変換

1.6. 音声を 0 と 1 であらわす

音とは何か?

0

音声合成と音声認識

1.7. データの「形式」

コンピュータ上では、すべての情報は 0 と 1 からなる。 その意味は、解釈する方法によって決まる

0と1をどのように解釈するかがわからないと、正しく表示できない。 パソコンでは、ファイル名の拡張子によって、 その情報 (0と1) をどのように解釈するかを決めている。

テキストファイルとは

ただ文字コードを羅列したファイル。 文字の大きさや色、図表などの情報は含まれていない。

2. Pythonプログラムの構造

2.1. 最初の Python プログラム (再掲)

greetings.py
print("What is your name?")
x = input("name:")
print(f"Good morning {x}!")

2.2. print関数 - 文字を表示する

構文:
print("文字列")
print(f"文字列")
例1:
print("おおさまのみみはろばのみみ")
例2:
donkey = "ろばのみみ"
print(f"おおさまのみみは{donkey}")

f"〜" のようにすると、 {〜} で囲まれた部分が変数の内容になる。

例3:
donkey = "ろばのみみ"
print("おおさまのみみは{donkey}")
f をつけない場合、 {donkey} はただ文字列として表示される。

2.3. input関数 - 文字を入力する

構文:
変数名 = input("質問")
例1:
x = input("x:")
例2:
name = input("name:")
print(f"Hello, {name}")

問. 例2. のプログラムが何をしているか、日本語で説明せよ。

3. Pythonで数値を表示・入力する

以下の2つのプログラムは、どう違うのか?

letter.py
x = input("x:")
print(f"x is {x}")
value.py
x = int(input("x:"))
print(f"x is {x}")
演習 2-5. 数値の入力
  1. 上の2つのプログラムを実行し、それぞれ x の値として 123 を入力して実行結果を観察せよ。
  2. 上の2つのプログラムを実行し、それぞれ x の値として abc を入力して実行結果を観察せよ。

3.1. 数値の入力

input() 関数を int(...) 関数で囲むと、 キーボードからの入力を文字ではなく数値として 処理することができる。

構文:
変数名 = int(input("質問"))
例1:
y = int(input("y:"))

…これの何が面白いのか?

4. 数値を計算する

本授業で最初に使うのは、この2つだけ

inc.py
x = int(input("x:"))
x = x + 1
x = x + 1
print(f"x is {x}")
演習 2-6. 数値の計算
  1. 上のプログラム inc.py を実行し、 いろいろな数値を与えて結果を観察せよ。

5. 数値を比較する

Python では、2つの数値を比較し、 その結果によって異なる動作をさせることができる。 このような機能を 条件分岐 (conditional branch) という。

conditional.py
x = int(input("x:"))
print(f"x is {x}")
if x == 0:
    print("x is zero.")
else:
    print("x is not zero.")

上の if文のあとは、かならず インデント (indentation、字下げ) が必要である。 上の例をたとえば以下のようにすると動作しない:

エラーになる例:
x = int(input("x:"))
print(f"x is {x}")
if x == 0:
print("x is zero.")
else:
print("x is not zero.")

メモ帳を使っている場合は、インデントには半角スペース4個を使う。 IDLEを使っている場合は、TABキーを押すとインデントされる。

演習 2-7. 条件分岐の実行
  1. 上のプログラム conditional.py を実行し、 x に正の値と負の値を与えて結果を観察せよ。

5.1. if文 (パターン1)

構文:
if 条件式:
    条件式が真であるときに実行される文
else:
    条件式が真でないときに実行される文
例1:
password = int(input("password:"))
if password == 1234:
    print("Correct.")
    print("Good.")
else:
    print("Wrong.")
    print("Baka.")

ifelse の内側に 複数の文を入れることもできる。 この場合も、インデントが重要。

例2:
x = int(input("x:"))
if x < 0:
    print("x is negative.")
else:
    print("x is positive.")

問. このプログラムは正しくない。どこがどう正しくないのか?

例3:
x = int(input("x:"))
if x < 0:
    print("x is negative.")
else:
    if 0 < x:
        print("x is positive.")
    else:
        print("x is zero.")

ifelseのなかに、さらにif文が入ることもありうる。 この場合、「内側のif文」は2重に字下げされる。

演習 2-8. 条件式の変更
  1. 上のプログラム conditional.py を変更し、年齢を入力させて 20歳未満であれば "young!"、 20歳以上であれば "old!" と表示するようにせよ。

5.2. 条件式とは

Python では、条件式は if 文の中で変数の値の大小比較をするのに使う。

構文:
変数名あるいは数値 < 変数名あるいは数値
変数名あるいは数値 > 変数名あるいは数値
変数名あるいは数値 == 変数名あるいは数値
変数名あるいは数値 != 変数名あるいは数値
変数名あるいは数値 <= 変数名あるいは数値
変数名あるいは数値 >= 変数名あるいは数値
例1:
if x < 0:
    ... (x は 0 より小さい) ...
例2:
if t == 33:
    ... (t は 33 と等しい) ...
例3:
if 4 >= y:
    ... (y は 4 以下) ...
演習 2-9. 条件式の練習
  1. x が 3 のとき、x > 2 は成り立つか?
  2. y が 0 のとき、y < 0 は成り立つか?
  3. z が 1 のとき、1 != z は成り立つか?
  4. t が 7 のとき、3 > 7 は成り立つか?

5.3. if文 (パターン2)

構文:
if 条件式:
    条件式が真であるときに実行される文
条件式が真のときのみ何かを実行させたい場合、 else: 以降は省略できる。
例1:
x = int(input("x:"))
if x < 0:
    print("x is negative.")
print(f"x is {x}")
例2:
x = int(input("x:"))
if x < 0:
    print("x is negative.")
    print(f"x is {x}")
例3:
x = int(input("x:"))
if x < 0:
    print("x is negative.")
if 0 < x:
    print("x is positive.")
if x == 0:
    print("x is zero.")

6. 繰り返し処理をおこなう

Python ではある条件が真である間、 同じ動作を繰り返し実行 (ループ) させることができる。

loop.py
i = 0
while i < 10:
    print(f"i={i}")
    i = i + 1
print("end")

上のプログラム loop.py は、次のように実行される:

6.1. while文

構文:
while 条件式:
    条件式が真の間、繰り返し実行される文

条件式の中には、通常、変数が入っている。 この値が変化すると条件式の真偽も変わる。

例1:
i = 10
while i > 0:
    print(f"i={i}")
    i = i - 1
print("end")
例2:
i = 10
while i > 0:
    print(f"i={i}")
i = i - 1
print("end")
問. 上の 例2. と違っている箇所はどこか?

注意: プログラムの繰り返しが止まらない (無限ループ) 場合は、 Control + C を押して止めること。

例3:
x = 1
while x != 0:
    x = int(input("x:"))
print("end")
この繰り返しは変数 x に 0 が入力されるまで続く。
演習 2-10. 繰り返し
  1. 上のプログラム loop.py を変更し、0 から 20 までの数を 2きざみで表示するようにせよ。
    i= 0
    i= 2
    i= 4
    i= 6
    i= 8
    i= 10
    i= 12
    i= 14
    i= 18
    i= 20
    end
    
  2. さらにこのプログラムを変更し、i が 10 になった直後に "ten!" と表示せよ。 (ヒント: while文の中で if 文を使うこと)
    i= 0
    i= 2
    i= 4
    i= 6
    i= 8
    i= 10
    ten!
    i= 12
    i= 14
    i= 18
    i= 20
    end
    

7. 足し算・掛け算を実現する

これまでの成果を使うと、「1を足す」「1を引く」だけの計算を使って、 任意の正の整数の和 a + b を計算することができる。 (なお、ここでは簡単のため正の数のみを考える。)

add.py (未完成)
a = int(input("a:"))
b = int(input("b:"))
a = a + 1
b = b - 1
a = a + 1
b = b - 1
(... b が 0 になるまで繰り返す ...)
print(f"answer={a}")

この「b が 0 になるまで繰り返す」という処理を while文を使って書くと、以下のようになる:

add.py (完成版)
a = int(input("a:"))
b = int(input("b:"))
while 0 < b:
    a = a + 1
    b = b - 1
print(f"answer={a}")

ここで 0 < b のかわりに b > 0 や、 b != 0 などの条件式を使ってもかまわない。

実行例

a:2
b:3
answer=5

7.1. 足し算を使って掛け算を実現する

さらに上の結果を使って、今度は掛け算を実現することを考える。 以下のプログラムは与えられた整数 p と q に対して p × q を計算する。

mult.py (未完成)
p = int(input("p:"))
q = int(input("q:"))
a = 0
while 0 < q:
(変数 a に p の値を足す)
q = q - 1 print(f"answer={a}")

ここで (変数 a に p の値を足す) の部分に 上の add.py の処理を埋め込むと、以下のようになる:

mult.py (完成版)
p = int(input("p:"))
q = int(input("q:"))
a = 0
while 0 < q:
    b = p
while 0 < b: a = a + 1 b = b - 1
q = q - 1 print(f"answer={a}")

実行例

p:2
q:5
answer=10
演習 2-11. 足し算プログラム・掛け算プログラムの実行
  1. 上のプログラム add.pymult.py をそれぞれ実行せよ。
  2. mult.py を短くしようとして 「b = p」の部分を削って以下のようにするとうまく動かなくなる。 なぜか考えよ。
    p = int(input("p:"))
    q = int(input("q:"))
    a = 0
    while 0 < q:
        while 0 < p:
            a = a + 1
            p = p - 1
        q = q - 1
    print(f"answer={a}")
    

9. 本日のまとめ・小課題

小課題 3. 引き算および割り算をするプログラム (10月18日締切)
  1. まず引き算をするプログラム sub.py から完成させよう。 これは a - b を計算するものである。 ここでも正の整数のみを考える。 上の add.py を少し変更すればできる:
    a-b を求めるプログラム sub.py (未完成)
    a = int(input("a:"))
    b = int(input("b:"))
    while  ? :
        a =  ? 
        b =  ? 
    print(f"answer={a}")
    
  2. つぎに、sub.py の一部をさらに div.py の中で 使って割り算をおこなう。ここでの割り算は原始的に「引けなくなるまで繰り返し引く」 方法を使う。したがって、商 (quotient) と余り (remainder) の両方を計算する必要がある。
    x ÷ y を求めるプログラム div.py (未完成)
    x = int(input("x:"))
    y = int(input("y:"))
    q = 0
    while y <= x:
    
    (変数 x から y を引く)
    print(f"quotient = {q}") print(f"remainder = { ? }")

Yusuke Shinyama