プログラミング入門I
2024.12.23
オブジェクトと型
今回も実行時のエラーが無く気持ちよく採点できました.その点はうれしかったです.ただ,依然として習ってもいないリストを使う人がなくなりません.もちろん分かって使っているのなら問題は無いのですが,それだけのスキルがある人ならしないような不備もあるので,やっぱり検索やAIに頼ってしまって実力が伴っていない人と判断差ざるを得ないものが大半です.何のために大学で高い授業料を原って授業を履修しているのか,その意味をよく考えてください. 出力時番号間違い: b2447 以下は例によって問題のあるプログラムの例です.参考にしてください.
MIN = 100
MAX = 1
変数名は小文字で始めるように何度も何度も何度も何度も...
for _ in range(5):
mx=0
mini=100
for _ in range(10):
ran = random.randint(1,100)
print(f'{ran:3}',end = ' ')
if mx < ran:
mx = ran
if mini > ran:
mini = ran
else:
print(f' -- {mini:3} {mx:3}')
else:
print()
|
目には見えないのですが,上の print 文の中に全角スペースが入っています.そのため,私の環境では表示が下のようになってしまいます.
100 35 63 87 73 57 63 10 9 51 □@-- 9 100 7 35 23 39 10 45 25 7 49 44 □@-- 7 49 45 100 85 81 1 67 37 36 66 12 □@-- 1 100 100 68 73 78 34 86 45 65 77 49 □@-- 34 100 39 3 16 100 52 84 43 68 34 50 □@-- 3 100 |
for j in range(5):
mn=101
mx=0
for i in range(10):
num=random.randint(1,100)
print(f'{num:3}',end=' ')
if num > mx:
mx = num
if num < mn:
mn = num
print(f' -- {mn:3} {mx:3}')
else:
print()
|
上の例は中身は問題ないのですが,インデントのTAB幅が2倍になっています.インデントが進むたびにどんどん右にずれていくので,全体としては見づらいものになります.IDLEでは標準で4文字分になっているはずですが,その設定がもし変わってしまったのなら直してください.
num = random.randint(1,100)
print(f'{num:3}', end = '')
|
発生させる乱数は1から100までですので,3桁は合っているのですが,スペースを入れていないのでくっついて見づらくなります.
71 76 82 33100 61 84100 19 76 -- 19100 19 42 51 97 61 74 64 45 47 86 -- 19 97 78 21 19 98 45 37 75 15 41 96 -- 15 98 33 52 84 14 56 11 63 28 43 35 -- 11 84 55 40 32 87 41 37 90 30 99 87 -- 30 99 |
for i in range(1,6):
ma = 0
mi = 100
for j in range(1,11):
j = random.randint(1,100)
print(f'{j:3} ', end = '')
if j > ma:
ma = j
elif j < mi:
mi = j
print(f' -- {mi:3} {ma:3}')
|
内側の for 文の引数 j を乱数にも使うという良くない書き方をしていますが,それに加えて,最小値の判定を elif にしているので,結果が以下のように間違ったものになります.elif を使った人は他にも何人かいました.最大値か最小値かは関係しないものなので,最大値でなければ最小値かという処理は間違いです.
1 65 98 67 27 46 21 64 48 46 -- 21 98 70 82 56 34 62 50 97 76 64 46 -- 34 97 14 20 71 70 7 54 35 62 23 63 -- 7 71 90 78 27 56 32 58 15 56 57 74 -- 15 90 30 57 28 94 39 13 14 81 58 22 -- 13 94 |
large = 0
small = 101
for _ in range(1,6):
for _ in range(1,11):
num = random.randint(1,100)
print(f'{num:3}',end = '' )
if num > large:
large = num
if num < small:
small = num
print(f'--{small:4}{large:4}')
|
最大値と最小値の初期値をループの外で行っているので,初期値が更新されず,前の値を引きずってしまっています.そのため,当然下のように結果は間違ったものになります.
55 78 91 80 47 37 25 56 30 26-- 25 91 81 88 23 68 74 36 37 39 42 61-- 23 91 16 34 1 61 86 96 77 31 65 24-- 1 96 74 98 80 52 12 11 35 66 29 51-- 1 98 74 5 3 90 65 50 4 93 65 34-- 1 98 |
max1=0
min1=100
n=0
for i in range(1,6):
for u in range(1,11):
n+=random.randint(1,100)
print(f'{n:3}',end=' ')
if max1 |
こちらは初期化はできているので値は正しいものになっていますが,最初に行った初期化は意味がありません.ループの先頭で1回書けば済みます.
for _ in range(5):
max1=0
min1=101
keep=0
for _ in range(10):
keep=random.randint(1,100)
print(f'{keep:3}',end=' ')
if max1 |
内側のループの前の変数 keep への代入は不要ですね.
print(f"{numbers_str:<25} -- {min_value:<10}{max_value:<10}")
|
なんで左揃えになってしまうのでしょうか?
for _ in range(5):
num1 = random.randint(1, 100)
print(f'{num1:4}', end ='')
mx = 0
mn = 100
for _ in range(9):
num2 = random.randint(1, 100)
print(f'{num2:4}', end = ' ')
if num2 > mx :
mx = num2
if num2 < mn:
mn = num2
if num1 > mx:
mx = num1
if num1 < mn:
mn = num1
else:
print(f' -- {mn:3} {mx:3}')
|
10個の整数を2つの組に分ける意味が分かりません.当然 if 文の処理も無駄に多くなります.
print(" ".join(f"{num:2d}" for num in numbers), end=" -- ")
print(f"{min_num:2d} {max_num:2d}")
|
1から100までの数なので,3桁ですよね?なぜ2桁分の表示なんでしょうかね.当然画面の表示は乱れます.自分でも気づいているはずですが.
以下はリストを使用したものです.心配しなくてもプログラミング入門IIでリストはやりますから,今は学習した内容を反映させて,今の能力で適切なものを作ってください.
for _ in range(5):
num = []
count = 0
while count < 10:
num.append(random.randint(1, 100))
count += 1
small = 101
large = -1
for n in num:
if n < small:
small = n
if n > large:
large = n
print(" ".join(f"{n:>3}" for n in num) + f" -- {small:>3} {large:>3}")
|
for i in range(5):
n = [random.randint(1, 100)for _ in range(10)]
MIN = min(n)
MAX = max(n)
numbers = ' '.join(f'{num:2}' for num in n)
print(f'{numbers} -- {MIN} {MAX}')
else:
print()
|
リストを使いこなせる能力があるのなら当然表示桁数もちゃんとできるはずですよねえ.
64 12 9 11 53 66 23 54 17 39 -- 9 66 69 24 47 84 81 25 71 42 30 86 -- 24 86 7 75 63 10 96 10 2 9 44 25 -- 2 96 7 25 60 36 100 47 8 77 37 26 -- 7 100 4 93 43 47 74 100 12 18 41 100 -- 4 100 |
for _ in range(5):
random_num = [random.randint(1, 100) for _ in range(10)]
min_num = min(random_num)
max_num = max(random_num)
print(f"{random_num}",end = ' ')
print(f"-- {min_num}",end = ' ')
print(f"{max_num}")
|
リストを使いこなせる能力があるのなら,当然アンパックくらいは知っていて,下のような変な表示はしないですよねえ.
[64, 33, 63, 67, 1, 100, 1, 83, 35, 79] -- 1 100 [90, 91, 32, 6, 23, 14, 15, 9, 20, 45] -- 6 91 [86, 95, 85, 57, 85, 46, 47, 19, 21, 89] -- 19 95 [4, 19, 35, 15, 18, 67, 72, 57, 58, 5] -- 4 72 [58, 84, 7, 54, 97, 68, 23, 96, 62, 49] -- 7 97 |
今回は確認テストで復習状況をチェックしますので,しっかり準備してください.
Python は「オブジェクト指向言語」というプログラミング言語の一つです.その「オブジェクト」の意味がこの章では詳しく説明されています.ただ,この授業で行っているような初歩的なプログラムではその恩恵を受けることはほとんどありませんが,それでも今回はいろいろと確認していきましょう.
変数に値を代入するという操作はオブジェクトとしての値に変数名を紐づける,ということになります.それが特にわかるようなことはプログラミングの作業中にはありませんが,後ほど出てくるように誰も参照しないオブジェクトは削除する,という裏側の機能によってメモリの無駄遣いを防ぐことにはなっています.
まずは,教科書 p.116 にあるようにインタラクティブシェルで試してみてください.
まだリストなどを学習していないので,このミュータブルとイミュータブルの違いを実感することはありません.リストを学習し始めて,変な処理を書いてしまうと,これに関するエラーを目にすることがあるかもしれません.
== は値が同じかどうかを判定する比較演算子でしたが,is 演算子はオブジェクトそのものが同じかどうかを判定します.
これまでにも型の話は出てきていますが,実際に演算を行うとどうなるのかについて,一応教科書をよく見て確認しておいてください.また,教科書 p.124 にある Table 5-3 には様々な組み込み関数が紹介されていますので,ここはぜひとも活用できるように覚えておきましょう.本日の演習問題ではこれらを使うプログラムを作っていきます.また,教科書 p.127 の List 5-7 に例示されている数値の表示の際の空白を 0 で埋める表現も,場合によっては使用しますので,確認しておいてください.
どのプログラミング言語の教科書にも出てくるビット演算ですが,入門的な範囲では基本的には使うことはありません.これは複数のフラグを管理するような用途において,通常の演算よりもビット演算の方が高速であるために用意されているものだと思ってください.
今回はファイルのアクセス許可などで使用されているフラグ判定についての簡単な作業を演習で体験します.一応こんなもんだと思って知識として持っておいてください.
今回の演習問題です.
宿題が公開されるのは明日火曜日10:00の予定で,締切りは来年の1月6日の10:00です.レポート提出システムを使用します.
次回は教科書のp.134-162の範囲を学習しますので,予習をしてきてください.