プログラミング入門I
2024.01.22
文字列1

Back to index page



  1. 本日の作業内容

  2. 前回の宿題について

    今回は以下のような軽微な残念なミスが少し出ました.今回が最後なので,これからもしっかり確認してから提出するようにしましょう.

    解答用紙の番号と名前: b2345 b2360 prog4

    出力時番号間違い: b2328 b2360 prog4

    以下は例によって問題のあるプログラムの例です.参考にしてください.

    print(f'Shifted:  {st[shiftnum:20]}',end='')
    print(f'{st[0:shiftnum]}')
    

    上のような書き方が今回多く見られました.ただ,これは課題の指示に従っていません.文字をシフトさせた文字列に変更してから出力するという条件になっていますので,上のようにただ単に文字列の後半と前半をそれぞれ表示するということでは適切ではありません.

    print(f'Shifted:  {alphabet[num:]}{alphabet[:num]}')
    

    これも同様で,print 文を2つに分けていないというだけで,実際にシフトさせた文字列は生成されていません.

    for _ in range(1):
        st = ''
    
        for _ in range(20):
            st += chr(random.randint(65, 90) + random.randint(0, 1) *32)
    

    どうして2重の for 文にしないといけないのでしょうかね?

    print(f'Shifted:  s[:{a}{st}]', end = '')
    

    よくわからない処理ですね.インデックスの指数を入れる部分に { } が入っているので下のように出力はおかしいものになります.

    Original: QdRZTbkpTQFTFmIWOwWu
    Shift 5 lettters
    Shifted:  s[:5QdRZTbkpTQFTFmIWOwWu]
    

    num2 = letter + letter
    num3 = num2[num1:21+num1]
    print(f'Original: {letter}')
    print(f'Shift {num1} letters')
    print(f'Shifted: {num3}')
    

    上のような方法も若干数出てきました.同じ文字列を2つ連結させてシフトに対応しようというものですが,まったく題意を満たしていません.文字列の文字を並べ替える処理をスライスで行うのが,今回のポイントです.

    for i in range(20):
        num += (alphabet[(a + i) % 20])
    print(f'Shifted: {num}')
    

    こちらも課題のページにわざわざやらないように指示していた for 文による並べ替えです.

    alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    random_string = ''.join(random.choice(alphabet) for _ in range(20))
    
    # 1から10の整数をランダムに発生させる
    shift_amount = random.randint(1, 10)
    
    # シフトさせた文字列を作成
    shifted_string = ''.join(chr((ord(char) - 65 + shift_amount) % 26 + 65) if char.isupper() else chr((ord(char) - 97 + shift_amount) % 26 + 97) for char in random_string)
    # 結果を表示
    print("Original:", random_string)
    print("shift", shift_amount )
    print("Shifted:", shifted_string)
    

    なんだかややこしいことをやっているようですが,結果は下に示すようにデタラメです.

    Original: whOxPEHEUaBKoYeCuzKx
    shift 4
    Shifted: alSbTILIYeFOsCiGydOb
    

    alphabet=''
    for _ in range(30):
        alphabet+= chr(random.randint(65, 90) + random.randint(0, 1) * 32)
    print(f'Original: {alphabet[0:20]}')
    num=random.randint(1,10)
    print(f'Shift {num} letters')
    print(f'Shifted:  {alphabet[num:num+20]}')
    

    こちらもインデックスの数値を追加しているだけなので,下のように当初は無い文字を表示しています.

    Original: zOIexIxtmZbMwHYmElyT
    Shift 9 letters
    Shifted:  ZbMwHYmElyTZWhBARVvV
    

    letter = ''
    print(f'Original: ',end = '')
    for _ in range(20):
        letter += chr(random.randint(65, 90) + random.randint(0, 1) * 32)
        print(f'{letter}', end = '')
    

    なぜかわかりませんが,文字列の出力を for 文の中に入れているので,文字が追加されるたびにその文字列を表示していて,以下のように長い文字列が出力されます.

    Original: GGGGGVGGVMGGVMzGGVMzxGGVMzxeGGVMzxekGGVMzxekvGGVMzxekvdGGVMzxekvdIGGVM
    zxekvdIYGGVMzxekvdIYRGGVMzxekvdIYRXGGVMzxekvdIYRXBGGVMzxekvdIYRXBKGGVMzxekvdIYRX
    BKoGGVMzxekvdIYRXBKokGGVMzxekvdIYRXBKokuGGVMzxekvdIYRXBKokuW
    Shift 1 letters
    Shifted:  GVMzxekvdIYRXBKokuWG
    

    num1=''
    for _ in range(20):
        num1 +=chr(random.randint(65,90) + random.randint(0,1) *32)
    print(f'Original:{num1}')
    
    num2=random.randint(1,10)
    num3=num1[num2:] + num1[:num2]
    
    print(f'Shift {num2} letters')
    print(f'Shifted: {num3}')
    

    スライスの使い方は合っているのですが,次々と新しい文字列を作っているので,元の文字列の変更にはなっていません.惜しいです.

    def shift_string(input_str, shift):
        return input_str[-shift:] + input_str[:-shift]
    original_str = ''.join(random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') for _ in range(20))
    

    基本的にはできているのですが,ずらし方が違いました.下のようになりますが,先頭から何文字かを後ろにずらすという問題の実行例をよく確認しておくべきでした.

    Original: fcIPyaFsvQljUFtjOXkf
    Shift 3 letters
    Shifted: XkffcIPyaFsvQljUFtjO
    

    def generate_random_string(length):
        letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
        return ''.join(random.choice(letters) for _ in range(length))
    
    def shift_string(original, shift):
        shifted = original[shift:] + original[:shift]
        return shifted
    
    def main():
        original_string = generate_random_string(20)
        shift_amount = random.randint(1, 10)
    
        print(f"Original: {original_string}")
        print(f"Shift {shift_amount} letters")
        
        shifted_string = shift_string(original_string, shift_amount)
        print(f"Shifted:  {shifted_string}")
    
    if __name__ == "__main__":
        main()
    

    なんでこんなややこしいことをするんでしょうか.これを自力でやっているのなら,たいした能力ですが,だったら教科書の習った範囲を使用してもっと簡単に書くこともできるはずです.

    print(f'Original: {s}')
    print('Shift 6 letters')
    print(f'Shifted:        {s[6:]+s[:6]}')
    

    6文字ずらしの決め打ちはダメですね.

    一応,改めて Python の代入について説明しておきます.教科書の p.19 に説明があるのですが,代入は逐次的に行われるのではなく,論理的に同時に行われます.解答例のところで,文字をずらした文字列を生成している部分は以下のようになっています.

    letters = letters[shift:] + letters[:shift]
    

    文字列 letters の shift + 1 番目の文字以降の文字列と,同じく letters の先頭から shift 番目までの文字列が,letters に同時に代入されます.そのため,従来の文字列が shift 文字分ずれた文字列に更新されます.新しい文字列変数を作ったりする必要はありません.

  3. 前回の復習

    文字列について学習しました.文字列は個々の文字が順番に並んでいる特殊なデータ形式(プログラミング入門IIで扱うリストなど配列形式)で,インデックスにより個々の文字にアクセスできます.また,インデックスを使ってスライスという方法を使うと,文字列の切り出しなどが行えます.

  4. 文字列その2

    1. 文字列の操作
      1. 探索
      2. in や not in 演算子を用いて,文字列の中に特定の文字列があるかどうかを判定したり,find 系メソッドによりさらに詳しい文字列に関する探索が可能になります.find などはメソッドなので,ピリオドでつなげて操作を行います.

        str.find('ABC')
        

        教科書にもあるように文字列 str の中に文字列 ABC が含まれているかどうかを調べます.詳しくは演習問題で確認しましょう.

      3. 連結,分割,置換,除去
      4. 文字列を操作するメソッドはたくさんあります.教科書に出ている split などのメソッドを演習問題で確認しましょう.

      5. その他のメソッド
      6. 大文字から小文字に変換するなどの文字種の変更を行うメソッドも用意されています.これまで数値としての文字コードに32に加えることで大文字を小文字に変換するなどしていましたが,upper メソッドを使用することで同じような操作が可能です.

    2. 書式化
      1. % 演算子
      2. 他の言語でも必ず用意されている % 記号を用いた表現です.Python ではあまり使用しないようですが,それには % の使い方が他の言語に比べて面倒なことがあるのかもしれません.

      3. format メソッド
      4. % 記法が面倒なため用意されていた format メソッドですが,記述が長くなる傾向にありますので,現時点では f 文字列が主流になったので,使う意味はもうほとんど無いようです.

      5. f 文字列
      6. これまでさんざん使ってきた f 文字列ですが,この機会に教科書の List 6-17 をしっかり確認して今後も自由に使えるようになりましょう.

  5. 演習

    今回の演習問題です.

  6. 本日のまとめ

  7. 宿題

    宿題が公開されるのは明日火曜日10:00の予定で,締切りは29日の10:00です.レポート提出システムを使用します.

  8. 確認テスト

    いよいよ最後となりましたので,授業の終わりに確認テストを実施します.


目次ページに戻る