なぜプログラミングは油絵のようにいかないのか?
コンピュータ上の情報は、 2種類の異なる状態の組み合わせで表される。
数字、文字、画像、音声などをコンピュータで扱うためには、 これらの情報をすべて 0 と 1 だけで表す必要がある。
print(...) や input(...) などの関数を使用できる。
1, 11, 111, 1111, 11111, ...
0, 1, 0, 1, 0, 1, 0, ...
我々がふだん使っている数 (10進数) は 「12345」を表すのに
1万文字を書いたりする必要はない。
「桁上がり」の考え方。
なぜ人間は10進数を使っているのか? → 5進数を使っている言語もあるらしい。
| 10進数 | 2進数 |
|---|---|
| 0 | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
1文字 = 1つの数値と考え、 数値の列を文字列とする。
ひとつの点 = 「ピクセル」
ここでは、0 と 1 を数字でなく、ただ単に点の羅列として扱っている。 このように2進数以外の目的で 0 と 1 を並べたものを ビットマップという。
そもそも、色とは何か?
R, G, B の各要素をそれぞれ 8ビット (0〜255) で表すと、 256×256×256種類の色が表現できる。 以下の色に(ほぼ)対応する RGB値、または対応する色を答えよ。 (例: 赤 = R…255, G…0, B…0)
音とは何か?
10, 25, 35, 40, 45, 40, 35, ...
コンピュータ上では、すべての情報は 0 と 1 からなる。 その意味は、解釈する方法によって決まる。
0と1をどのように解釈するかがわからないと、正しく表示できない。 パソコンでは、ファイル名の拡張子によって、 その情報 (0と1) をどのように解釈するかを決めている。
Macでは (Windowsでも)、ファイルの拡張子はふだんは表示されない設定になっている。 これを変更するには、以下のようにする:
.txt
.doc または .docx
.xls または .xlsx
.jpg または .jpeg
.png
.htm または .html
.mp3 など
.mp4, .mov など
.zip
.app, .exe
ただ文字コードを羅列したファイル。 文字の大きさや色、図表などの情報は含まれていない。
Hello! 01001000 01100101 01101100 01101100 01101111 00100001
日本 11100110 10010111 10100101 11100110 10011100 10101100
長いので、こっちに移動しました。
print(...) や input(...) などの関数を使用できる。
IDLE を使おうとするとパソコンがクラッシュする (異常終了する) ので、 CotEditor を使うことにした。
cd する。
greetings.py
というテキストファイルを作成する。
$ cd Desktop $ mkdir cs1 $ cd cs1 $ cot -n greetings.py (すでにファイルが存在する場合 -n は不要)
print("What is your name?")
x = input("name=")
print(f"Good morning {x}!")
greetings.py を実行する。
$ python greetings.py What is your name? name=euske Good morning euske!
print("文字列")
print(f"文字列")
print("おおさまのみみはろばのみみ")
donkey = "ろばのみみ"
print(f"おおさまのみみは{donkey}")
f"〜" のようにすると、
{〜} で囲まれた部分が変数の内容になる。
donkey = "ろばのみみ"
print("おおさまのみみは{donkey}")
f をつけない場合、
{donkey} はただ文字列として表示される。
変数名 = input("質問")
x = input("x=")
name = input("name=")
print(f"Hello, {name}")
以下の2つのプログラムは、どう違うのか?
x = input("x=")
print(f"x is {x}")
x = int(input("x="))
print(f"x is {x}")
123 を入力して実行結果を観察せよ。
abc を入力して実行結果を観察せよ。
input() 関数を int(...) 関数で囲むと、
キーボードからの入力を文字ではなく数値として処理することができる。
変数名 = int(input("質問"))
y = int(input("y="))
…これの何が面白いのか?
本授業で最初に使うのは、この2つだけ。
変数名 = 変数名 + 1 (変数の値に1を足す)
変数名 = 変数名 - 1 (変数の値から1を引く)
x = int(input("x="))
x = x + 1
x = x + 1
print(f"x is {x}")
inc.py を実行し、
いろいろな数値を与えて結果を観察せよ。
Python では、2つの数値を比較し、 その結果によって異なる動作をさせることができる。 このような機能を 条件分岐 (conditional branch) という。
x = int(input("x="))
print(f"x is {x}")
if x == 0:
print("x is zero.")
else:
print("x is not zero.")
上の if文のあとは、かならず
インデント (indentation、字下げ) が必要である。
CotEditor では、Tab キーを使ってインデントをおこなう。
conditional.py を実行し、
x に正の値と負の値を与えて結果を観察せよ。
if 条件式:
条件式が真であるときに実行される文
else:
条件式が真でないときに実行される文
password = int(input("password?"))
if password == 1234:
print("Correct.")
print("Good.")
else:
print("Wrong.")
print("Baka.")
if や else の内側に
複数の文を入れることもできる。
この場合も、インデントが重要。
x = int(input("x="))
if x < 0:
print("x is negative.")
else:
print("x is positive.")
このプログラムは正しくない。どうすればよいか?
x = int(input("x="))
if x < 0:
print("x is negative.")
else:
if 0 < x:
print("x is positive.")
else:
print("x is zero.")
ifやelseのなかに、さらにif文が入ることもありうる。
この場合、「内側のif文」は2重に字下げされる。
conditional.py を変更し、年齢を入力させて
20歳未満であれば "young!"、
20歳以上であれば "old!" と表示するようにせよ。
Python では、条件式は if 文の中で変数の値の大小比較をするのに使う。
変数名あるいは数値 < 変数名あるいは数値 変数名あるいは数値 > 変数名あるいは数値 変数名あるいは数値 == 変数名あるいは数値 変数名あるいは数値 != 変数名あるいは数値 変数名あるいは数値 <= 変数名あるいは数値 変数名あるいは数値 >= 変数名あるいは数値
if x < 0:
... (x は 0 より小さい) ...
if t == 33:
... (t は 33 と等しい) ...
if 4 >= y:
... (y は 4 以下) ...
x が 3 のとき、x > 2 は成り立つか?
y が 0 のとき、y < 0 は成り立つか?
z が 1 のとき、1 != z は成り立つか?
t が 7 のとき、3 > 7 は成り立つか?
if 条件式:
条件式が真であるときに実行される文
条件式が真のときのみ何かを実行させたい場合、
else: 以降は省略できる。
x = int(input("x="))
if x < 0:
print("x is negative.")
print(f"x is {x}")
x = int(input("x="))
if x < 0:
print("x is negative.")
print(f"x is {x}")
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.")
Python ではある条件が真である間、 同じ動作を繰り返し実行 (ループ) させることができる。
i = 0
while i < 10:
print(f"i={i}")
i = i + 1
print("end")
上のプログラム loop.py は、次のように実行される:
i < 10 である。したがって while文中の i = i + 1 が実行され、 i = 1 となる。
i < 10 である。したがって while文中の i = i + 1 が実行され、 i = 2 となる。
i < 10 である。したがって while文中の i = i + 1 が実行され、 i = 3 となる。
i < 10 である。したがって while文中の i = i + 1 が実行され、 i = 4 となる。
i < 10 である。したがって while文中の i = i + 1 が実行され、 i = 5 となる。
i < 10 である。したがって while文中の i = i + 1 が実行され、 i = 6 となる。
i < 10 である。したがって while文中の i = i + 1 が実行され、 i = 7 となる。
i < 10 である。したがって while文中の i = i + 1 が実行され、 i = 8 となる。
i < 10 である。したがって while文中の i = i + 1 が実行され、 i = 9 となる。
i < 10 である。したがって while文中の i = i + 1 が実行され、 i = 10 となる。
i < 10 ではない。したがって while文の次の文である
print("end") が実行される。
while 条件式:
条件式が真の間、繰り返し実行される文
条件式の中には、通常、変数が入っている。 この値が変化すると条件式の真偽も変わる。
i = 10
while i > 0:
print(f"i={i}")
i = i - 1
print("end")
i = 10
while i > 0:
print(f"i={i}")
i = i - 1
print("end")
問.
上の 例2. と違っている箇所はどこか?
注意: プログラムの繰り返しが止まらない (無限ループ) 場合は、 Control + C を押して止めること。
x = 1
while x != 0:
x = int(input("x="))
print("end")
この繰り返しは変数 x に 0 が入力されるまで続く。
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
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
これまでの成果を使うと、「1を足す」「1を引く」だけの計算を使って、 任意の正の整数の和 a + b を計算することができる。 (なお、ここでは簡単のため正の数のみを考える。)
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文を使って書くと、以下のようになる:
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 などの条件式を使ってもかまわない。
さらに上の結果を使って、今度は掛け算を実現することを考える。 以下のプログラムは与えられた整数 p と q に対して p × q を計算する。
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 の処理を埋め込むと、以下のようになる:
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}")
add.py、 mult.py をそれぞれ実行せよ。
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}")
本日の成果を使って以下の 2つのプログラムを完成させ、OCW-i から提出せよ。
sub.py」と
および割り算をするプログラム「div.py」を完成させよ。sub.py から完成させよう。
ここでも正の整数のみを考える。
上の add.py を少し変更すればできる:
a = int(input("a="))
b = int(input("b="))
while ? :
a = ?
b = ?
print(f"answer={a}")
sub.py の一部をさらに div.py の中で
使って割り算をおこなう。ここでの割り算は原始的に「引けなくなるまで繰り返し引く」
方法を使う。したがって、商 (quotient) と余り (remainder) の両方を計算する必要がある。
x = int(input("x="))
y = int(input("y="))
q = 0
while y <= x:
(変数 x から y を引く)
print(f"quotient = {q}")
print(f"remainder = { ? }")
なお、OCW-i に提出する際のコメント欄はほとんど読まないので、 あまり重要なことは書かないこと。(読みとばす危険性がある)