これは12月13日のアドベントカレンダーです。
はじめに
『たすき』をたぬきします。え、なんだって…?
友人や家族に手紙を送るときに手紙の内容を暗号化することを幼いころにやりませんでしたか。今回はたぬき暗号たちを復号していきます。
目次
- 『たすき』をたぬき
- 『さんご』さがり
- 愛情をこめたい
- 使いやすく
『たすき』をたぬき
たぬきとは、文字列から「た」を抜くこと。
ということで、pythonで作ったものが下のものになります。
moji_l = list(map(str,input().split()))
moji = moji_l[0].replace(moji_l[1],'')
moji = moji.strip()
print(moji)
たすき た
すき
~流れ~
最初に、復号化したい文字列と消したい文字を配列に格納します。
次に、復号化したい文字列の中から消したい文字と一緒のものを空白に置き換えます。
最後に、空白をなくして出力します。
『さんご』をさがり
さがりとは、文字列の「さ」を「り」に変えること。
ということで、作ったコードは下のものになります。
moji_l = list(map(str,input().split()))
moji = moji_l[0].replace(moji_l[1],moji_l[2])
moji = moji.strip()
print(moji)
~変更点~
3行目の文字の置き換えを空白から入力文字三つ目に変更しました。
ここで事件発生!!
UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 9-10: invalid continuation byte
さんご さ り
エラー…なぜでしょうか。デコードできないって何でしょうか…
空白が全角なのが駄目なのでしょうか…
さんご さ り
空白を全角から半角に変えたらいけました。
でも、両方使えるようにしたいです。
愛情をこめたい
誰かに日頃の感謝を伝えたいけど、少し照れくさくて伝えられないときありませんか。その思いを暗号化しましょう。
①たぬき暗号
moji_l = input()
moji_x = moji_l[-1]
num = list(map(int, input().split(',')))
angou_l = []
j = 0
for i in range(len(moji_l)-2):
if i == num[j]:
angou_l.append(moji_x)
j += 1
angou_l.append(moji_l[i])
angou = ''.join(angou_l)
print(angou)
ありがとう て
2,3,4
ありてがてとてう
②文字変更
文字変更は「『さんご』をさがり」と同じものを使います。
使いやすく(らすと!!)
使いやすくしたかったのですが、うまくまとめることができませんでした。うまくいかなかった点は次の2つでした。
- 最初の選択をするIF文が動かない
- 判定とループの矛盾
まず、最初の選択するif文が動かない点についてですが、3行目の「if A == '1'
」のような判定なところを「if A == 1
」としていました。これは、数字の1
、半角英数字の'1'
、全角の'1'
の違いが分かっていませんでした。単純なミスなのですが、エラーが出ないミスだったのでなかなか気づけず苦労しました。
if A == 1 ⇒ if A == '1'
次に、判定とループの矛盾についてです。事の発端は『一つ前の愛を込めたい』で作成したコードを更に使いやすくしたいと考えたことがきっかけです。具体的には、「ありがとう」という文字に「た」という文字を挿入するとき「あたたたたりがとう」のように同じ位置に複数回入れたいと思っていました。ですが、作成したプログラムは一つの位置に一つの文字しか入れられません。使いやすくしようと考えた結果…
moji_l = list(map(str,input().split(',')))
moji = list(moji_l[0])
num = list(map(int,input().split(',')))
angou_l = []
j = 0
for i in range(len(moji)):
if i == num[j]:
while num[j] <= i:
angou_l.append(moji_l[1])
j += 1
angou_l.append(moji[i])
angou = ''.join(angou_l)
print(angou)
ありがとう,た
1,2,3,4
/usr/lib/python3/dist-packages/requests/__init__.py:89: RequestsDependencyWarning: urllib3 (1.26.12) or chardet (3.0.4) doesn't match a supported version!
warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported "
Traceback (most recent call last):
File "test_02.py", line 8, in <module>
while num[j] <= i:
IndexError: list index out of range
このような結果になってしまいました。このエラーの意味は、どこかでインデックス範囲外になってしまってるとのことです。ここから行き詰ってしまったため、先輩のお力をお借りしました。
まず、このエラーが出る原因についてですが、実際入力した値で考えるとわかりやすかったです。
ありがとう,た
1,2,2,3
①「あた」②「あたりたた」③「あたりたたとた」 ←ここ
上の部分のときに while
で num[4] <= i
この判定をおこなってしまっているため、エラーが出てしまうそうです。
次にエラーは出ていないのですが、if
とwhile
の判定のところで「i == num[j]
」と「num[j] <= i
」矛盾を起こしてしまっています。そもそもwhile文の方を正せばif文は書く必要がないみたいです。
これらを直して
print('1.たぬき暗号化','2.たぬき復号化','3.文字変更')
A = input()
if A == '1':
print('文字列,入れたい文字 全角で入力してください')
moji_l = list(map(str,input().split(',')))
moji = list(moji_l[0])
print('数字,数字,数字,... のように半角で入力してください')
num = list(map(int,input().split(',')))
angou_l = []
j = 0
for i in range(len(moji)):
while j < len(num) and num[j] == i:
angou_l.append(moji_l[1])
j += 1
angou_l.append(moji[i])
angou = ''.join(angou_l)
print(angou)
elif A == '2':
print('文字列 消したい文字 全角で入力してください')
moji_l = list(map(str,input().split(' ')))
moji = moji_l[0].replace(moji_l[1],'')
moji = moji.strip()
print(moji)
elif A == '3':
print('文字列 変える文字 変えたい文字 全角で入力してください')
moji_l = list(map(str,input().split(' ')))
moji = moji_l[0].replace(moji_l[1],moji_l[2])
moji = moji.strip()
print(moji)
else:
print('ERROR')
完成です。
感想
愛情を込めることの大変さとプログラムにかきなれていないことを改めて実感しました。一つのエラーの意味を理解するのに時間を掛けすぎてしまったのが、自分で書いたプログラムを理解していないと感じてとても悔しいかったです。また、変数名やコードをきれいにかけていないと相手に伝えるのが難しいためきれいコードについて調べていこうと思いました。
皆さんもたすきを大切な人へ。
参考資料
・リストの指定した位置へ要素を挿入する
・【Python】競技プログラミング 基本入力まとめ
・簡単に作れる!メッセージを暗号に変える方法