2013-03-29 48 views
1

最終,我將能夠在聊天室中發佈類似這樣的簡單問題,但現在我必須發佈它。我仍在努力解決Python中的比較問題。我有一個包含從文件中獲得的字符串的列表。我有一個函數,它包含單詞列表(以前由文件創建)和一些「密文」。我正在嘗試使用Shift Cipher破解密文。我的問題與比較整數相同。雖然我可以看到在嘗試使用打印語句進行調試時,我的密文將被轉移到單詞列表中的單詞,但它永遠不會評估爲True。我可能會比較兩種不同的變量類型,或者一個/ n可能會將比較關閉。對不起今天的所有帖子,我今天在做準備即將到來的作業方面做了很多練習題。Python字符串比較使用單詞列表

def shift_encrypt(s, m): 

    shiftAmt = s % 26 
    msgAsNumList = string2nlist(m) 

    shiftedNumList = add_val_mod26(msgAsNumList, shiftAmt) 
    print 'Here is the shifted number list: ', shiftedNumList 

    # Take the shifted number list and convert it back to a string 
    numListtoMsg = nlist2string(shiftedNumList) 
    msgString = ''.join(numListtoMsg) 

    return msgString 

def add_val_mod26(nlist, value): 
    newValue = value % 26 
    print 'Value to Add after mod 26: ', newValue 
    listLen = len(nlist) 
    index = 0 
    while index < listLen: 
     nlist[index] = (nlist[index] + newValue) % 26 
     index = index + 1 
    return nlist 

def string2nlist(m): 
    characters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] 
    numbers = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25] 
    newList = [] 
    msgLen = len(m)   # var msgLen will be an integer of the length 

    index = 0    # iterate through message length in while loop 
    while index < msgLen: 
     letter = m[index] # iterate through message m 
     i = 0 
     while i < 26: 
      if letter == characters[i]: 
       newList.append(numbers[i]) 
      i = i + 1 
     index = index + 1 
    return newList 

    def nlist2string(nlist): 
    characters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] 
    numbers = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25] 
    newList = [] 
    nListLen = len(nlist) 

    index = 0 
    while index < nListLen: 
     num = nlist[index] 
     newNum = num % 26 
     i = 0 
     while i < 26: 
      num1 = newNum 
      num2 = numbers[i] 
      if (num1 == num2): 
      newList.append(characters[i]) 
     i = i + 1 
    index = index + 1 
    return newList 


    def wordList(filename): 

    fileObject = open(filename, "r+")      
    wordsList = fileObject.readlines() 
    return wordsList 


    def shift_computePlaintext(wlist, c): 

    index = 0 
    while index < 26: 
     newCipher = shift_encrypt(index, c) 
     print 'The new cipher text is: ', newCipher 
     wordlistLen = len(wlist) 
     i = 0 
     while i < wordlistLen: 
      print wlist[i] 
      if newCipher == wlist[i]: 
       return newCipher 
      else: 
       print 'Word not found.' 
      i = i + 1 
     index = index + 1  

    print 'Take Ciphertext and Find Plaintext from Wordlist Function: \n' 
    list = wordList('test.txt') 
    print list 
    plainText = shift_computePlaintext(list, 'vium') 
    print 'The plaintext was found in the wordlist: ', plainText 

當偏移量= 18,密文=名稱這是我的單詞表一個詞,但它永遠不會計算爲True。感謝您提前提供任何幫助!

+1

嘗試打印'repr(x)'而不是'x'。這樣可以更容易看到額外的''\ n''或其他空白字符,並區分'2'和'2',以及所有其他您正在討論的內容。 – abarnert

+0

同時,你可以給我們'test.txt'的內容,並修正縮進,幷包括一個完整的示例(所有這些函數'shift_encrypt'調用),所以我們可以真正運行你的代碼並進行調試嗎? – abarnert

+1

作爲一個方面說明,調用一個變量'list'是個壞主意,因爲這是內建'list'類型的名稱,您將無法再訪問它。 – abarnert

回答

5

很難確保用我們至今的資料,但這裏有一個猜測:

wordsList = fileObject.readlines() 

這將字符串list返回你保存下來,如換行:

['hello\n', 'my\n', 'name\n', 'is\n', 'jesi\n'] 

所以,裏面shift_computePlaintext,當你遍歷wlist尋找一些解密的'vium'匹配,你正在尋找一個匹配'name',其中沒有一個匹配的字符串,包括'name\n'

換句話說,正是你懷疑的。

有幾種方法來解決這個問題,但最明顯的是使用wlist[i].strip(),而不是wlist[i],或者使用類似wordsList = [line.strip() for line in fileObject],而不是wordsList = fileObject.readlines()剝離擺在首位的一切。


一些旁註:

有幾乎從來沒有一個很好的理由罵readlines()。這將返回可以迭代的行列表...但文件對象本身已經是可迭代的迭代行。如果你真的需要確保它是一個列表而不是其他類型的迭代,或者爲以後創建一個單獨的副本,或者其他任何東西,只需在其上調用list,就像你使用其他迭代器一樣。

你應該幾乎從來不寫這樣的循環:

index = 0 
while index < 26: 
    # ... 
    index = index + 1 

相反,只是這樣做:

for index in range(26): 

它更容易閱讀,很難得到錯誤的(微妙的off-by-一個錯誤是你一生中要做的一半令人沮喪的調試的原因)等等。

如果你正在循環一個集合的長度,甚至不要這樣做。取而代之的是:

wordlistLen = len(wlist) 
i = 0 
while i < wordlistLen: 
    # ... 
    word = wlist[i] 
    # ... 
    i = i + 1 

...只是這樣做:

for word in wlist: 

...或者,如果你既需要iword(你偶爾做):

for i, word in enumerate(wlist): 

同時,如果你循環一個集合的唯一原因是檢查它的每個值,你甚至不需要它。取而代之的是:

wordlistLen = len(wlist) 
while i < wordlistLen: 
    print wlist[i] 
    if newCipher == wlist[i]: 
     return newCipher 
    else: 
     print 'Word not found.' 
    i = i + 1 

...只是這樣做:

if newCipher in wlist: 
    return newCipher 
else: 
    print 'Word not found.' 

在這裏,你實際上已經得到了那些微妙的錯誤之一:您打印「一詞沒有發現」了個遍,而不是僅如果未找到,則最後打印一次。

+2

+1爲教育學。 – DSM

+0

@DSM我同意!同樣結構化的答案可以在[codereview.SE]找到。 – Adam

+0

我有這樣的感覺。謝謝您的幫助!我使用了wlist [i] .strip(),並且能夠找到匹配的單詞。太感謝了!! – jesiKat