Python は映画やアニメの製作でもよく使われている: Python For Feature Film
西暦 y 年がうるう年かどうかを判定するプログラムを作りたい。
(x × y) ピクセルの画像がある。 これを、(w × h) ピクセルの画面に フィットするように表示したい。 幅と高さ (x', y') の値を計算せよ。
# リストの最大値を求める a = [-3, 8, 19, -4] maxi = 0 i = 0 while i < len(a):??? ...print(f"max index = {maxi}") print(f"max value = {a[maxi]}")
なぜ最大値そのものの値ではなく、maxi
を求める必要があるのか?
こうしておくと、以下のようなことが可能になるからである:
# 得点がもっとも高い学生の番号を表示する student = [1234, 3456, 7890, 1111] a = [-3, 8, 19, -4] maxi = 0 i = 0 while i < len(a):??? ...print(f"max index = {maxi}") print(f"max value = {a[maxi]}") print(f"best student = {student[maxi]}")
有名な格言:
# 加減算のみを使って p×q を計算する。 def multiple(p, q): a = 0 while 0 < q: # q回、p を足す。 a = a + p q = q - 1 return aここで「掛け算ではなく、割り算を計算するプログラムを書け」と言われたらどうするだろうか。 「掛け算と割り算は逆だから、逆にすりゃいいだろう」と思って、 単純に
+
を -
演算子にするだけでは動かない:
# 加減算のみを使って p÷q を計算する。
def divide(p, q):
a = 0
while 0 < q:
a = a - p
q = q + 1
return a
これは、考えてみれば当然である。
上の関数は divide
と名前がついている
(し、コメントにも ÷ と書いてある) が、本当に割り算をしているわけではない。
割り算をさせるには、見よう見真似でプログラムを「逆」にするだけではだめで、
実際に割り算をさせる手順を自分で考えて書かないとだめなのである。
しかし表面的な置換を「プログラミング」と勘違いしている人は時々いる。
プログラミングは、ファンタジーに出てくる魔法ではない。
print("foo)
… エラー!
print{"foo"}
… エラー!
print(f”x={x}")
… エラー!
print("x={x}")
… エラーじゃないけど変な動作
ここで格言をもう一度:
以下のようなループを考える:
# 0から9まで表示する。
i = 0
while i < 10:
print(i)
i = i + 1
これと同じ処理は、条件式 True
と break
文を使って、
以下のように書くこともできる:
i = 0 while True: # つねに真 print(i) if i == 10: break # i==10ならば抜ける i = i + 1
break
文を実行すると、
一番近い while
文から抜ける。
以下のようにすると出力結果はどう変わるか予想せよ。 実際に実行し、結果を確認せよ。
i = 0 while True: # つねに真 print(i) i = i + 1 if i == 10: break # i==10ならば抜ける
ふたたび同じループを考える:
# 0から9まで表示する。
i = 0
while i < 10:
print(i)
i = i + 1
上のようなループは、for
文を使うとより簡潔に書ける:
# 0から9まで表示する。
for i in range(10):
print(i)
for 変数名 in range(繰り返し数): 繰り返す文 ...
このとき、変数名 の値は
0
〜 (繰り返し数 - 1)
まで変化する。
for n in range(10): if (n % 2) == 0: print(f"{n}は偶数") else: print(f"{n}は奇数")
for
文の中に if
文などを書くこともできる。
for i in range(9): for j in range(9): x = i+1 y = j+1 print(f"{x} * {y} = {x*y}")
for
文を二重にすると、
外側のfor
文が一回まわるごとに
内側のfor
文がすべて実行される。
a = [5, 9, 4, 0] for i in range(len(a)): print(f"{i}番目の要素は {a[i]}")
range()
中は決まった数でなくてもよい。
len(a)
(リスト a
の長さ) を入れることで、
リストの全要素を表示できる。
Python における文字列 (string) とは、 文字のリストである。
変数名 = "文字列"
… 文字列を変数に代入する。
変数名[i]
… 文字列中の i番目の文字をとりだす。
文字列 + 文字列
… 2つの文字列を連結する。
len(文字列)
… 文字列の長さ (文字数) を計算する。
文字列 == 文字列
または 文字列 != 文字列
,
… 2つの文字列が等しい (等しくない) かどうかを判定する。
s = "おうさまのみみはろばのみみ" print(s[8]) # 「ろ」が表示される print(len(s)) # 13
リストと同じように、文字列も最初の文字は「0文字目」です。
a = "お"
for i in range(4):
a = a + "よ"
print(a) # およよよよ
文字列はいくらでも + 記号で連結できる。
print("よろ" + "よろ") # 「よろよろ」 print("よろ" - "よろ") # エラー!
文字列は +
記号で連結できるが、引くことはできない。
a = "東工大"
a[1] = "京" # エラー!
リストとは違って、Python では文字列の要素は変更できない。
password = input("password:") if password == "sesami": print("Correct!") else: print("Wrong!")
数値と同じように、文字列に対しても
==
および !=
を使った条件式が使える。
name = ""
なお、input()
関数で何も入力せずにただ Enter を押すと、
空の文字列が返される。
以下のプログラムを実行すると、次の図形が表示される。
# 三角形を表示する for i in range(5): # iは0〜4まで変化する。 s = "" # 空の文字列を準備する。 for j in range(i+1): # i+1回だけ繰り返す。 s = s + "O" # 文字列を延長する。 print(s)
$ python triangle.py O OO OOO OOOO OOOOO
このプログラムを改造して、
以下のような図形が表示されるプログラムを書け。
(行頭の部分は空白文字 " "
を入れること)
OOOOO OOOO OOO OO O
リストの中に文字列を入れることもできる。
names = ["睦月", "如月", "弥生", "卯月", "皐月", "水無月", "文月", "葉月", "長月", "神無月", "霜月", "師走"] for m in range(12): print(f"{m+1}月は{names[m]}")
前回の投票集計プログラムを改良し、番号でなく 候補者の名前を入力して投票できるようにしたい。 (ただ Enter のみが押されたらループを抜けるものとする。) 以下のプログラム vote3.py を完成させよ。
このプログラムを実行すると、以下のように動作する:
$ python vote3.py name:trump name:kim name:abe name:kim name: (Enter のみを押す) abe: 1 trump: 1 kim: 2
なお、不正な文字列 (候補者のどれでもなく、空文字でもない文字列) が 入力される可能性は考えなくてよい。
# 候補者の名前 cands = ["abe", "trump", "kim"] votes = [0, 0, 0] while True: # 候補者の名前を入力する。 name = input("name:") # name を候補者の名前と比較し、一致した候補者の票を増やす。??? ...# 3人の得票数を表示する。 for i in range(3): print(f"{cands[i]}: {votes[i]}")
Python の変数に格納されるデータは、 実はいくつかの「型 (type)」に分類されている:
3
, -15.7
など。
"abc"
など。
[4, 6, 4, 9]
など。["月", "火", "水", "木", "金", "土", "日"]
[ [9,6,3], [8,5,2], [7,4,1] ]
True
と
False
の2種類の値しかない。)
+
演算子の意味は、計算対象のデータ型によって異なる。
print(123+456) # 整数 + 整数: 579 print("123"+"456") # 文字列 + 文字列: "123456" print(123+"456") # 整数 + 文字列: エラー!
型が異なるデータの計算は意味をなさないので、ふつうはエラーが発生する。
"abc" - 5
… エラー!
[3,1,4] + "moo"
… エラー!
int(文字列)
… 文字列を整数として解釈する。
ord(文字列)
… 1文字の文字コード (Unicode) を整数として返す。
a = 123 # a は整数の 123 b = int("123") # b は整数の 123 print(a+b) # 整数+整数: 246
print(ord("A")) # "A"の文字コード: 65 print(ord("あ")) # 「あ」の文字コード: 12354
s = input("string:") for i in range(len(s)): # i は 0〜(文字数-1) まで変化する。 print(ord(s[i])) # i番目の文字コードを表示。
上の例3. のプログラムを実行し「日」「本」の各文字コードを調べよ。
本来、Pythonのinput
関数は入力された 文字列 (string) を返す。
s = input("string:") # s は文字列型
print(s)
ここに int()
関数を適用することで、
文字列を整数型として利用できる。
s = input("number:")
x = int(s) # x は文字列型
print(x)
str(数値)
… 整数を文字列として表す。int()
の逆。
chr(数値)
… 整数で表される文字コードの文字を返す。ord()
の逆。
a = 123 # a は整数の 123 b = str(a) # b は文字列の "123" print(b+"0") # 文字列+文字列: 1230
a = 9829 b = chr(a) # b は Unicode 9829番 で表される文字 print("I"+b+"NY") # I♥NY
chr()
関数に与える文字コードは
Unicode で定義されている。
for i in range(26): # 26回繰り返す。 print(chr(65+i)) # (65+i) で表されるUnicodeの文字を表示する。
このプログラムを実行すると、A から Z までの文字が表示される。
まとめると、以下のような関係がなりたつ:
文字 → 数値 | 数値 → 文字 | |
---|---|---|
文字列 | int(x) | str(x) |
文字 | chr(x) | ord(x) |
入力された文字列の中から英小文字だけを取り出して表示するプログラム
loweronly.py
を書け。
このプログラムを実行すると、次のように動作する:
$ python loweronly.py string:ABCdef def $ python loweronly.py string:123xyzFooBaa xyzooaa
英小文字の文字コードは、 このページ で調べることができる。
# 入力された文字列のうち、英小文字だけを表示する。 s = input("string:") t = "" for i in range(len(s)): c = ord(s[i]) # i番目の文字の文字コードをとりだす。 # 英小文字であれば、変数 t の末尾に加える。??? ...# tの文字列を表示。 print(t)
f"〜"
と "〜"
の違い
じつは、print
関数の機能は
print(文字列) # 文字列を表示する。
などの書き方は、以下のようにもできる:print("hello") print(f"x={x}")
s = "hello" # s は文字列型 print(s) # s の内容を表示 t = f"x={x}" # t は文字列型 print(t) # t の内容を表示
さらに、
f"x={x}"
は、
文字列の連結と str(x)
関数を
組み合わせたものと同じである:
t = "x=" + str(x)
vote3.py
」を
T2SCHOLA から提出せよ。
# 候補者の名前 cands = ["abe", "trump", "kim"] votes = [0, 0, 0] while True: # 候補者の名前を入力する。 name = input("name:") # name を候補者の名前と比較し、一致した候補者の票を増やす。??? ...# 3人の得票数を表示する。 for i in range(3): print(f"{cands[i]}: {votes[i]}")
name
に入っている文字列が何番目の候補者名と等しいか?
を求める必要がある。
この「候補者番号」を入れる変数をたとえば found
としよう。
すると、この部分はこんなふうに書ける:
found = -1
for i in range(3):
# i番目の候補者名と name が等しければ、found に i を代入する。
...
name
の内容が空文字列 ""
になる。
この場合はどうすればよいのか? を考えよう。