プログラミング入門I
2024.11.06
if 文 その1
今回の課題の提出においても,形式上の不備も見られました.きちんと決まりを守ってまずは解答用紙を作り上げることから始めてください.また,中身については実に様々なプログラムが出てきており,ちょっと驚きました.それらについては後でまた説明します. 実行時エラー: b2426 (採点対象外) 不要なヘッダ部分の出力: b2458 解答用紙の学生番号と名前の未修正: b2421 解答用紙と実行時出力の学生番号間違い: b2456 学生番号でなくアカウントを記入・出力: b2465 以下は問題のあるプログラムの例です.参考にしてください.
print('\n------------------------\n')
print("#################################")
print("#")
print("# プログラミング入門Ⅰ 宿題 2024,10,28")
print("# 学生番号: s******")
print("# 氏名: 〇〇 〇〇〇")
print("#")
print("#################################")
前回も言ったのですが,解答用紙のこの部分は出力しません.解答用紙を勝手に改ざんしないでください.
import random print('Student number: b2****') print('') print('\n------------------------\n') num1 = random.randint(2,4) min_value = 10**(num1-1) max_value = 10**num1 - 1 random_number = random.randint(min_value, max_value) print(f"Random number: {num1}") print(f"Random number : {random_number}") |
自分のプログラムは,元の解答用紙の print('') と print('--- 中略 ---') の間に書き込んでください.実行時に自分の学生番号がまず表示され,最後にハイフンラインが来るようにしてください.
import random num1=random.randint(2,4) num2=random.randint(10**(num1-1),10**num1-1) print('Student number: s******') print(f'A random number with {num1} digits:{num2}') |
これも同じようなもので,学生番号表示の後に自分のプログラムを書き込んでください.また,元から解答用紙についている print('') も消さないでください.
print(f'A random number with 4 digits: {num4}') |
問題の脚注に書いておいたのですが,やっぱり理解できていない人がいました.この数字の部分は乱数が入りますよね.
A=random.randint(2,4) B=random.randint(10**(A-1),10**A-1) print(f'{B}') |
変数名は小文字で始めてください.プログラミングのお約束です.
Num1 = random.randint(2, 4) Num2 = random.randint(10**(Num1-1), 9999//10**(4-Num1)) |
こちらも同様なのですが,加えてめんどうでややこしい処理を書いています.
a=random.randint(2,4) b=random.randint(10**(a-1),10**a-1) |
a とか b とかのような無意味な変数名の使用はやめましょう.変数の実態にあった名前をつけてください.
反復処理のところで出てくる変数 i などは別です.それはそれで意味のある変数名ですので.
print(f"生成された桁数: {digit_count}") print(f"生成されたランダムな数: {random_number}") |
どのように画面に出力するかは,問題の出力例に示しています.自分で勝手に結果の表示を変えないでください.
num2=random.randint(10**(num1-1),10**(num1)-1) |
後ろのカッコは不要ですね.
num1 = random.randint(2,4) num2 = random.randint(10,10**num1) |
この間違いが何例か出てきました.これでは変数 num1 の値にかかわらず,10 から 10 ** num1 までの範囲の乱数が出てきますので,間違いです.最大値の方もこれでは可能性としては5桁の 10000 が出ることになります.
A random number with 4 digits:97 |
実行結果としてはこんなものになります.
num1 = random.randint(2,4) num2 = random.random() num3 = 10**(num1) num4 = num2*num3 print(f'A random number with {num1} digits:{num4:.0f}') |
今回実にさまざまなパターンが見られましたが,これもその一つです.整数で処理をすればよいだけなのに,なんで実数に持っていきますかね.計算機の内部では2進数で処理をしていますが,小数を2進数で表すのはそれなりに大変なので,処理速度の観点から,プログラミング言語では数値を整数と実数に分けて,整数だけで処理をすれば良いものは整数だけでやります.その方が速いのです.
num = random. randint(2,4) num1= random.randint(10,99)*(10**(num - 2)) print(f'A random number with {num} digits: {num1}') |
2桁の乱数に10の倍数をかけているだけですので,結果は下のように3桁では1の位が0に,4桁では最後が 00 になってしまいますね.
A random number with 3 digits: 770 |
num1=random.randint(2. 4) num2=random.uniform(1.000, 9.999) print(f'A random number with {num1} digits: {num2*10**(num1-1):.0f}') |
こちらも実数を使用しています.別に必要はないんですが.
num=random.randint(1000,9999) print(f'A random number with 4 digits:{num}') |
上のように最初から4桁の乱数しか作らない処理を書いている人が複数人いました.題意を満足していません.
digit_count=random.choice([2,3,4]) min=10 ** (digit_count-1) max=10 ** (digit_count-1) random_number=random.randint(min, max) print('') print(f"桁数:{digit_count}") print(f"乱数:{random_number}") |
桁数:4 乱数:1000 |
いろいろと問題のあるプログラムですが,一番まずいのは変数 min と max の値が同じであることです.なので,100,1000,10000しか出ません.実行すれば自分で気づいたはずですが,実行しませんでしたか?
まだ習っていないリストを使用して random.choice を使用していますね.別に使うのはいいのですが,本来は不規則な並びの候補からどれか選ぶときに威力を発揮するもので,2-4のような連続する整数で使用する意味はほとんどありません.
print(f"A random with {num_digits}digits:{random_number}") |
前回こちらも指摘したのですが,英語は分かち書きの文化ですので,単語の切れ目はスペース(空白文字)で表します.出力時に注意してください.上のものは以下のような表示となり,スペースが抜けています.
A random with 4digits:7018 |
num1 = random.randint( 2,4 ) num2 = random.randint(1000, 9999) num3 = num2*10**( num1 - 4) print(f"A random number with {num1},{num3:.0f} " ) |
こちらも無駄にややこしい処理を使用していますが,それ以外にやはり print の中が本来要求していたものと違っています.
A random number with 4,3240 |
num1= random.randint(1000, 9999) num2=random.randint(1, 4) num3=10**-4 print(f'Random number with {num2} digits: {num1*10**num2*num3:.0f}') |
こちらも不必要にややこしい処理を書いていますが,結局間違っているので,下のように一桁の数が出てきてしまいました.何度か実行して正しく動作することを確認してから提出しましょう.
Random number with 1 digits: 5 |
さて,ここからはやっちゃダメ!な例です.プログラムは簡潔にわかりやすく書くことが求められますが,ちゃんと考えればすっきり書けるものを,とにかく力業でゴリゴリやるのは歓迎しません.以下のものがやっちゃダメ!な理由は,乱数の桁数を変えるとプログラム全体が変わってしまうことです.2桁から10桁までのどれかの桁数の乱数を発生させるとすると,どうなりますか? 100桁までだとどうなりますか?今後はそういうことを意識してプログラミングをしましょう.
num=random.randint(2,4) x=num-1 y=num-2 z=num-3>0 a=random.randint(1,9)*10**x b=random.randint(1,9)*10**y c=random.randint(1,9)*10**z d=random.randint(1,9) print(f'A random number with {num} digits:{a+b+c+d}') |
if num1==2: num2=random.randint(10,99) if num1==3: num2=random.randint(100,999) if num1==4: num2=random.randint(1000,9999) |
num0=random.randint(2,4) num1=random.randint(10,99) num2=random.randint(100,999) num3=random.randint(1000,9999) if num0==2: print(f'A random number with 2 digits: {num1}') if num0==3: print(f'A random number with 3 digits: {num2}') if num0==4: print(f'A random number with 4 digits: {num3}') |
上の2つは本日から学習するまだ習っていない if 文を使っていますが,この授業の課題では,基本的には習っていない関数やメソッドを使用することはありません.予習もいいですが,そういうことを必要としていないのに使うのは無駄です.また,プログラムの動作において時間がかかるのは条件分岐(if 文など)なので,なくて済むのなら無いままで行きましょう.
んで,前回ちょっと紹介した困ったプログラムが以下のようなものです.
import random print('Student number: s******') import random num_digits = random.choice([2, 3, 4]) def generate_random_number(num_digits): lower_bound = 10**(num_digits - 1) upper_bound = 10**num_digits - 1 return random.randint(lower_bound, upper_bound) random_number = generate_random_number(num_digits) print(f"A random number with 4 digits: {random_number}.") |
A random number with 4 digits: 122. |
プログラミング入門IIの後半で学習する自作関数を使っています.どうしてそんなものが必要なんでしょうかね.そして,このような処理をわからないままにコピペする場合の特徴として,もらったソースをそのまま張っつけたりするので,解答用紙の先頭に import random があるのに,もらったソースにあった import random を含めて張り付けています.変ですよね.
さらにこの例で最悪なのは,処理が間違っていることです.実行例を見てみると一目瞭然ですね.
前回は乱数について学習しました.Python にあらかじめ用意してある関数を使用して乱数を発生させることができるようになったので,今後はプログラムの作成においてほぼ毎回使用することになります.整数や実数の乱数を使いこなせるようにしましょう.
関数 | 引数仕様 | 発生する数値 |
---|---|---|
randint() | min, max | min から max の範囲の整数 |
random() | 無し | 0 以上 1 未満の数値 |
randrange() | min, max, step | min から max の範囲の整数で step 刻み |
プログラムの処理の流れは入力された数値や計算結果などにより分岐させて条件ごとの処理を行うことが大半です.そのために処理を条件ごとにわけることを条件分岐と言いますが,そのためにどの言語においても用意されているのが今回取り扱う if 文です.基本的なことは教科書に書いてありますので,それに従って作業していきましょう.
if 文のポイント
単純な if 文 | 条件式が真の場合に処理を行う |
if - else 文 | 条件式が真の場合にある処理を行い,偽の場合に別の処理を行う |
if - elif 文 | 条件式が真の場合にある処理を行い,偽の場合にはさらに別の条件式が真であれば別の処理を行う |
if 文の Tips
例えば変数の値が偶数のときのみ何かの処理をすることを考えてみましょう.その際には,次のような書き方が考えられます.
if num % 2 == 0: Do something |
次に偶数だったらある処理をして,奇数だったら別の処理をすることを考えます.その際に以下のように書くことはお薦めしません.
if num % 2 == 0: Do this if num % 2 == 1: Do that |
プログラムを書いている際にはよくあることですが,ちょっとしたキーの打ち間違いや入力忘れなどでちょっと間違った処理にしてしまったりします.今回は偶数と奇数とどちらの場合も何かの処理を必ず行うので,上のように書いてしまうとどちらも実行しないとか,両方とも実行してしまうという間違いにつながることがあります.
そうならないようにするために,条件分岐の数が何個であろうとも,必ずどれかの処理を実行するという場合には最後に必ず else をつけておいて,何があっても何かを1つだけ実行するという保険をかけておくことが大事です.
if num % 2 == 0: Do this else: Do that |
比較演算子の中の等しいかどうかを判定する記号は == です.ところが,誰でも必ず1回以上はこれを間違えて等号一つの = にしてしまうでしょう.他の言語ではこれは文法的には問題ないものの間違った処理となります.ところが,Python ではこれを文法エラーとしてはじいてくれます.便利ですね.
IDLE で Run module した際のエラーメッセージ
File "Z:\Ubuntu_backup\common\ECS_html\lecture\python1_23\20231106\equal.py", line 3 if a = 2: ^^^^^ SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='? |
教科書の p.46 に説明があるように,if 文では処理の構成をインデント(字下げ)によって作ります.インデントの文字幅が間違っているとエラーとなりますので,注意してください.
教科書の補足
値の型として整数型や文字列型などが以前から出てきていますが,if 文の判定などでは真か偽かの2択となる論理型(ブール型)が登場します.ほとんどの言語で値が数値の 0 のときが偽となります.また,文字列の False も偽を意味します.そういったもの以外は大体真として扱われます.
比較演算子を用いて大きい,小さい,等しいなどを if 文では判定しますが,そのような比較を複数まとめて表現する際に論理演算子が使用されます.言葉でいうと,「かつ」や「または」です.他の言語では記号が用意されていることが大半ですが,Python では文字の and や or を使用します.
Python の特徴として論理演算子を省略できる書き方があります.他の言語では認められない以下のような表現が可能です.
if 0 < num < 10:
上の処理は例えばC言語では以下のようになり,論理演算子が必要です.
if(num > 0 && num < 10)
条件式が単純な大小比較などであれば簡単な表現で処理を実現できますが,とびとびの値など比較演算子だけでは長くなる処理などで,教科書 p.61 の List 3-19 にあるような集合(プログラム入門IIで学習予定)を用いた判定が役に立ちます.これも Python の便利なところの一つです.
今回の演習問題です.
教科書の p.46-63 の範囲について学習しました.if 文は以下のように構成されています.
if 式: 文 |
最初のうちは式の後のコロン : を忘れがちなので注意しましょう.また,文はインデント(字下げ)が無いと認識されませんので,注意してください.
宿題が公開されるのは明日木曜日10:00の予定で,締切りは来週の月曜日11月11日の10:00です.レポート提出システムを使用します.
次回も教科書のp.45-88の範囲を学習しますので,予習をしてきてください.