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.