Browse files in Python

1

I'm trying to make part of a program in which you get the typical login screen or create an account. The create account part I have made, making the user's information is saved in an external file, however, at the time of doing the part of login I do not know how to go through the file already created and check if the Username and password that have been entered belong to a user already registered in the file or not.

def crearFichero(nombre):
    fichero=open(nombre, "a")
    fichero.close()

def escribirFichero(nombre, linea):
    fichero=open(nombre, "a")
    fichero.write(linea)
    fichero.close()

def leerFichero(nombre):
    fichero=open(nombre, "r")

    for linea in fichero:
        linea.split(",")

    fichero.close()

#-----------CREAR CUENTA E INICIAR SESIÓN------------

opcion=input("Indique la opción que desea realizar: \n1)Iniciar sesión\n2)Crear cuenta\n")


if(opcion=="1"):

   print("INICIO DE SESIÓN:")
   usuario_comprobar=input("Nombre usuario:")
   password_comprobar=input("Contraseña:")
   leerFichero("Usuarios")


elif(opcion=="2"):

   crearFichero("Usuarios.txt")

   print("CREAR CUENTA:")
   nombre_usuario=input("Introduzca el nombre de usuario que desea: ")
   password=input("Introduzca una constraseña: ")

   escribirFichero("Usuarios.txt", "\n" + "Usuario:{}  Contraseña:{}".format(nombre_usuario, password))
    
asked by Diego Martinez 30.07.2018 в 14:08
source

1 answer

3

As you are generating your file, users will store one for each line with the following format:

Usuario:Diego  Contraseña:12345
Usuario:Laura  Contraseña:abcdef
Usuario:Alejandro  Contraseña:879abc

It would be convenient to add the new line character to the end of the string, not the beginning as you do now, this causes a blank line at the beginning of the file that can unnecessarily make further work difficult.

To iterate over the lines of a file just iterate over it with a for as commented:

with open(ruta, "r") as fichero:
    for linea in fichero:
        # Procesar línea

Internally this is done by an iterator that calls the implementation of the function readline until it reaches the end of the file. Keep in mind that readline does not remove any blank space in the chain, which includes the end of line character ( \n , \r\n , \r ), so we must remove it if necessary , for example by str.strip("\r\n") or better str.rstrip("\r\n") .

With the above clear, comes the problem of obtaining the data of each line, it would possibly be simpler to use a csv format as commented @ abulafia, there are many alternatives. In your case you have several options to pair it, for example you can do the following:

  • Delete the new line character as commented. In your case a slicing that ignores the last character would also be worth, linea[:-1] .

  • Delete Usuario: of the string, for this we can use a simple slicing or slicing of the string: linea[8:-1] will get a new string from the original line discarding the first 8 characters and the last one in the chain.

     >>> "Usuario:Diego  Contraseña:12345\n"[8: -1]
     Diego  Contraseña:12345'
    
  • Apply str.split on the string resulting from the previous step using " Contraseña:" as a separator, this will return a result list from splitting the previous string by the substring " Contraseña:" :

    >>> "Diego  Contraseña:12345".split("  Contraseña:")'
    ["Diego", "12345"]
    

    You can index the list to obtain each data or simply unpack it:

    >>> usr, passw = "Diego  Contraseña:12345".split("  Contraseña:")'
    >>> usr
    'Diego'
    >>> passw
    '12345'
    

    Once this is done, it is enough to go line by line comparing what the user has entered.

That is, something like this:

def autentificar_usuario(ruta: str, usuario: str, password: str) -> bool:
    '''
    Retorna True si el usuario está en el archivo y
    la contraseña es correcta, False en caso contrario
    '''
    with open(ruta, "r") as fichero:
        for linea in fichero:
            nombre, contr = linea[8: -1].split("  Contraseña:", 1)
            if usuario == nombre and password == contr:
                return True
        return False

Now, the above is useful if you would like to validate user and password separately, list the user pairs: password of the file, etc. If you only want to know if that user with that password is in the file, it is simpler to generate the corresponding string for what is entered by the user and directly compare the lines:

from pathlib import Path


def guardar_usuario(ruta: str, usuario: str, password: str):
    line = gen_line(usuario, password)
    with open(ruta, "a") as fichero:
        fichero.write(line)

def autentificar_usuario(ruta: str, usuario: str, password: str) -> bool:
    line = gen_line(usuario, password)
    with open(ruta, "r") as fichero:
        for file_line in fichero:
            if line == file_line: 
                return True
        return False

def gen_line(usuario: str, password: str) -> str:
    line = "Usuario:{}  Contraseña:{}\n".format(usuario, password)
    return line


#-----------CREAR CUENTA E INICIAR SESIÖN------------

file = Path("Usuarios.txt")
file.touch(exist_ok=True)

opcion = input(("Indique la opción que desea realizar:\n"
                "1)Iniciar sesión\n"
                "2)Crear cuenta\n"
               ))

if opcion == "1":
    print("INICIO DE SESIÓN:")
    usuario = input("Nombre usuario: ")
    password = input("Contraseña: ")
    if autentificar_usuario(file, usuario, password):
        print("Autentificación exitosa")
    else:
        print("Lo siento, el usuario o contraseña no son correctos")

elif opcion == "2":
   print("CREAR CUENTA:")
   nombre_usuario = input("Introduzca el nombre de usuario que desea: ")
   password = input("Introduzca una contraseña: ")
   guardar_usuario(file, nombre_usuario, password)

Note that in your code you create the file only when you enter option 2, if the user tried to "log in" without having executed option 2 previously you would have an exception because the file does not exist. You must therefore create the file before, or check the existence of the file or handle the exception in the function in charge of validating.

  

The clause with allows to use the context manager, in this case it basically closes the file automatically safely at the output of the block, even when an exception occurs during the execution of the same.

    
answered by 30.07.2018 / 18:24
source