Definición de Funciones y Pasaje de Parámetros en Python

'''
1. Sistema de inicio de sesión y registro con bucle: opción 1 para iniciar sesión, opción 2 para registrarse, opción 0 para salir, otras entradas son inválidas
2. Los datos de usuario se almacenan en el archivo datos_usuarios.txt para mantener la persistencia
3. En el inicio de sesión, se valida la cuenta antes de pedir la contraseña. Tres intentos fallidos en la cuenta redirigen al registro. Tres intentos fallidos en contraseña cierran el sistema
4. Primer registro escribe en el archivo como "cuenta:contraseña", registros posteriores añaden "|cuenta:contraseña"
'''

# Obtener información de usuarios desde archivo
def obtener_usuarios():
usuarios = {}
with open('datos_usuarios.txt', 'r', encoding='utf-8') as archivo:
datos = archivo.read()
if datos:
pares = datos.split('|')
for par in pares:
cuenta, contrasena = par.split(':')
usuarios[cuenta] = contrasena
return usuarios

# Guardar información de usuario
def guardar_usuario(cuenta, contrasena):
usuarios = obtener_usuarios()
with open('datos_usuarios.txt', 'a', encoding='utf-8') as archivo:
if not usuarios:
info = cuenta + ":" + contrasena
else:
info = '|' + cuenta + ":" + contrasena
archivo.write(info)

# Función de registro
def registrar():
print('Página de registro')
usuarios = obtener_usuarios()
while True:
cuenta = input('Cuenta: ')
if cuenta in usuarios:
print('La cuenta ya existe')
continue
contrasena = input('Contraseña: ')
guardar_usuario(cuenta, contrasena)
return

# Función de inicio de sesión
def iniciar_sesion():
print('Página de inicio de sesión')
usuarios = obtener_usuarios()

# Validación de cuenta
intentos_cuenta = 0
while True:
if intentos_cuenta >= 3:
print('Error en cuenta 3 veces')
registrar()
return True
cuenta = input('Cuenta: ')
if cuenta not in usuarios:
intentos_cuenta += 1
else:
break

# Validación de contraseña
intentos_contrasena = 0
while True:
if intentos_contrasena >= 3:
print('Error en contraseña 3 veces')
return True
contrasena = input('Contraseña: ')
if contrasena != usuarios.get(cuenta):
print('Error en inicio de sesión')
intentos_contrasena += 1
else:
print('Inicio de sesión exitoso')
return

# Iniciar sistema
def iniciar():
print("¡Sistema iniciado!")

# Bucle principal del sistema
fin_sistema = False
while not fin_sistema:
opcion = input("""Ingrese la opción deseada:
0: Salir
1: Iniciar sesión
2: Registrarse
>>>: """)
if opcion.isdigit():
opcion = int(opcion)
if opcion == 0:
break
elif opcion == 1:
fin_sistema = iniciar_sesion()
elif opcion == 2:
registrar()
else:
print("Entrada inválida, intente de nuevo")

# Iniciar el sistema
iniciar()

Parámetros Formales y Argumentos Reales

# Parámetros formales: variables en la definición de la función
def funcion_datos(valor1, valor2, valor3):
print(valor1)
print(valor2)
print(valor3)
# Variables externas pueden usarse dentro
print(externo1)
print(externo2)
print(externo3)

# Argumentos reales: valores reales pasados a la función
# Pueden ser constantes, variables, expresiones o combinaciones

externo1 = 10
externo2 = 20
externo3 = 30

# funcion_datos(10, 20, 30)
# funcion_datos(externo1, externo2, externo3)
funcion_datos(externo1 + 5, externo2 * 2, externo3 / 3)

# Relación: al llamar la función, los argumentos reales se asignan a los parámetros formales
# Esta relación es temporal durante la llamada. Fuera de la función, los parámetros formales no existen

Tipos de Argumentos Reales


def procesar_datos(a, b, c):
print(a, b, c)

# Argumentos posicionales: deben seguir el orden, de izquierda a derecha
procesar_datos(10, 20, 30)
procesar_datos(30, 20, 10)

# Argumentos por palabra clave: especifican explícitamente el parámetro
procesar_datos(a=10, b=20, c=30)
procesar_datos(c=30, b=20, a=10)

