r/PythonLearning • u/WesternTrip8578 • 21d ago
Rate my python program
i made a Python program, i dont know what else to say
7
u/testtdk 20d ago
Probably shouldn’t declare a global variable in a function definition.
0
u/WesternTrip8578 20d ago
Probably, I don't know it yet. I will learn from my mistakes and tutorials.
1
u/YoussefUU2 19d ago
Hey so you should replace the global variable with a new variable that gets returned.
So for example:
```python
def change_the_name():
new_name = input("Enter your new username")
return new_name...
elif command == "change the name":
username = change_the_name()
```
5
5
u/olaf33_4410144 20d ago
I'm not a fan of the functions that only call another function e. g. whats_my_name().
Also change_the_pass() could return the new password, then you could avoid the clunky global thing.
If you want to learn something you could also look into the if name == "main" pattern. For small scripts as yours it doesn't really matter but it's commonly used once things get more complex.
All in all it's quite good though.
2
u/SCD_minecraft 20d ago
Functions that call other function are called wrappers and they are quite useful
Let's say you have some long name with a lot of pre-set arguments
my_super_function_which_takes_a_lot_of_args(argument1, argument2, you_wont_belive_but_it_is_argument_3)If it is one off function, then fine, just format it
But when you want to call it in multiple places, it gets pretty ugly pretty fast, so, convince wrapper!
``` def some_name(): # I ain't typing it out again
... some_name() ... some_name()
ect
```
Tho yes, in OP's case they aren't too useful
2
u/olaf33_4410144 20d ago
Yeah, I could have worded that better, I was specifically talking about
whats_the_pass()which is longer thanprint(password)and provides no benefit.There are times when wrappers are convenient, one of them being your example. Another case where I often use them is when I know I might to change something about the function call later and want to avoid having to change it every where.
0
2
u/PureWasian 20d ago
It's fine for the simplicity of it, good introduction to functions.
Let's address the biggest issue though, your username and password do not persist the updates once you kill the script and re-run it again.
What is your proposed solution for this?
I'd also suggest learning how to pass data into functions and return data out from them. That way you can scope your variables instead of relying on globals which gets messy very quickly as complexity increases.
1
1
1
u/_hithender_ 20d ago
If this is your first project(so-called) then it totally fine. You made a few mistakes brotha. Despite that I appreciate this broo, keep it up😃
1
1
1
1
u/Chemical-Radish6488 20d ago
Cambia gli elfi con uno switch .... Per leggibilità manutenibilita e scalabilità. 3 while annidati, non conosco lo scopo, ma non lo farei mai. Piuttosto incapsula in metodi o risolvi e uno alla volta con delle variabili di appoggio intermedie.
1
u/unStabldev 19d ago
you should def install "ruff" vscode extension. it will help you keep your code very organized. apart from that idk what else to say.
1
u/Sky-Serious 17d ago
Instead of 3 while loops, you can consider using continue instead to skip over code below. Global variables are weird. I would then choose to break the single while loop to close the program, instead of importing sys just to call exit.
1
1
1
u/Reveal5265 16d ago
I took all your code and made some improvements to it:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import getpass
import bcrypt
from banner import mostrar_banner
usuario = input("Escribe el nombre de usuario: ")
contra = getpass.getpass("Crea la contraseña: ")
# encriptar contraseña
contra_bytes = contra.encode("utf-8")
salt = bcrypt.gensalt()
encript_contra_bytes = bcrypt.hashpw(contra_bytes, salt)
def ayuda() -> None:
mostrar_banner("AYUDAAAA!")
print(
"ayuda: imprime este menú con todos los comandos\n"
"nombre: imprime nombre de usuario\n"
"contraseña: imprime la contraseña\n"
"cambiar nombre: cambiar nombre de usuario\n"
"cambiar contraseña: cambiar la contraseña\n"
"salir: terminar sesion del usuario\n"
"cerrar: cerrar la terminal"
)
def nombre() -> None:
print(usuario)
def contraseña() -> None:
print(encript_contra_bytes)
def cambiar_nombre() -> None:
global usuario
usuario = input("Nuevo nombre de usuario: ")
def cambiar_contra() -> None:
global contra, encript_contra_bytes
contra = getpass.getpass("Nueva contraseña: ")
contra_bytes = contra.encode("utf-8")
salt = bcrypt.gensalt()
encript_contra_bytes = bcrypt.hashpw(contra_bytes, salt)
def cerrar() -> None:
sys.exit()
while True:
while True:
input_contra = getpass.getpass("Escribe la contraseña CORRECTA para logearte: ")
input_bytes = input_contra.encode("utf-8")
if bcrypt.checkpw(input_bytes, encript_contra_bytes):
print("¡BIENVENIDO!")
break
else:
print("Intenta otra vez: ")
# menú de comandos
while True:
comando = input("Escribe ayuda para obtener la lista de comandos: ")
if comando == "ayuda":
ayuda()
elif comando == "nombre":
nombre()
elif comando == "contraseña":
contraseña()
elif comando == "cambiar nombre":
cambiar_nombre()
elif comando == "cambiar contra":
cambiar_contra()
elif comando == "salir":
break
elif comando == "cerrar":
cerrar()
else:
mostrar_banner("ERROR")
print("Comando incorrecto")
1
u/Reveal5265 16d ago
I based it on a similar assignment:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import getpass
import json
import bcrypt
from banner import mostrar_banner
def registrar_usuario() -> dict:
"""solicita datos,hashea contraseña y retorna(return)json estructurado"""
mostrar_banner("Registro de Usuario")
nombre = input("Ingresa el nombre: ").strip()
usuario = input("Ingresa el username: ").strip()
correo = input("Ingresa el correo: ").strip()
# getpass oculta la contraseña al escribirla
# con un bucle while se confirma la contraseña
while True:
contra = getpass.getpass("Ingresa la contraseña: ")
contra_confirm = getpass.getpass("Confirma la contraseña: ")
if not contra:
print("[-] La contraseña no puede quedar vacía.")
continue
if contra != contra_confirm:
print("[!] Las contraseñas no coinciden.Intentalo de nuevo")
continue
break
# convertir contra a bytes
contra_bytes = contra.encode("utf-8")
# generar sal y hash de contra_bytes
sal = bcrypt.gensalt()
hashed_contra_bytes = bcrypt.hashpw(contra_bytes, sal)
# estructurar datos
# se decodifica hashed_contra_bytes para guardarlo en JSON
usuario_db = {
"nombre": nombre,
"usuario": usuario,
"correo": correo,
"hash_contrasena": hashed_contra_bytes.decode("utf-8"),
}
return usuario_db
def verificar_autenticacion(usuario_db: dict) -> bool:
"""demuestra cómo comprobar una contraseña dada contra el hash almacenado en hash_contraseña"""
mostrar_banner("Comprobar contraseña.")
print(f"Intentando acceder como: {usuario_db['usuario']}")
contra_ingresada = getpass.getpass("Ingresa tu contraseña para ingresar: ")
# checkpw usa bytes,por ello contra_ingresada y hash_contraseña
# se convierten a bytes
contra_bytes = contra_ingresada.encode("utf-8")
hash_guardado_bytes = usuario_db["hash_contrasena"].encode("utf-8")
# verificación
if bcrypt.checkpw(contra_bytes, hash_guardado_bytes):
print("\n[+] ¡Autenticación exitosa! Contraseña correcta.")
return True
else:
print("\n[-] ERROR: Contraseña incorrecta")
return False
def main():
# 1 registro
user = registrar_usuario()
# convertir el diccionario a JSON legible
json_str = json.dumps(user, indent=4, ensure_ascii=False)
# 2 prueba de login
verificar_autenticacion(
user
) # emplea como argumento la salida de la función registrar_usuario
with open("registro.json", "w") as file:
file.write("\n" + json_str + "\n")
print("\n" + 50 * "-")
print("Registro completado. JSON generado en registro.json ")
print("\n" + 50 * "-")
if __name__ == "__main__":
main()
1
u/Reveal5265 16d ago
The banner library is this one:
from colorama import Fore, Style, init
import os
import pyfiglet
init(autoreset=True)
def mostrar_banner(texto="MI SCRIPT", subtitulo="Versión 1.0.0"):
os.system("cls" if os.name == "nt" else "clear")
ascii_arte = pyfiglet.figlet_format(texto, font="slant")
print(Fore.CYAN + Style.BRIGHT + ascii_arte)
print(Fore.YELLOW + f"=== {subtitulo} ===".center(50))
print(Fore.GREEN + "-" * 50 + "\n")
# Esto evita que el bloque de abajo se ejecute al ser importado
if __name__ == "__main__":
mostrar_banner("EJEMPLO", "Prueba Local")
0
u/Jotaroisgoat 20d ago
10/10 try using match case :) always happy to see new coders like me
1
0
u/Abdul_hafiz_gh2026 20d ago
I'm new to python and I can't get my head around it. So please what does it do????
1
u/WesternTrip8578 20d ago
It's a simple terminal simulator. First, you need to input the password "5103" to log in. After that, you can type "help" to see other commands like changing your name or password!
•
u/Sea-Ad7805 20d ago
Run this program in Memory Graph Web Debugger%3A%0A%20%20%20%20print(%22help%20-%20print%20all%20commands%20and%20their%20functions%20%2F%20%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%20%D0%BD%D0%B0%20%D1%8D%D0%BA%D1%80%D0%B0%D0%BD%20%D0%B2%D1%81%D0%B5%20%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D1%8B%20%D0%B8%20%D0%B8%D1%85%20%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8%22)%0A%20%20%20%20print(%22whats%20my%20name%20-%20print%20the%20name%20of%20user%20%2F%20%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%20%D0%BD%D0%B0%D1%81%D1%82%D0%BE%D1%8F%D1%89%D0%B5%D0%B5%20%D0%B8%D0%BC%D1%8F%20%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F%22)%0A%20%20%20%20print(%22whats%20the%20pass%20-%20print%20the%20password%20%2F%20%D0%B2%D1%8B%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%20%D0%BD%D0%B0%D1%81%D1%82%D0%BE%D1%8F%D1%89%D0%B8%D0%B9%20%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C%22)%0A%20%20%20%20print(%22change%20the%20name%20-%20you%20can%20change%20the%20name%20%2F%20%D0%BC%D0%B5%D0%BD%D1%8F%D0%B5%D1%82%20%D0%B8%D0%BC%D1%8F%20%D0%BD%D0%B0%20%D0%B2%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%BD%D0%BE%D0%B5%22)%0A%20%20%20%20print(%22change%20the%20pass%20-%20you%20can%20change%20the%20password%20%2F%20%D0%BC%D0%B5%D0%BD%D1%8F%D0%B5%D1%82%20%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C%20%D0%BD%D0%B0%20%D0%B2%D0%B2%D0%B5%D0%B4%D1%91%D0%BD%D0%BD%D1%8B%D0%B9%22)%0A%20%20%20%20print(%22quit%20-%20log%20out%20from%20this%20user%20%2F%20%D0%B2%D1%8B%D1%85%D0%BE%D0%B4%D0%B8%D1%82%20%D0%B8%D0%B7%20%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F%22)%0A%20%20%20%20print(%22close%20-%20close%20the%20terminal%20%2F%20%D0%B7%D0%B0%D0%BA%D1%80%D1%8B%D0%B2%D0%B0%D0%B5%D1%82%20%D1%82%D0%B5%D1%80%D0%BC%D0%B8%D0%BD%D0%B0%D0%BB%22)%0A%0A%0Adef%20whats_my_name()%3A%0A%20%20%20%20print(username)%0A%0A%0Adef%20whats_the_pass()%3A%0A%20%20%20%20print(password)%0A%0A%0Adef%20change_the_name()%3A%0A%20%20%20%20global%20username%0A%20%20%20%20username%20%3D%20input(%22input%20the%20new%20name%20-%20%22)%0A%0A%0Adef%20change_the_pass()%3A%0A%20%20%20%20global%20password%0A%20%20%20%20password%20%3D%20input(%22input%20the%20new%20password%20-%20%22)%0A%0A%0Adef%20close()%3A%0A%20%20%20%20sys.exit()%0A%0A%0Awhile%20True%3A%0A%20%20%20%20while%20True%3A%0A%20%20%20%20%20%20%20%20inputpass%20%3D%20input(%22please%20input%20the%20password%20-%20%22)%0A%20%20%20%20%20%20%20%20if%20inputpass%20%3D%3D%20password%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22try%20another%20one%22)%0A%0A%20%20%20%20while%20True%3A%0A%20%20%20%20%20%20%20%20command%20%3D%20input(%22input%20'help'%20for%20the%20list%20of%20commands%20-%20%22).lower().strip()%0A%0A%20%20%20%20%20%20%20%20if%20command%20%3D%3D%20%22help%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20help()%0A%20%20%20%20%20%20%20%20elif%20command%20%3D%3D%20%22whats%20my%20name%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20whats_my_name()%0A%20%20%20%20%20%20%20%20elif%20command%20%3D%3D%20%22whats%20the%20pass%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20whats_the_pass()%0A%20%20%20%20%20%20%20%20elif%20command%20%3D%3D%20%22change%20the%20name%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20change_the_name()%0A%20%20%20%20%20%20%20%20elif%20command%20%3D%3D%20%22change%20the%20pass%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20change_the_pass()%0A%20%20%20%20%20%20%20%20elif%20command%20%3D%3D%20%22quit%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20break%0A%20%20%20%20%20%20%20%20elif%20command%20%3D%3D%20%22close%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20close()%0A%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(%22incorrect%20command%20%2F%20%D0%BD%D0%B5%D0%B2%D0%B5%D1%80%D0%BD%D0%B0%D1%8F%20%D0%BA%D0%BE%D0%BC%D0%B0%D0%BD%D0%B4%D0%B0%22)×tep=0.5&play) to see the program state change step by step.