将值从循环返回到print()仅一次

时间:2018-08-16 04:05:55

标签: python python-3.x loops iteration string-length

当尝试检索第二种选择的解密密码时,无论输入的网站是否正确,我都无法阻止程序打印Does Not Compute。如果不正确,它将打印两次,因此使我相信它正在打印for i in the range(len(passwords)),即2。

如何获取仅打印密码或Does Not Compute一次而不再次进行迭代的密码?我正在尝试检查输入的内容是否等于网站,但它仍然打印两次迭代。

import csv
import sys

# The password list - We start with it populated for testing purposes
passwords = [["yahoo", "XqffoZeo"], ["google", "CoIushujSetu"]]
# The password file name to store the passwords to
passwordFileName = "samplePasswordFile"
# The encryption key for the caesar cypher
encryptionKey = 16
# Caesar Cypher Encryption
def passwordEncrypt(unencryptedMessage, key):
    # We will start with an empty string as our encryptedMessage
    encryptedMessage = ""
    # For each symbol in the unencryptedMessage we will add an encrypted symbol into the encryptedMessage
    for symbol in unencryptedMessage:
        if symbol.isalpha():
            num = ord(symbol)
            num += key
            if symbol.isupper():
                if num > ord("Z"):
                    num -= 26
                elif num < ord("A"):
                    num += 26
            elif symbol.islower():
                if num > ord("z"):
                    num -= 26
                elif num < ord("a"):
                    num += 26
            encryptedMessage += chr(num)
        else:
            encryptedMessage += symbol
    return encryptedMessage


def loadPasswordFile(fileName):
    with open(fileName, newline="") as csvfile:
        passwordreader = csv.reader(csvfile)
        passwordList = list(passwordreader)
    return passwordList


def savePasswordFile(passwordList, fileName):
    with open(fileName, "w+", newline="") as csvfile:
        passwordwriter = csv.writer(csvfile)
        passwordwriter.writerows(passwordList)


prompt_msg = """
What would you like to do:
 1. Open password file
 2. Lookup a password
 3. Add a password
 4. Save password file
 5. Print the encrypted password list (for testing)
 6. Quit program
Please enter a number (1-4)
"""

while True:
    print(prompt_msg)
    choice = input()

    if choice == "1":  # Load the password list from a file
        passwords = loadPasswordFile(passwordFileName)

    elif choice == "2":  # Lookup at password
        print("Which website do you want to lookup the password for?")
        for keyvalue in passwords:
            print(keyvalue[0])
        print("----")
        passwordToLookup = input()
        for i in range(len(passwords)):
            print(f"i={i}, store_info={passwords[i]}, website={passwords[i][0]}")
            if passwordToLookup == passwords[i][0]:
                password = passwordEncrypt(passwords[i][1], -(encryptionKey))
                print(f"=> The password is {password}.")
            else:
                print("=> Does not compute!")

    elif choice == "3":
        print("What website is this password for?")
        website = input()
        print("What is the password?")
        unencryptedPassword = input()
        unencryptedPassword = passwordEncrypt(unencryptedPassword, encryptionKey)
        newList = [website, unencryptedPassword]
        passwords.append(newList)
        print("Your password has been saved.")

    elif choice == "4":  # Save the passwords to a file
        savePasswordFile(passwords, passwordFileName)

    elif choice == "5":  # print out the password list
        for keyvalue in passwords:
            print(", ".join(keyvalue))

    elif choice == "6":  # quit our program
        sys.exit()

    print()
    print()
    ####### YOUR CODE HERE ######
    # You will need to find the password that matches the website
    # You will then need to decrypt the password
    #
    # 1. Create a loop that goes through each item in the password list
    #  You can consult the reading on lists in Week 5 for ways to loop through a list
    #
    # 2. Check if the name is found.  To index a list of lists you use 2 square backet sets
    #   So passwords[0][1] would mean for the first item in the list get it's 2nd item (remember, lists start at 0)
    #   So this would be 'XqffoZeo' in the password list given what is predefined at the top of the page.
    #   If you created a loop using the syntax described in step 1, then i is your 'iterator' in the list so you
    #   will want to use i in your first set of brackets.
    #
    # 3. If the name is found then decrypt it.  Decrypting is that exact reverse operation from encrypting.  Take a look at the
    # caesar cypher lecture as a reference.  You do not need to write your own decryption function, you can reuse passwordEncrypt
    #
    #  Write the above one step at a time.  By this I mean, write step 1...  but in your loop print out every item in the list
    #  for testing purposes.  Then write step 2, and print out the password but not decrypted.  Then write step 3.  This way
    #  you can test easily along the way.
    #

2 个答案:

答案 0 :(得分:1)

似乎您只想在所有存储的密码都不匹配输入的情况下才打印does not compute;但实际上,您正在为该消息打印不匹配的EACH密码(即使其他密码确实匹配)。

我已经修改了您的循环,使其在找到匹配项时中断,并且仅在未找到匹配项时才打印消息(通过在for循环中添加else子句,该子句仅在循环匹配时执行一直到最后。)

    passwordToLookup = input()
    for i in range(len(passwords)):
        if passwordToLookup == passwords[i][0]:
            webSite = passwordEncrypt(passwords[i][1],-(encryptionKey))
            print()
            print('The password is ' + webSite+'.')
            print(i)
            print(passwords[i])
            print(passwords[i][0])
            break
    else:
        # if we got to the end of the loop, no passwords matched
        print('Does not compute!')

答案 1 :(得分:0)

首先,我可以自由地重新格式化并改进您的代码以使其看起来更好。

  • 提示的多行字符串
  • 用于打印变量的F字符串(Python 3.4及更高版本)
  • 使用新的black模块进行格式化

您的问题是您遍历所有存储的网站

    for i in range(len(passwords)):
        if passwordToLookup == passwords[i][0]:
            ...
        else:
            ...

实际上您应该做的是

  1. 检查网站是否存在于当前列表中
  2. 返回找到的解密密码,否则返回Cannot computer

做1.的最好方法是:

  • 将密码的元组转换为字典:passwords = {"yahoo":"XqffoZeo", "google":"CoIushujSetu"}
  • 检查网站是否为键之一:if website in passwords.keys(): ...
  • 相应地更新其余代码(因为密码列表不是元组列表而是字典)

或更简单地说:提取密码时,只需将元组列表转换为字典即可:

elif choice == "2":  # Lookup at password
    print("Which website do you want to lookup the password for?")
    for keyvalue in passwords:
        print(keyvalue[0])
    print("----")
    passwordToLookup = input()
    dict_passwords = dict(passwords)
    if passwordToLookup in dict_passwords:
        encrypted = dict_passwords[passwordToLookup]
        password = passwordEncrypt(encrypted, -(encryptionKey))
        print(f"=> The password is {password}.")
    else:
        print("=> Does not compute!")