Читает только последнюю строку файла Python - PullRequest
0 голосов
/ 11 марта 2019

Я пытаюсь создать систему регистрации для базового текстового решения

Система регистрации работает нормально, но при попытке входа в систему она принимает имя пользователя и пароль только из последней строки внешнего файла, даже если введены правильные имя пользователя и пароль. Я не уверен, в чем проблема, поскольку принимается только LAST LINE файла. Спасибо за вашу помощь!

def loginSys():
    ("=========LOGIN=========")
    f = open("loginDetails.txt","r")
    for line in open("loginDetails.txt","r").readlines():
        loginInfoP1 = line.split()
    print("Player One, enter your details first!")
    correctDetailsP1 = 0
    while correctDetailsP1 == 0:
        usnmAttemptP1 = input("Enter your username\n")
        pswdAttemptP1 = input("Enter your password\n")
        if usnmAttemptP1 == loginInfoP1[0] and pswdAttemptP1 == loginInfoP1[1]:
            correctDetailsP1 += 1
            print("You have successfully logged on " + usnmAttemptP1 + "!")
        else:
            print("Either your username or password is incorrect! Please try again")
    f.close()  
    x = open("loginDetails.txt","r")
    for line in open("loginDetails.txt","r").readlines():
        loginInfoP2 = line.split()
        #print(loginInfoP2)
    print("Player Two, enter your details now!")
    correctDetailsP2 = 0
    while correctDetailsP2 == 0:
        usnmAttemptP2 = input("Enter your username\n")
        pswdAttemptP2 = input("Enter your password\n")
        if usnmAttemptP2 == loginInfoP2[0] and pswdAttemptP2 == loginInfoP2[1]:
            correctDetailsP2 += 1
            print("You have successfully logged on " + usnmAttemptP2 + "!")
        else:
            print("Either your username or password is incorrect! Please try again")
    x.close()
    startGame()

Спасибо

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

Здесь:

for line in open("loginDetails.txt","r").readlines():
    loginInfoP1 = line.split()
# code using loginInfoP1 here

вы перебираете содержимое вашего файла и перепривязываете loginInfoP1 на каждой итерации - поэтому очевидно, что после завершения цикла for loginInfoP1 содержит значения для последней строки.

То, что вы хотите здесь, это построить дикт из всех данных входа в систему (используя имя пользователя в качестве ключа):

accounts = {}
# NB : make sure we close the file after use
with open("loginDetails.txt") as f:
    # nb: files are iterable, no need to read the whole
    # file at once
    for line in f: 
        # make sure we don't have an empty line
        line = line.strip()
        if not line:
            continue
        username, passwd = line.split()
        accounts[username] = passwd

тогда вам просто нужно проверить диктовку:

    usnmAttemptP1 = input("Enter your username\n").strip()
    pswdAttemptP1 = input("Enter your password\n").strip()
    if  usnmAttemptP1 in accounts and accounts[usnmAttemptP1] == pswdAttemptP1:
        # ok

Обратите внимание, что ваш код входа в систему абсолютно одинаков для обоих игроков, поэтому вы можете выполнить рефакторинг в специальной функции. Кроме того, ваш поток выполнения неверен - функция входа не имеет смысла запускать игру, она должна только возвращать определенное значение (либо данные учетной записи пользователя, либо просто логическое значение, указывающее, что пользователь правильно вошел в систему) своему вызывающему и позволить вызывающему нести его. со следующим шагом:

def read_accounts():
    accounts = {}
    # NB : make sure we close the file after use
    with open("loginDetails.txt") as f:
        # nb: files are iterable, no need to read the whole
        # file at once
        for line in f: 
            # make sure we don't have an empty line
            line = line.strip()
            if not line:
                continue
            username, passwd = line.split()
            accounts[username] = passwd
    return accounts


def auth_user(accounts, prompt):
    print(prompt)
    max_attempts = 10 # let's not loop forever
    correctDetailsP1 = 0
    while correctDetailsP1 < max_attemps:
        usnmAttemptP1 = input("Enter your username\n")
        pswdAttemptP1 = input("Enter your password\n")
        if  usnmAttemptP1 in accounts and accounts[usnmAttemptP1] == pswdAttemptP1:

            correctDetailsP1 += 1
            print("You have successfully logged on " + usnmAttemptP1 + "!")
            return True
        else:
            print("Either your username or password is incorrect! Please try again")
    # failed
    return False



def main():
    accounts = read_accounts()
    for prompt in ("Player One, enter your details first!", "Player Two, enter your details now!"):
        if not auth_user(accounts, prompt):
            return False
     startGame() 

if __name__ == "__main__":
    main()            

В качестве примечания: я понимаю, что это не является критически важным программным обеспечением, но хранение незашифрованных паролей - очень плохая идея. Канонический способ - хранить зашифрованные пароли, а во время входа зашифровать пароль, предоставленный пользователем (с тем же алгоритмом, конечно), и сравнить его с сохраненным зашифрованным паролем.

0 голосов
/ 11 марта 2019

Посмотрите еще раз на то, что здесь происходит:

f = open("loginDetails.txt","r")
for line in open("loginDetails.txt","r").readlines():
    loginInfoP1 = line.split()

Вы открываете текстовый файл, а затем перебираете все его строки. Для каждой строки вы помещаете ее содержимое в loginInfoP1. Для каждой строки .

Это означает, что после цикла для содержимое loginInfoP1 будет фактически последнимповторяющаяся строка, которая является последней строкой файла.


Если строки следуют определенному порядку, то есть первая строка - учетные данные для игрока 1, а вторая строка - для игрока 2;затем вы можете вернуть генератор (yield) и выполнить итерации строк по требованию:

def get_login_information(file):
    with open(file, 'r') as fh:
        for line in fh:
            yield line.split()

def loginSys():
    login_information = get_login_information('loginDetails.txt')

    print("=========LOGIN=========")
    print("Player One, enter your details first!")

    loginInfoP1 = next(login_information) # <------

    correctDetailsP1 = 0
    while correctDetailsP1 == 0:
        usnmAttemptP1 = input("Enter your username\n")
        pswdAttemptP1 = input("Enter your password\n")
        if usnmAttemptP1 == loginInfoP1[0] and pswdAttemptP1 == loginInfoP1[1]:
            correctDetailsP1 += 1
            print("You have successfully logged on " + usnmAttemptP1 + "!")
        else:
            print("Either your username or password is incorrect! Please try again")

    print("Player Two, enter your details now!")

    loginInfoP2 = next(login_information) # <------

    correctDetailsP2 = 0
    while correctDetailsP2 == 0:
        usnmAttemptP2 = input("Enter your username\n")
        pswdAttemptP2 = input("Enter your password\n")
        if usnmAttemptP2 == loginInfoP2[0] and pswdAttemptP2 == loginInfoP2[1]:
            correctDetailsP2 += 1
            print("You have successfully logged on " + usnmAttemptP2 + "!")
        else:
            print("Either your username or password is incorrect! Please try again")

    startGame()
...