プログラミング入門I
2025.01.06
文字列1
今回はテストにしてはエラーのものが少なく,そこはだいぶ皆さんも慣れてきたのかと思いました.ただ,ゼロでは無いのでそこはさらに慎重にお願いします.確認テストはもう1回あります. 前回の課題提出: b2438 実行時エラー: b2407 番号出力間違い: b2410 以下は例によって問題のあるプログラムの例です.参考にしてください.ただし,箸にも棒にも掛からないものは特に説明はしません.
print('-'*27)
解答用紙に元からあるのにどうして追加するんでしょうか.結局下のような表示になります.他にも上に同じものでハイフンラインをつけた人もいました.
2 3 4 5 6 7 8 9 10 3 4 5 6 7 8 9 10 11 4 5 6 7 8 9 10 11 12 5 6 7 8 9 10 11 12 13 6 7 8 9 10 11 12 13 14 7 8 9 10 11 12 13 14 15 8 9 10 11 12 13 14 15 16 9 10 11 12 13 14 15 16 17 10 11 12 13 14 15 16 17 18 11 12 13 14 15 16 17 18 19 --------------------------- ------------------------ |
for i in range(1, 11): print(f'{i:2}', end = '') i += 1 for j in range(i, i + 9): print(f'{j:2}', end = '') j += 1 else: print() |
授業の例題でずっと else のところに改行を入れる練習をしてきたと思うのですが,まだ見についていない人も多くみられました.
1 2 3 4 5 6 7 8 910 2 3 4 5 6 7 8 91011 3 4 5 6 7 8 9101112 4 5 6 7 8 910111213 5 6 7 8 91011121314 6 7 8 9101112131415 7 8 910111213141516 8 91011121314151617 910111213141516171810111213141516171819 |
for i in range (0,11): for j in range(1,11): print(f'{i + j:3d}', end='') print() |
外側の for 文が11回繰り返すものになっていますので,下のように余分にもう1行出力してしまいます.
1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 11 3 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 12 13 5 6 7 8 9 10 11 12 13 14 6 7 8 9 10 11 12 13 14 15 7 8 9 10 11 12 13 14 15 16 8 9 10 11 12 13 14 15 16 17 9 10 11 12 13 14 15 16 17 18 10 11 12 13 14 15 16 17 18 19 11 12 13 14 15 16 17 18 19 20 |
for i in range(1,11): for j in range(i+1,i+10): print(f'{i}',end = ' ') |
ただ単に変数 i を出力するだけなら,結果は当然下のようになるよね.
1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 10 |
for i in range (a,b): print(f'{i:3}', end = '') a += 1 b += 1 for j in range (a,b): print(f'{j:3}', end = '') |
どうして for 文なのにこんな += を使う?
for i in range(1, 11): for j in range(1, 11): print(f'{i:2} {j:2}', end = '') else: print() |
内側の for 文の print の中で i と j 両方を出力するから当然下のように数字が2つ出てきますよね.
1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 2 10 3 1 3 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 3 10 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 4 10 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5 8 5 9 5 10 6 1 6 2 6 3 6 4 6 5 6 6 6 7 6 8 6 9 6 10 7 1 7 2 7 3 7 4 7 5 7 6 7 7 7 8 7 9 7 10 8 1 8 2 8 3 8 4 8 5 8 6 8 7 8 8 8 9 8 10 9 1 9 2 9 3 9 4 9 5 9 6 9 7 9 8 9 9 9 10 10 110 210 310 410 510 610 710 810 910 10 |
for i in range(1, 11): print(f'{i:2}', end = ' ') print() for j in range(i, i + 10): print(f'{j:2}', end = ' ') else: print() |
上のように内側の for 文の前になぜか print を入れる人が結構いました.どうしてそういう発想になるんでしょうか?
1 1 2 3 4 5 6 7 8 9 10 2 2 3 4 5 6 7 8 9 10 11 3 3 4 5 6 7 8 9 10 11 12 4 4 5 6 7 8 9 10 11 12 13 5 5 6 7 8 9 10 11 12 13 14 6 6 7 8 9 10 11 12 13 14 15 7 7 8 9 10 11 12 13 14 15 16 8 8 9 10 11 12 13 14 15 16 17 9 9 10 11 12 13 14 15 16 17 18 10 10 11 12 13 14 15 16 17 18 19 |
for i in range(1,11): for j in range(1,11): print(f'{j:2}',end=' ') j+=1 print() j+=1 |
こちらもどうして for 文で j+=1 とか要るんでしょうかね? while 文で作るのならわかりますが.
for a in range(10): for b in range(10): num+=1 print(f'{num:2}',end=' ') print('') num-=10 num+=1 |
せっかく変数 a と b が range 関数によって 0 から 9 まで順に変わっていくのにどうして num なんて変数を使うんでしょうか?
for i in range(1, 11): print(f'{i:2}', end = '') for j in range(i + 1, i + 10): print(f'{j:2}',end = ' ') else: print() |
上のものもなぜか内側の for 文の前に print があるので,そこだけ表示が下のようにずれています.
1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 11 3 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 12 13 5 6 7 8 9 10 11 12 13 14 6 7 8 9 10 11 12 13 14 15 7 8 9 10 11 12 13 14 15 16 8 9 10 11 12 13 14 15 16 17 910 11 12 13 14 15 16 17 18 1011 12 13 14 15 16 17 18 19 |
for i in range(1,11): for j in range(i+1,20): print(i,j,end=' ') print() else: print() |
これも変数 i と j の両方を出力していますし.
1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15 1 16 1 17 1 18 1 19 2 3 2 4 2 5 2 6 2 7 2 8 2 9 2 10 2 11 2 12 2 13 2 14 2 15 2 16 2 17 2 18 2 19 3 4 3 5 3 6 3 7 3 8 3 9 3 10 3 11 3 12 3 13 3 14 3 15 3 16 3 17 3 18 3 19 4 5 4 6 4 7 4 8 4 9 4 10 4 11 4 12 4 13 4 14 4 15 4 16 4 17 4 18 4 19 5 6 5 7 5 8 5 9 5 10 5 11 5 12 5 13 5 14 5 15 5 16 5 17 5 18 5 19 6 7 6 8 6 9 6 10 6 11 6 12 6 13 6 14 6 15 6 16 6 17 6 18 6 19 7 8 7 9 7 10 7 11 7 12 7 13 7 14 7 15 7 16 7 17 7 18 7 19 8 9 8 10 8 11 8 12 8 13 8 14 8 15 8 16 8 17 8 18 8 19 9 10 9 11 9 12 9 13 9 14 9 15 9 16 9 17 9 18 9 19 10 11 10 12 10 13 10 14 10 15 10 16 10 17 10 18 10 19 |
rows = 10 cols = 10 matorix= [[i + j for j in range(1, cols + 1)] for i in range(rows)] for row in matorix: print(" ".join(map(str, row))) |
前回の宿題のところで説明しましたが,リストや内包表記,さらには join メソッドまで使いこなせるのなら,下のような表示はあり得ないよね.
1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 11 3 4 5 6 7 8 9 10 11 12 4 5 6 7 8 9 10 11 12 13 5 6 7 8 9 10 11 12 13 14 6 7 8 9 10 11 12 13 14 15 7 8 9 10 11 12 13 14 15 16 8 9 10 11 12 13 14 15 16 17 9 10 11 12 13 14 15 16 17 18 10 11 12 13 14 15 16 17 18 19 |
エラーになるものはありませんでしたが,依然として解答用紙の学生番号と名前を自分のものに書き換えることを忘れている人は出ています.注意しましょう.
解答用紙の番号と氏名: b2429
出力時番号: b2429
さて,今回はプログラムを作る際にビット単位の論理演算子の使用を条件としていました.その部分を完全に無視してプログラムしている人が少なくない人数でした.残念です.当然ながら,題意を満たしていないので不合格点となってしまいます.問題文をよく理解してから取り組みましょう.
以下は例によって問題のあるプログラムの例です.参考にしてください.
S1 = random.randint(0,1) S2 = random.randint(0,1) S3 = random.randint(0,1) |
変数名は小文字で始めるよう何度も何度も何度も何度も何度も何度も何度も何度も何度も何度も何度も何度も何度も...
z = s2 | s3 w = s1 & z |
以前にも指摘したのですが,意味のないアルファベット1文字の変数名はやめましょう.見る人にとっては何を表すものなのかがわかりません.
if s1 == 1 and s2 | s3 == 1: res = 'ON' else: res = 'OFF' |
このパターンの処理を書いた人が結構多くみられました.if 文ところで体験はしたはずなのですが,忘れているのでしょうか.True とは何か,False とは何かというときに,Python では数値の 0 をブール値の False と対応させています.ですので,
num = 0 if num: do something |
のような場合に if 文の式は False になります.これは11月18日の確認テストの解答例の「条件式の簡略化」の方でも紹介しています.
if S1 == 1 & S2 == 1 or S3 == 1: print('Light: ON') else: print('Light: OFF') |
上の例も & は使用しているものの数値としての 1 を使用することになっていますね.
# ライトの状態を判定 # 条件: (S1 & S2 & S3) or (S1 & S2 & ~S3) or (S1 & ~S2 & S3) light = ((s1 & s2 & s3) | (s1 & s2 & ~s3) | (s1 & ~s2 & s3)) & 1 |
これも無駄に条件を複雑にしています.論理和を使っていないせいですね.
if s1==1 and s1 & (s2 | s3): print('Light: ON') else: print('Light: OFF') |
上のものも s1==1 が不要でした.
if swith1 & (swith2 | swith3) == 0: print('Light: ON') elif swith1 == 1: print('Light: OFF') else: print('Light: OFF') |
こちらもやはり変な処理でした.
s4 = s2 | s3 s = s1 & s4 |
こちらも何度か指摘していますが,無駄な変数を仲介させるのをやめましょう.見る人にとっては分かりづらくなります.それにスイッチ S4 は元々無いですから,名前も誤解させるものになります.
light = s1 & (s2 | s3) if s1 == 1: ss1 = 'ON' else: ss1 = 'OFF' if s2 == 1: ss2 = 'ON' else: ss2 = 'OFF' if s3 == 1: ss3 = 'ON' else: ss3 = 'OFF' if light == 1: slight = 'ON' else: slight = 'OFF' |
上のものも不要な変数を使って分かりにくくしています.
if random1&random2|random3: print('Light:ON') else: print('Light:OFF') |
& と | は同じ強さの演算子ですので,カッコでくくらないと s2 か s3 のどちらかが 1 になると必ず真になります.ですので,下のように間違った結果になります.
S1:OFF S2:OFF S3:ON Light:ON |
以下は歓迎できない処理のものたちです.
if s1 & s2 & ~s3: print(f'S1: ON\nS2: ON\nS3: OFF\nLight: ON') elif s1 & s2 & s3: print(f'S1: ON\nS2: ON\nS3: ON\nLight: ON') elif s1 & s3 & ~s2: print(f'S1: ON\nS2: OFF\nS3: ON\nLight: ON') elif s2 & s3 & ~s1: print(f'S1: OFF\nS2: ON\nS3: ON\nLight: OFF') elif s2 & ~s3 & ~s1 : print(f'S1: OFF\nS2: ON\nS3: OFF\nLight: OFF') elif s3 & ~s2 & ~s1: print(f'S1: OFF\nS2: OFF\nS3: ON\nLight: OFF') elif s1 & ~s2 & ~s3: print(f'S1: ON\nS2: OFF\nS3: OFF\nLight: OFF') else: print(f'S1: OFF\nS2: OFF\nS3: OFF\nLight: OFF') |
上のように複雑なものは私は絶対に出題しないと何度も言っています.本当にこんな処理が必要なものを出題すると,合っているかどうか採点が地獄の苦しみになるからです.
binary=0 for i in range(1,4): num=random.randint(0,1) binary += num * 100//10**(i-1) if num == 1: print(f'S{i}: ON') else: print(f'S{i}: OFF') if binary <= 100: print(f'Light: OFF') else: print(f'Light: ON') |
まったく題意を無視して勝手なことをやっていますが,なんで?
S1 = 1 S2 = 1 S3 = 0 Light = S1 & S2 & (~S3 & 1) print("S1:", "ON" if S1 else "OFF") print("S2:", "ON" if S2 else "OFF") print("S3:", "ON" if S3 else "OFF") print("Light:", "ON" if Light else "OFF") |
上のように乱数を使用しないで決め打ちのものもなぜか複数でてきました.こちらもどうしてなんでしょうかね?
ビット演算子の活用について学習しました.ただ,中身はビットの並びを意識してよく考えないとわからないややこしいものでしたし,複合演算子なども出てきましたので,余計に難しくなったかもしれません.いずれどこかで出てきたら,またその時に改めて考えましょう.
変数名などで文字の並んだものをこれまで使用してきましたが,値として文字の並びを持つものが文字列です.文字が1文字であっても Python は文字列として扱うことになっています.
インデックス
文字列のそれぞれの文字には順番に応じて番号が振られており,それをインデックスと言います.先頭を 0 番としそれ以降 1, 2, 3, … と続きます.また,末尾の文字から順番に数えていきたいときには -1, -2, -3 … のように負の数で表現します.このインデックスは反復処理などで文字列を扱う際に重要です.
s = 'python' print(s[1]) |
上のようにすると,文字列 'python' の2文字目の y が出力されます.このようにインデックスは [ ] で指定します.
len 関数
len(str) は文字列 str の文字数を返す関数ですが,この例で str は文字列オブジェクトの変数名であり,値の方の文字数を返すことはわかるとおもいます.
スライス
スライスは Python に特徴的な操作で文字列の中から任意の文字を取り出すことができます.教科書 p.139にスライスで文字を抽出する際の例がありますので,ぜひ見ておいてください.
文字列に対してさまざまな操作を行うメソッドが用意されています.次回以降演習問題を通して学習していきましょう.
ここまで f 文字列を多く利用してきましたが,他にも % 記法や format メソッドがあります.こちらは必要に応じて使用しましょう.
今回の演習問題です.
文字列に関するいくつかの操作を学習しました.次回以降も使用する処理としてはランダムな文字からなる文字列の生成です.以下のように,類纂代入演算子 += と反復処理を利用して任意の長さの文字を作ることができます.
s = '' for _ in range(5): s += chr(random.randint(97, 122)) |
上の例はアルファベットの小文字をランダムに5個並べた文字列の生成の例です.
宿題が公開されるのは明日火曜日10:00の予定で,締切りは20日の10:00です.レポート提出システムを使用します.
次回も引き続き教科書のp.134-162の範囲を学習しますので,予習をしてきてください.
なお,次回は最後ですので,授業の終わりに確認テストを実施します.