コンピュータ演習II 第08回 基礎トレーニング(for とリストの復習)¶
この回では、新しいことは学びません。第05回(リスト)と第06回(for 文)で学んだことを、たくさんの小さな問題で何度も練習して、確実に身につける ための回です。読んで分かることと自分で書けることの間には大きな差があります。この回は、その差を埋めるために とにかく自分の手でコードを書く 時間です。
進め方は次のとおりです。
- 問題は Colab で解きます。各問題の 入力例 をそのまま自分のセルに書き、続けて自分でコードを書いて実行してください。
- 各問題に 期待される出力 を載せています。自分のプログラムの出力とこれを見くらべて、合っているかを自分で確かめてください(出力が一致すれば正解です)。
- わからなくなったら、第05回と第06回の教材を見返してかまいません。答えを写すのではなく、書き方を思い出して自分で書く ことが大切です。
- 「読む」問題は、実行する前に出力を予想し、そのあと実際に実行して答え合わせをしてください。
同じ種類の問題を、値を変えて何度も出しています。くり返し解いて、手が自然に動くようになることを目指してください。
重要な注意事項¶
Google Colab ではコードを生成できる機能がありますが、この演習では使用しないでください。 気持ちはわかります。 しかしこの授業の目的は、皆様がプログラムを書くだけでなく読めるようになることです。 生成AI でコードを書くことはできます。 しかし生成AI が書いたコードを理解することができないと、生成AI を活用することは非現実的です。
例えば、うまく動かないプログラムがあって、本来は数文字直せばいいところをいちいち生成AI を使う、などといった状況は馬鹿らしいですよね。 以下のようなプログラムを見てみましょう。
# 1次関数:f(x) = a * x + b
f = 0 # 関数f
x = 0 # 変数x
a = 3 # 傾きa
b = 1 # 切片b
# 上の直線を実際に表示します
import matplotlib.pyplot as plt
xs = []
fs = []
for x in range(0, 6):
xs.append(x)
fs.append(a * x + b)
f = a * x + b
print(f"f({x}) = {f}", end=", ")
plt.grid()
plt.plot(xs, fs)
plt.xlim(0, 5)
plt.ylim(0, 20)
plt.show()
これは 1 次関数 f = ax + b の直線を表示する簡単なプログラムです。
a は傾き、b は切片で、x を 0 から 5 まで変えたときの f を計算しています。
ここで、あなたは傾きを3 から5 に変えた直線を見たくなったとします。
プログラムを読める人なら、a = 3 の行を a = 5 に書き換えればいいことがわかります。
一方生成AI を使う人はたった1 文字の、しかもとても初歩的な修正のために、生成AI に「傾きを 3 から 5 に変えたプログラムを書いて」と頼むことになります。
生成AI は確かに便利ですが、これは明らかに時間と資源の無駄です。
自分で読めないコードを生成AI に書かせることは、結局自分の首を絞めることになります。
これからは生成AI をうまく使う能力が求められる時代となることは確実です。 プログラムも生成AI が書く時代になるでしょう。 しかし、生成AI が書いたコードを理解できないと、生成AI を100% 活用することはできません。
さらに言うと、理解できない人が生成AI で作ったコードは、頑健性や信頼性、汎用性が著しく低くなり、結局広く一般には公開することができないでしょう。 これからの時代、IT 業界で生きていく人材は、ここが一つの分岐点になると思います。
このような背景もありますので、この授業では必ず自分でプログラムを書いて、読めるようになることを目指してください。
1. ウォームアップ: range と for¶
問題 1: range の範囲を読む(その1)¶
次のコードは何を出力しますか。予想してから、Colab で実行して確かめてください。繰り返しの回数と、最後に表示される i にも注目してください。
次のコード:
for i in range(1, 5):
print(i)
実行結果:
1
2
3
4
問題 3: range の範囲を読む(その3)¶
次のコードの出力を予想してください。range の終了の値そのものは含まれないことに注意してください。
次のコード:
for i in range(3, 8):
print(i)
実行結果:
3
4
5
6
7
問題 4: 同じ文字をくり返す¶
for 文を使って、こんにちは という文字を 5 回表示してください。
期待される出力:
こんにちは
こんにちは
こんにちは
こんにちは
こんにちは
ヒント(フローチャート):
問題 5: 1 から 10 まで¶
for 文を使って、1 から 10 までの整数を 1 つずつ表示してください。
期待される出力:
1
2
3
4
5
6
7
8
9
10
ヒント(フローチャート):
問題 7: 5 から 15 まで¶
for 文を使って、5 から 15 までの整数を 1 つずつ表示してください。15 も含めます。
期待される出力:
5
6
7
8
9
10
11
12
13
14
15
ヒント(フローチャート):
2. リストの基礎¶
問題 8: 要素を取り出す¶
first と third という 2 つの変数を定義し、それぞれに 0 を代入してください。その後、リスト prices の 先頭の要素 を first に、インデックス 2 の要素 を third に入れて、first と third を表示してください。
入力例:
prices = [4, 8, 15, 16, 23]
期待される出力:
4
15
問題 9: 長さを求める(その1)¶
length という変数を定義し、0 を代入してください。その後、len で求めたリスト prices の要素数を length に入れて、length を表示してください。
入力例:
prices = [4, 8, 15, 16, 23]
期待される出力:
5
問題 10: 長さを求める(その2)¶
同じように、length という変数を定義し、0 を代入してください。その後、リスト data の要素数を length に入れて、length を表示してください。
入力例:
data = [3, 1, 4, 1, 5, 9, 2]
期待される出力:
7
問題 11: 最後の要素(その1)¶
last という変数を定義し、0 を代入してください。その後、リスト prices の 最後の要素 を last に入れて、last を表示してください。インデックスの数字を直接書かず、prices[len(prices)-1] の形で求めてください。
入力例:
prices = [4, 8, 15, 16, 23]
期待される出力:
23
問題 12: 最後の要素(その2)¶
同じように、last という変数を定義し、0 を代入してください。その後、リスト temps の 最後の要素 を last に入れて、last を表示してください。temps[len(temps)-1] の形で求めてください。
入力例:
temps = [12, 15, 9, 20, 8]
期待される出力:
8
問題 13: 要素の上書き¶
リスト prices の インデックス 1 の要素 を 100 に上書きし、そのあと prices 全体を表示してください。
入力例:
prices = [4, 8, 15, 16, 23]
期待される出力:
[4, 100, 15, 16, 23]
問題 14: append で作る(その1)¶
values という空のリストが用意してあります。この values に append で 10、20、30 を順に追加してください。その後、values 全体と len(values) を表示してください。
入力例:
values = []
期待される出力:
[10, 20, 30]
3
ヒント(フローチャート):
問題 15: append で作る(その2)¶
同じように、用意された空のリスト values に、append で 7、14、21、28 を順に追加してください。その後、values 全体と len(values) を表示してください。
入力例:
values = []
期待される出力:
[7, 14, 21, 28]
4
ヒント(フローチャート):
問題 16: 間接参照(その1)¶
numbers[numbers[0]] は、まず内側の numbers[0] を計算し、その値をインデックスとして使ってもう一度リストを参照します。result という変数を定義し、0 を代入してください。その後、次の numbers について numbers[numbers[0]] の結果を result に入れて、result を表示してください。
入力例:
numbers = [3, 10, 20, 50, 80]
期待される出力:
50
問題 17: 間接参照(その2)¶
同じように、result という変数を定義し、0 を代入してください。その後、次の numbers について numbers[numbers[0]] の結果を result に入れて、result を表示してください。
入力例:
numbers = [2, 7, 1, 9]
期待される出力:
1
3. for とリストの反復¶
問題 18: 合計を求める(その1)¶
total という変数を定義し、0 を代入してください。その後、for 文で scores の全要素を 1 つずつ total に足していき、最後に total を表示してください。range(0, len(scores)) の形でくり返します。
入力例:
scores = [10, 30, 25, 40, 15]
期待される出力:
120
ヒント(フローチャート):
問題 19: 合計を求める(その2)¶
同じ「合計の蓄積」を、次の data でも練習します。total という変数を定義し、0 を代入してください。その後、for 文で data の全要素を total に足していき、total を表示してください。
入力例:
data = [5, 5, 5, 5, 5]
期待される出力:
25
ヒント(フローチャート):
問題 20: 条件つきカウント(その1)¶
count という変数を定義し、0 を代入してください。その後、for 文と if 文で scores を調べ、80 以上の要素が見つかるたびに count を 1 増やして、最後に count を表示してください。
入力例:
scores = [90, 98, 85, 72, 63]
期待される出力:
3
ヒント(フローチャート):
問題 21: 条件つきカウント(その2)¶
count という変数を定義し、0 を代入してください。その後、for 文と if 文で data を調べ、偶数の要素(2 で割った余りが 0)が見つかるたびに count を 1 増やして、count を表示してください。
入力例:
data = [6, 1, 2, 5, 0, 8]
期待される出力:
4
ヒント(フローチャート):
問題 22: 最大値を求める(その1)¶
max_value という変数を定義し、先頭の要素 data[0] を代入してください。その後、for 文で残りの要素を調べ、max_value より大きい要素が見つかったら max_value を更新して、最後に max_value を表示してください。max は使いません。
入力例:
data = [2, 3, 6, 4, 1, 8, 9]
期待される出力:
9
ヒント(フローチャート):
問題 23: 最大値を求める(その2)¶
同じやり方で、次の data の最大値を求めます。max_value という変数を定義し、先頭の要素 data[0] を代入してください。その後、より大きい要素が見つかったら max_value を更新して、max_value を表示してください。
入力例:
data = [15, 3, 22, 8, 19]
期待される出力:
22
ヒント(フローチャート):
問題 24: 最小値を求める(その1)¶
min_value という変数を定義し、先頭の要素 data[0] を代入してください。その後、for 文で残りの要素を調べ、min_value より小さい要素が見つかったら min_value を更新して、min_value を表示してください。min は使いません(不等号の向きが最大値のときと逆になります)。
入力例:
data = [2, 3, 6, 4, 1, 8, 9]
期待される出力:
1
ヒント(フローチャート):
問題 25: 最小値を求める(その2)¶
同じやり方で、次の data の最小値を求めます。min_value という変数を定義し、先頭の要素 data[0] を代入してください。その後、より小さい要素が見つかったら min_value を更新して、min_value を表示してください。
入力例:
data = [15, 3, 22, 8, 19]
期待される出力:
3
ヒント(フローチャート):
4. 複合問題¶
問題 26: 奇数だけの合計¶
total という変数を定義し、0 を代入してください。その後、for 文と if 文で data を調べ、奇数の要素(2 で割った余りが 1)だけを total に足していって、total を表示してください。
入力例:
data = [6, 1, 2, 5, 0, 7]
期待される出力:
13
ヒント(フローチャート):
問題 27: 平均を求める¶
まず total という変数を定義し、0 を代入してください。その後、for 文で scores の合計を total に求めてください。最後に、その合計を len(scores) で割った平均を average に入れて、average を表示してください。
入力例:
scores = [10, 30, 25, 40, 15]
期待される出力:
24.0
ヒント(フローチャート):
問題 28: ある値以上の合計¶
total という変数を定義し、0 を代入してください。その後、for 文と if 文で data を調べ、10 以上の要素だけを total に足していって、total を表示してください。
入力例:
data = [12, 5, 28, 9, 17]
期待される出力:
57
ヒント(フローチャート):
5. 学籍番号のリストで練習¶
問題 29: 学籍番号の各桁の合計¶
自分の学籍番号後半 5 桁から作るリスト digits を使います。total という変数を定義し、0 を代入してください。その後、for 文で digits の全要素を total に足していき、total を表示してください。入力例は sid が 61250 のときの値です。自分の sid に変えると答えも変わります。
sidが61250ならdigitsは[6, 1, 2, 5, 0]です。
入力例:
sid = 61250 # ← 自分の学籍番号後半 5 桁に書き換える
digits = [sid // 10000 % 10, sid // 1000 % 10, sid // 100 % 10, sid // 10 % 10, sid % 10]
期待される出力:
14
ヒント(フローチャート):
問題 30: 合計と最大値を 1 回のループで求める¶
この回でいちばん中身のある問題です。まず total に 0 を、max_value に先頭の要素 digits[0] を代入してください。その後、for 文を 1 つだけ 使って、total に digits の合計を足していき、同時に、より大きい要素が見つかったら max_value を更新してください。最後に、total、max_value の順に表示してください(2 行になります)。
入力例:
sid = 61250 # ← 自分の学籍番号後半 5 桁に書き換える
digits = [sid // 10000 % 10, sid // 1000 % 10, sid // 100 % 10, sid // 10 % 10, sid % 10]
期待される出力:
14
6
ヒント(フローチャート):
発展問題¶
問題 31: 最大値の位置¶
まず max_value に先頭の要素 data[0] を、max_index に 0 を代入してください。その後、for 文で max_value より大きい要素が見つかったら、max_value を更新すると同時に、そのときのインデックス i を max_index に覚えておいてください。最後に max_index を表示してください。インデックスは 0 から数えます。
入力例:
data = [15, 3, 22, 8, 19]
期待される出力:
2
ヒント(フローチャート):
問題 32: 最大値と最小値の差¶
まず max_value と min_value に、どちらも先頭の要素 data[0] を代入してください。その後、for 文で最大値を max_value に、最小値を min_value に求めてください。最後に、max_value から min_value を引いた差を difference に入れて、difference を表示してください。
入力例:
data = [15, 3, 22, 8, 19]
期待される出力:
19
ヒント(フローチャート):
まとめ¶
この回では、第05回と第06回で学んだ リスト と for 文 を、たくさんの問題でくり返し練習しました。特に大切なのは、次の「for 文でよく使うパターン」です。どれも「変数を用意しておき、繰り返しのたびに少しずつ更新する」という同じ形です。
- 合計:
total = 0から始めて、total = total + data[i]を繰り返す。 - カウント:
count = 0から始めて、条件に合うたびにcount = count + 1。 - 最大値と最小値: 先頭を暫定値にして、より大きい(小さい)要素が見つかったら更新する。
- リストの全要素をまわす:
for i in range(0, len(data)):が基本の形。lenを使うと、長さが変わっても動く。
これらのパターンは、この先の 2 重ループや整列、探索でもずっと使い続けます。この回で「見れば分かる」から「自分で書ける」へ進めておくことが、次からの土台になります。