# Uso combinado: posicionales deben ir primero, no se puede asignar dos veces al mismo parámetro
# procesar_datos(10, c=20, a=30) # Error: múltiples valores para 'a'

# Uso válido
procesar_datos(10, c=30, b=20)
procesar_datos(10, b=30, c=20)

def procesar_completo(a, b, c, d, e, f):
print(a, b, c, d, e, f)

procesar_completo(10, 20, 30, e=100, f=500, d=200)

Tipos de Parámetros Formales

Parámetros posicionales

# Parámetros posicionales: definidos en orden de izquierda a derecha
def funcion_posicional(a, b, c):
print(a, b, c)

# Pueden recibir valores por posición o por palabra clave
funcion_posicional(10, 20, 30)
funcion_posicional(a=10, b=20, c=30)

Parámetros con valores por defecto

# Parámetros con valor por defecto: ya tienen un valor asignado en la definición
def funcion_defecto(a=10, b=20):
print(a, b)
'''
Notas:
1. Si hay posicionales y por defecto, estos últimos deben ir al final
def funcion_mixta(a, b, c=10, d=20):
print(a, b, c, d)
2. Pueden recibir valores por posición, palabra clave o usar el valor por defecto
funcion_mixta(20, 30)
funcion_defecto(a=200, b=300)
funcion_defecta(100)
funcion_defecta(b=100)
3. El valor por defecto se fija en la definición, solo una vez
m=10
def foo(x, y=m):
print(x, y)
m=20
foo(1)  # Resultado: 1, 10
4. Usar tipos inmutables para valores por defecto
'''
# Parámetros posicionales deben recibir valores, los por defecto son opcionales
funcion_mixta(100, 200, d=1000)

Parámetros poiscionales variables

# Solo pueden recibir argumentos posicionales
def funcion_variable(a, b=10, *args):
print(a, b)
print(args)

# * recibe los argumentos posicionales excedentes como tupla
funcion_variable(1, 20, 100, 200)
funcion_variable(100)

# Desempaquetar colecciones
def recibir_variable(*args):
print(args)

# Colecciones simples: str, list, set, tuple
cadena = 'ab'
lista = [1, 2]
tupla = (1, 2)
conjunto = {1, 2}
recibir_variable(cadena)  # ('ab',)
recibir_variable(lista)  # ([1, 2],)
recibir_variable(tupla)  # ((1, 2),)
recibir_variable(conjunto)  # ({1, 2},)

# Desempaquetar con * en argumentos
recibir_variable(*cadena)
recibir_variable(*lista)
recibir_variable(*tupla)
recibir_variable(*conjunto)

# Desempaquetar lista
def recibir_lista(*args):
print(args)

datos = [1, 2, 3, 4, 5]
recibir_lista(datos)  # (datos,)
recibir_lista(*datos)  # (1, 2, 3, 4, 5)

Parámetros por palabra clave

# * actúa como separador, puede tener nombre (*args) o ser solo separador
# a: posicional
# b: por defecto
# c, e: palabra clave sin valor por defecto
# d: palabra clave con valor por defecto

# Parámetros después de * deben pasarse por palabra clave
def funcion_palabra(a, b=10, *, c, d=10, e):
print(a, b, c, d, e)

def solo_palabra(*, a, b=10, c):
print(a, b, c)
# solo_palabra(10, 20, 30)  # Error
solo_palabra(b=300, c=100, a=200)

# Parámetros de palabra clave variables
def funcion_kwargs(*, a, b=20, c, **kwargs):
print(a, b)
print(kwargs)

funcion_kwargs(d=40, e=50, a=10, c=30)

# ** en argumentos desempaqueta diccionarios
datos = {'nombre': 'Owen', 'edad': 18}
def procesar_kwargs(**kwargs):
print(kwargs)

procesar_kwargs(**datos)

datos_complejos = {
'k1': [1, 2, 3, 4, 5],
'k2': {"nombre":"Bob"}
}
procesar_kwargs(**datos_complejos)

# Desempaquetar lista con *
def procesar_lista(*args):
print(args)

lista_compleja = [1, [1, 2], {"nombre":"Bob"}]
procesar_lista(*lista_compleja)

Etiquetas: funciones Parámetros Python programación

Publicado el 6-16 16:43