2017-06-21 6 views
0

私は現在、初心者向けのPythonコースの暗号プログラムを開発中です。最初に、アルファベットの文字列を参照として使用して、指定された文字の位置を返す関数を作成するように指示されました(これは私のalphabet_position関数です)。次に、単一の文字を許可する関数を作成するように指示されました文字を選択された数だけ回転させる(つまりrotate_character関数)。第3に、前の2つの機能を使用して基本的なシーザー暗号を作成することになりました。それらのすべては、以下の私のコードで実証されたように仕事をすることができました。Python Vigenereは動作していますが、関数を使ってスペースやアルファベット以外の文字を扱うことはできません

しかし、ビゲーネははるかに困難であることが証明されています。私はアルファベット文字だけが使用されていても、アルファベット以外の文字(!や?など)を入力するとすぐに、最初の関数(alphabet_position)を使って作業するためのコードスニペットを実際に見つけることができました。私はValueErrorの返品を受け取ります:部分文字列が見つかりません。プログラムがこれらのアルファベット以外の文字に遭遇すると、キーはそれらをスキップして、キーのN番目の文字を次のアルファベット文字に運ぶと考えられます。

私は、どういうわけか、rotate_character関数を自分のEncrypt関数に組み込んでいると思っていますが、rotate_character関数がアルファベット文字を期待していて、これを行う方法がわかりません.vigenere関数は、それを実行しています。

アドバイスはありますか?そして、私は新しいプログラマだと、私は喜んであなたが浸透することをお勧めします私のコーディング慣行上の他の有用な批判を取る! `

> #Create function alphabet_position(letter) to turn letter into number 
> #such as a=0 or e=4, using lowercase to make sure case doesnt matter. 
    alphabet = "abcdefghijklmnopqrstuvwxyz" 
    def alphabet_position(letter): 
>  lower_letter = letter.lower() #Makes any input lowercase. 
>  return alphabet.index(lower_letter) #Returns the position of input 
              as a number. 
> 
> def rotate_character(char, rot): 
>  if char.isalpha(): 
>   a = alphabet_position(char); 
>   a = (a + rot) % (int(len(alphabet)));   #needs modulo 
>   a = (alphabet[a]); 
>   if char.isupper(): 
>    a = a.title() 
>   return a 
>  else: 
>  return char 
> 
> def caesar(text, rot): 
>  list1 = "" 
>  for char in text: 
>   list1 += rotate_character(char, rot) 
>  return list1 
> 
> def vigenere(text,key):  
    m = len(key) 
> 
> newList = "" 
> 
> for i in range(len(text)):  
     text_position = alphabet_position(text[i])  
     key_position = alphabet_position(key[i % m])  
     value = (text_position + key_position) % 26   
     newList += alphabet[value]  
    return newList 
> 
> def main(): 
>  x = input("Type a message: ") 
>  y = input("Rotate by: ") 
>  result = vigenere(x, y) 
>  print (result) 
> 
> if __name__ == '__main__': 
     main() 

答えて

1

いいえ、あなたはもう回転機能を必要としません。アルファベットにない文字を新しいリストに直接追加して、暗号化部分をスキップするだけで済みます。

pt_c = text[i] 
pt_i = alphabet.find(pt_c) # returns -1 instead of an error when not found 
if pt_i == -1: 
    newList += pt_c 
else: 
    newList += pt_c 
    # do your thing *with the given index* 

この:より最適なもちろん

if text[i] in alphabet: 
    # do your thing 
else: 
    newList += text[i] 

一度だけアルファベットを通過し、変数を使用することです:

は今これを行うための次善の方法は、if ... in ...を使用することですもちろん、Vigenère暗号のランタイムには違いはありません。しかし、それは後で効率的なプログラミングを考える方法を示しています.2回検索する必要はありません。

あなた可能性もcontinue代わりにelse文持つのループ:あなたのループを作るの不幸な副作用で

pt_c = text[i] 
pt_i = alphabet.find(pt_c) # returns -1 instead of an error when not found 
if pt_i == -1: 
    continue 
# do your thing with the given index 

が、これはあなたのループの押し込み深さを行います(スコープの量)より少ないが、より複雑(ローカルの出口点を作成する)。

+0

あなたが与えた最初のオプションを試してみましたが、それは完璧に機能しました!私は他の人たちと一緒に彼らがどのようにうまくいくかを見て回ります。学習するための実験のために、私のvigenere関数内でrotate_character関数を使用するように調整する方法はありますか?そうでない場合は、それは問題ありません。助けてくれてありがとう! –

+0

確かに、forループと 'rotate_character'関数のfor文を再び見てください。彼らはぼんやりと馴染んで見ていないのですか? 'key'position'を' rot'パラメータとして使うとどうなりますか? –

+0

ありがとうございます!私はこれらのすべてを実験して、スクリプトでどのように動作するかを見ていきます! –

関連する問題