プログラミング入門I
2023.11.27
for 文
短い時間でのテストはタイムプレッシャーがかかるせいか,だいたいエラーの出るプログラムの提出の確率が高くなる傾向にありますが,今回も同様でした.まずは,エラーのないプログラムを出して,部分点の獲得を目指しましょう. 以下は問題のあるプログラムの例です.参考にしてください.
Li = random.randint(0,3)
Sa = random.randint(0,3)
変数名は小文字で始めるというのが,プログラミングにおける常識です.
a = random.randint(0,3) b = random.randint(0,3) |
間違いではないですが,このような変数名はほかの人から見てわかりづらいので,ぼちぼちちゃんとした名前をつける習慣をつけましょう.
print('THe winner: ' ,end='') |
英文をタイプするときによくやる間違いではありますね.
if num1 > num2: print(f'The winner: Liverpool FC') elif num1 < num2: print(f'The winner: Sanfrecce FC') else: print(f'Draw') |
間違った動作をするわけではありませんが,print 関数の引数の中に変数の値などが含まれていないので,f 文字列にする必要は無いですよね.
if num1 > num2: print(f'Liverpool {num1} - {num2} Sanfrecce') print('The winner: Liverpool FC') elif num1 < num2: print(f'Liverpool {num1} - {num2} Sanfrecce') print('The winner: Sanfrecce Hiroshima FC') else: print(f'Liverpool {num1} - {num2} Sanfrecce') print('Draw') |
前回のコメントにも書きましたが,インデントが揃っていればいいとは言え,1文字分では識別が難しく,パッと見に構成を把握しづらいところがありますので,ちゃんと標準のTABで4文字分確保しましょう.
if x>y: print(f'Liverpool {x}-{y} Sanfrecce,\nThe winner: Liverpool FC') if x<y: print(f'Liverpool {x}-{y} Sanfrecce,\nThe winner: Sanfrecce Hiroshima FC') if x==y: print(f'Liverpool {x}- {y} Sanfrecce Draw') |
どれか一つに帰結する条件分岐のときに if の連発はよくないとこれまで何度か説明していますね.また,分岐に関係ないスコアの部分は if 文のスイートの中に入れる必要は無いですね.
S=random.randint(1,3) R=random.randint(1,3) print(f'Liverpool Gool {R} - {S} Sanfrecce') |
変数名の大文字については前述していますが,実行例の例文に無いものを入れています.しかも,綴りが間違っているし.
print(f'Liverpool {x} - {y} Sanfrecce ' , end = '') |
なぜ,改行しないの?
print(f'Liverpool (num1) - (num2) Sanfrecce') |
ちょっとした間違いといえばそうですが,f 文字列で変数の値を参照するときは中カッコ { } です.
今回は残念ながら大きな問題のあるプログラムが提出されてしまいました.自分でプログラムを実行してみて,エラーや無限ループであれば気づくはずですので,ちゃんとしたプログラムに修正してから提出してください.
実行時エラー: b2314 (日本語全角スペース混入) b2252 (:抜け,というか書きかけ)
無限ループ: b2322
出力時番号間違い: b2340 b2258
以下は例によって問題のあるプログラムの例です.参考にしてください.
b = 2 if a % b == 0: print(f'{a} is not a prime number.') while a % b != 0: b += 1 if a != b: if a % b == 0: print(f'{a} is not a prime number.') else: print(f'{a} is a prime number.') else: print('') |
今回いくつか見られた形式に上のようなものがあります.最初に if で偶数を排除していますが,特にそのような処理は無くてもいいですし,無い方が単純なプログラムになるので,見やすくなります.
while num1 > 1: if num1 % div == 0: print(f'{num1} is not a prime number.') break else: div += 1 if num1 == div: print(f'{num1} is a prime number.') break else: print() |
上のようなものが結構たくさん出されたのですが,最初に紹介したものも含めて,反復処理の中に最終的な文字列の表示をさせる print 関数を入れることは推奨しません.必ず break で抜けるということですが,print 関数をループの中に入れる必然性はありません.
for n in range(2, x-1): if x % n == 0: break else: a = f'{x} is a prime number.' |
while 文の単元で,なぜ for 文?
num = random.randint(10, 20) a = 1 if num < 2 : a = 0 else: b = 2 while b * b <= num : if num % b == 0 : a = 0 break b += 1 |
変数 num は10以上の数になるはずですが,なぜ num < 2 の判定が必要なんでしょうかね?
def is_prime(num): if num < 2: return False for i in range(2, int(num**0.5) + 1): if num % i == 0: return False return True n=random.randint(10,20) if is_prime(n): print(f'{n} is a prime number') else: print(f'{n} is not a prime number') |
別に良いっちゃ良いんですが,この程度のプログラムでなぜ関数を定義して使用するのでしょうか?
さて,以下は絶対にやっちゃダメ!なものです.というのは,今回は 10 から 20 までの数を乱数で発生させましたが,発生させる乱数が100までの整数とか,さらに言えば1億までの整数とかになったときに,以下のような書き方は可能でしょうか?プログラミングは人間がさぼるためにあるので,自分で約数を探して処理を書くというのは絶対ダメです.
while i < 1: if m % 2 == 0 or m % 3 == 0: print(f'{m} is not a prime number.', end = '') else: print(f'{m} is a prime number.', end = '') i += 1 |
if num%2==0 or num%3==0 or num%5==0 or num%7==0: print(' is not a prime number.') else: print(' is a prime number.') |
if a == 11 or 13 or 17 or 19: print(f'{a} is a prime number.') else: print(f'{a} is not a prime number.') |
この最後のものはさらにダメダメです.if 文の条件式のところは,必ず真になります.なので,全部素数になりますが,自分で気づきませんでしたかね.
前回は while 文について学習しました.何らかの変数の値が条件式が真の間,指示した処理が実行される,という構成でした.条件式に入る変数は,ループが始まる前に値が定義されていないといけないこと,また,反復して処理するスイートの中に,その変数の増分や変更などが含まれていないと無限ループとなってしまうことに注意してください.
for 文は基本的には繰り返す回数が決まっているときに使用する反復処理です.もちろん変数の値の回数繰り返すとすると,決まった回数ではないように見えますが,それでもその変数分の回数繰り返すということは,あらかじめ決まっていることになります.
教科書にもあるように,for 文は以下のような基本的な構成となります.
for 変数 in 並び式: スイート |
for 文において,繰り返す回数を指定するのには range 関数が使用されます.引数仕様は以下の通りです.
range(n) | 0 以上 n 未満の数値を順番に列挙した数列 |
range(a, b) | a 以上 b 未満の数値を順番に列挙した数列 |
range(a, b, step) | a から b の手前までの数値を step 個おきに列挙した数列 |
range 関数のツボ
最初のうちによく間違えることがあるのですが,range(1, 10) のようにしたときには,変数の値が 1 から 9 まで変わる間反復処理を行うので,1 から 10 までとしたいときには,range(1, 11) としないといけません.ここは要注意です.
自分で作ったプログラムが思ったように動かないときには,変数の値が反復処理によりどのように変わっていくのかを,逐次手作業で確認してみてください.処理の流れに従って変数が変わっていきますが,それが希望した動作になっているのか,メモなどを取りながら値の変化を確認することが,プログラムの間違いを見つける大事な方法です.
今回の演習問題です.
宿題が公開されるのは明日火曜日10:00の予定で,締切りは来週の月曜日12月4日の10:00です.レポート提出システムを使用します.
次回も引き続き教科書のp.102-114(旧版は p.100-111)の範囲を学習しますので,予習をしてきてください.