コンピュータサイエンス第一 第5週

  1. 先週の復習
  2. 条件式 True と break文
  3. For文
  4. 文字列
  5. データの「型」について
  6. 本日の課題

雑談

ゲームジャム (Ludum Dare 45) に参加しました。

ゲームジャム (game jam) とは何か?

Ludum Dare 45

0. 先週の復習

0.1. 前回までのあらすじ

練習問題.

西暦 y 年がうるう年かどうかを判定するプログラムを作りたい。

グレゴリオ暦: “4年に1度うるう年があるが、100年に1度はない、しかし400年に1度はうるう年がある”
  1. 「変数 y が 4 で割り切れる」を表す条件式を Python で書け。
  2. 「変数 y が 4 で割り切れるが、100 では割り切れない」を表す条件式を書け。
  3. 「変数 y が 4 で割り切れるが、100 では割り切れない、あるいは 400 で割り切れる」を表す条件式を書け。
練習問題.

(x × y) ピクセルの画像がある。 これを、(w × h) ピクセルの画面に フィットするように表示したい。 幅と高さ (x', y') の値を計算せよ。

x y w h 横フィット x y w h 縦フィット
  1. 横フィットの場合、x', y' を計算する式を書け。
  2. 縦フィットの場合、x', y' を計算する式を書け。
  3. x, y, w, h の値が与えられたとき、 この画像が横フィットになるような条件式を書け。

前回の宿題について・補足

maxi.py
# リストの最大値を求める
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 を求める必要があるのか? こうしておくと、以下のようなことが可能になるからである:

best_student.py
# 得点がもっとも高い学生の番号を表示する
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]}")

1. 条件式 True と break文

以下のようなループを考える:

# 0から9まで表示する。
i = 0
while i < 10:
    print(i)
    i = i + 1

これと同じ処理は、条件式 Truebreak文を使って、 以下のように書くこともできる:

i = 0
while True:  # つねに真
    print(i)
    if i == 10:
        break  # i==10ならば抜ける
    i = i + 1

break文を実行すると、 一番近い while文から抜ける。

演習 5-1.
以下のようにすると出力結果はどう変わるか予想せよ。 実際に実行し、結果を確認せよ。
i = 0
while True:  # つねに真
    print(i)
    i = i + 1
    if i == 10:
        break  # i==10ならば抜ける

2. For文

ふたたび同じループを考える:

# 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) まで変化する。

例1: ループ中で条件分岐
for n in range(10):
    if (n % 2) == 0:
        print(f"{n}は偶数")
    else:
        print(f"{n}は奇数")

for文の中に if文などを書くこともできる。

例2: 九九の表示
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文がすべて実行される。

例3: リストでfor文
a = [5, 9, 4, 0]
for i in range(len(a)):
    print(f"{i}番目の要素は {a[i]}")

range() 中は決まった数でなくてもよい。 len(a) (リスト a の長さ) を入れることで、 リストの全要素を表示できる。

3. 文字列

Python における文字列 (string) とは、 文字のリストである。

復習: コンピュータでは文字はどうやって表現されていたか?

構文:
例1:
s = "おうさまのみみはろばのみみ"
print(s[8])    # 「ろ」が表示される
print(len(s))  # 13
例2:
a = "お"
for i in range(4):
    a = a + "よ"
print(a)  # およよよよ

文字列はいくらでも + 記号で連結できる。

例3:
print("よろ" + "よろ")  # 「よろよろ」
print("よろ" - "よろ")  # エラー!

文字列は + 記号で連結できるが、引くことはできない。

例4:
a = "東工大"
a[1] = "京"  # エラー!

リストとは違って、Python では文字列の要素は変更できない

例5:
password = input("password?")
if password == "sesami":
    print("Correct!")
else:
    print("Wrong!")

数値と同じように、文字列に対しても == および != を使った条件式が使える。

リストと同じように文字列も、最初の文字は「0文字目」です。

演習 5-2.

以下のプログラムを実行すると、次の図形が表示される。

triangle.py:
# 三角形を表示する
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

3.1. リスト + 文字列

リストの中に文字列を入れることもできる。

names = ["睦月", "如月", "弥生", "卯月", "皐月", "水無月",
         "文月", "葉月", "長月", "神無月", "霜月", "師走"]
for m in range(12):
    print(f"{m+1}月は{names[m]}")
演習 5-3.

前回の投票集計プログラムを改良し、番号でなく 候補者の名前を入力して投票できるようにしたい。 ("end" が入力されたらループを抜けるものとする。) 以下のプログラム vote3.py を完成させよ。

vote3.py
# 候補者の名前
cands = ["abe", "trump", "kim"]
votes = [0, 0, 0]
while True:
    # 候補者の名前を入力する。
    name = input("name?")
    # name を候補者の名前と比較し、一致した候補者の票を増やす。
??? ...
# 3人の得票数を表示する。 for i in range(3): print(cands[i], ":", votes[i])

4. データの「型」について

Python の変数に格納されるデータは、 実はいくつかの「 (type)」に分類されている:

+ 演算子の意味は、計算対象のデータ型によって異なる。

print(123+456)      # 整数 + 整数: 579
print("123"+"456")  # 文字列 + 文字列: "123456"
print(123+"456")    # 整数 + 文字列: エラー!

型が異なるデータの計算は意味をなさないので、ふつうはエラーが発生する。

4.1. 文字(列)型 → 整数型への変換

構文:
例1:
a = 123         # a は整数の 123
b = int("123")  # b は整数の 123
print(a+b)      # 整数+整数: 246
例2:
print(ord("A"))   # "A"の文字コード: 65
print(ord("あ"))  # 「あ」の文字コード: 12354
例3:
s = input("string?")
for i in range(len(s)):  # i は 0〜(文字数-1) まで変化する。
    print(ord(s[i]))     # i番目の文字コードを表示。
練習問題.

上の例3. のプログラムを実行し「日」「本」の各文字コードを調べよ。

input関数の動き

本来、Pythonのinput関数は入力された文字列を返す。

s = input("string?")  # s は文字列型
print(s)

ここに int() 関数を適用することで、 文字列を整数型として利用できる。

s = input("number?")
x = int(s)  # x は文字列型
print(x)

4.2. 整数型 → 文字(列)型への変換

構文:
例1:
a = 123        # a は整数の 123
b = str(a)     # b は文字列の "123"
print(b+"0")   # 文字列+文字列: 1230
例2:
a = 9829
b = chr(a)         # b は Unicode 9829番 で表される文字
print("I"+b+"NY")  # I♥NY

chr()関数に与える文字コードは Unicode で定義されている。

例3:
for i in range(26):   # 26回繰り返す。
    print(chr(65+i))  # (65+i) で表されるUnicodeの文字を表示する。

このプログラムを実行すると、A から Z までの文字が表示される。

まとめると、以下のような関係がなりたつ:

文字 → 数値数値 → 文字
文字列int(x)str(x)
文字chr(x)ord(x)

4.3. print関数における 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)

5. 本日の課題

小課題 3. 英小文字だけを表示するプログラム lowercase.py
lowercase.py
# 入力された文字列のうち、英小文字だけを表示する。
s = input("string?")
t = ""
for i in range(len(s)):
    c = ord(s[i])  # i番目の文字の文字コードをとりだす。
    # 英小文字であれば、変数 t の末尾に加える。
??? ...
# tの文字列を表示。 print(t)

このプログラムを実行すると、次のように動作する:

$ python lowercase.py
string?ABCdef
def
$ python lowercase.py
string?123xyzFooBaa
xyzooaa

Yusuke Shinyama