informatica:programacion:python:cursos:introduccion_programacion_python:funciones
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| informatica:programacion:python:cursos:introduccion_programacion_python:funciones [2023/04/18 16:30] – [Llamada a función] tempwin | informatica:programacion:python:cursos:introduccion_programacion_python:funciones [2023/04/19 10:15] (actual) – [Problema de las ocho reinas] tempwin | ||
|---|---|---|---|
| Línea 94: | Línea 94: | ||
| else: | else: | ||
| print(" | print(" | ||
| + | </ | ||
| + | |||
| + | Versión con excepciones (en lugar de devolver ' | ||
| + | |||
| + | <code python> | ||
| + | from math import sqrt | ||
| + | |||
| + | def segundo_grado(a: | ||
| + | ''' | ||
| + | Busca las raíces reales de una ecuación de segundo grado con la forma a*x**2 + b*x + c = 0 | ||
| + | En caso de no tener soluciones reales, causa excepción | ||
| + | ''' | ||
| + | d = b**2 - 4 * a * c | ||
| + | if d >= 0: | ||
| + | x1 = (-b + sqrt(d)) / (2 * a) | ||
| + | x2 = (-b - sqrt(d)) / (2 * a) | ||
| + | return x1, x2 | ||
| + | else: | ||
| + | raise ValueError(f" | ||
| + | </ | ||
| + | |||
| + | Uso: | ||
| + | |||
| + | < | ||
| + | Coeficiente a: 1 | ||
| + | Coeficiente b: 0 | ||
| + | Coeficiente c: 1 | ||
| + | |||
| + | AQUI ERROR | ||
| + | </ | ||
| + | |||
| + | Podemos capturar el error de la siguiente manera con '' | ||
| + | |||
| + | <code python> | ||
| + | a = float(input(" | ||
| + | b = float(input(" | ||
| + | c = float(input(" | ||
| + | |||
| + | try: | ||
| + | resultado = segundo_grado(a, | ||
| + | |||
| + | r, s = resultado | ||
| + | print(r, s) | ||
| + | |||
| + | except ValueError as error: | ||
| + | print(error) | ||
| + | </ | ||
| + | |||
| + | Cuando lo usamos: | ||
| + | |||
| + | < | ||
| + | Coeficiente a: 1 | ||
| + | Coeficiente b: 0 | ||
| + | Coeficiente c: 1 | ||
| + | La ecuación 1.0*x**2 + 0.0*x + 1.0 = 0 no tiene soluciones reales. | ||
| + | </ | ||
| + | |||
| + | ===== Paso de parámetros ===== | ||
| + | |||
| + | ==== Parámetros posicionales ==== | ||
| + | |||
| + | Van en el mismo orden que están definidos: | ||
| + | |||
| + | <code python> | ||
| + | segundo_grado(1, | ||
| + | </ | ||
| + | |||
| + | ==== Parámetros con nombre ==== | ||
| + | |||
| + | Se pueden indicar en cualquier orden especificando el nombre de cada uno: | ||
| + | |||
| + | <code python> | ||
| + | segundo_grado(b = 2, a = 1, c = -3) | ||
| + | </ | ||
| + | |||
| + | ==== Parámetros con valores por defecto ==== | ||
| + | |||
| + | Se pueden indicar valores por defecto para los parámetros, | ||
| + | |||
| + | <code python> | ||
| + | def calcular_impuesto(base, | ||
| + | return base * iva / 100.0 | ||
| + | </ | ||
| + | |||
| + | Uso: | ||
| + | |||
| + | <code python> | ||
| + | # Omitimos parámetro iva, así que toma un valor por defecto 21 | ||
| + | calcular_impuesto(1000) # 210.0 | ||
| + | |||
| + | # Indicamos explícitamente el valor del parámetro | ||
| + | calcular_impuesto(1000, | ||
| + | </ | ||
| + | |||
| + | ===== Funciones con un número variable de parámetros ===== | ||
| + | |||
| + | Las funciones pueden recibir parámetros variables: | ||
| + | |||
| + | * Si son posicionales (sin nombre), se recogen en una lista | ||
| + | * Si son con nombre, se recogen en un diccionario. | ||
| + | |||
| + | Con el asterisco ('' | ||
| + | |||
| + | <code python> | ||
| + | def calcular_promedio(*datos: | ||
| + | ''' | ||
| + | Calcula el promedio de varios datos de tipo numérico. | ||
| + | El número de datos puede ser variable | ||
| + | ''' | ||
| + | | ||
| + | # Primero comprobamos que hay datos. Si no hay, que devuelva ' | ||
| + | if len(datos) == 0: | ||
| + | return None | ||
| + | | ||
| + | # A continuación, | ||
| + | # vamos a ir sumando todo | ||
| + | suma = 0.0 | ||
| + | for d in datos: | ||
| + | suma += d | ||
| + | | ||
| + | # Después de recorrer los datos uno a uno, lo dividimos entre el número de datos y ahí | ||
| + | # tenemos el promedio | ||
| + | return suma / len(datos) | ||
| + | </ | ||
| + | |||
| + | Uso: | ||
| + | |||
| + | < | ||
| + | calcular_promedio(1, | ||
| + | |||
| + | calcular_promedio(5, | ||
| + | </ | ||
| + | |||
| + | Con dos asteriscos ('' | ||
| + | |||
| + | <code python> | ||
| + | def calcular_nota_final(**notas): | ||
| + | nota = 0.0 | ||
| + | if ' | ||
| + | nota = notas[' | ||
| + | if ' | ||
| + | nota = notas[' | ||
| + | return nota | ||
| + | </ | ||
| + | |||
| + | Uso: | ||
| + | |||
| + | < | ||
| + | calcular_nota_final(examen=7.5) # 7.5 | ||
| + | |||
| + | calcular_nota_final(examen=4, | ||
| + | </ | ||
| + | |||
| + | <code python> | ||
| + | def vale_todo(*args, | ||
| + | for d in args: | ||
| + | print(" | ||
| + | for k, v in kwargs.items(): | ||
| + | print(f" | ||
| + | </ | ||
| + | |||
| + | Uso: | ||
| + | |||
| + | < | ||
| + | vale_todo(" | ||
| + | |||
| + | # Argumento posicional: alpha | ||
| + | # Argumento posicional: bravo | ||
| + | # Argumento con nombre: c=charlie | ||
| + | # Argumento con nombre: d=delta | ||
| + | </ | ||
| + | |||
| + | Otro ejemplo: | ||
| + | |||
| + | <code python> | ||
| + | l = [" | ||
| + | d = {" | ||
| + | |||
| + | # Para desagregar la lista y el diccionario anteriores y pasárselos como | ||
| + | # argumentos variables a la función: | ||
| + | |||
| + | vale_todo(*l, | ||
| </ | </ | ||
| ===== Funciones anónimas en línea (lambda) ===== | ===== Funciones anónimas en línea (lambda) ===== | ||
| Línea 113: | Línea 295: | ||
| sorted(palabras) # [' | sorted(palabras) # [' | ||
| - | Se le puede pasar una función a ' | + | # Se le puede pasar una función a ' |
| sorted(palabras, | sorted(palabras, | ||
| def logitud_inv(s: | def logitud_inv(s: | ||
| - | return | + | return -len(s) |
| | | ||
| sorted(palabras, | sorted(palabras, | ||
| Línea 135: | Línea 317: | ||
| </ | </ | ||
| - | ===== Funciones que no retornan valor (procedimientos) | + | ===== Funciones que no retornan valor ===== |
| <code python> | <code python> | ||
| Línea 294: | Línea 476: | ||
| factorial(0) # 1 | factorial(0) # 1 | ||
| + | </ | ||
| + | |||
| + | ===== Ejemplos prácticos ===== | ||
| + | |||
| + | ==== Torres de Hanoi ==== | ||
| + | |||
| + | Ejemplo clásico de recursividad. | ||
| + | |||
| + | El juego consiste en pasar todos los discos desde el poste ocupado (es decir, el que posee la torre) a uno de los otros postes vacíos. Para realizar este objetivo, es necesario seguir tres simples reglas: | ||
| + | |||
| + | * Solo se puede mover un disco cada vez y para mover otro los demás tienen que estar en postes. | ||
| + | * Un disco de mayor tamaño no puede estar sobre uno más pequeño que él mismo. | ||
| + | * Solo se puede desplazar el disco que se encuentre arriba en cada poste. | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | La fórmula para encontrar el número de movimientos necesarios para transferir n discos desde un poste a otro es '' | ||
| + | </ | ||
| + | |||
| + | |||
| + | <code python> | ||
| + | def hanoi(n, origen=' | ||
| + | if n > 1: | ||
| + | hanoi(n - 1, origen, auxiliar, destino) | ||
| + | |||
| + | print(f" | ||
| + | |||
| + | if n > 1: | ||
| + | hanoi(n - 1, auxiliar, destino, origen) | ||
| + | | ||
| + | </ | ||
| + | |||
| + | ==== Problema de las ocho reinas ==== | ||
| + | |||
| + | El problema de las ocho reinas es un pasatiempo que consiste en poner ocho reinas en el tablero de ajedrez sin que se amenacen. | ||
| + | |||
| + | <WRAP center round info 60%> | ||
| + | El problema de las 8 reinas tiene 92 soluciones. | ||
| + | </ | ||
| + | |||
| + | |||
| + | https:// | ||
| + | |||
| + | <code python> | ||
| + | def mostrar_tablero(reinas): | ||
| + | # Dibujamos un tablero de ajedrez | ||
| + | for columna in reinas: | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | print(" | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | mostrar_tablero([1, | ||
| + | </ | ||
| + | |||
| + | Vamos ahora con la resolución del problema: | ||
| + | |||
| + | <code python> | ||
| + | contador_soluciones = 0 | ||
| + | |||
| + | def reinas(posiciones=[]): | ||
| + | global contador_soluciones # Indicamos que queremos acceder a una variable externa a la función | ||
| + | # Determinamos el número de fila donde colocar la reina | ||
| + | # simplemente contando los elementos ya posicionados | ||
| + | fila = len(posiciones) | ||
| + | # En esa fila, probamos a colocar una reina en cada una | ||
| + | # de las columnas | ||
| + | for columna in range(8): | ||
| + | # Comprobar si la columna está libre; si no lo está, | ||
| + | # saltamos a la siguiente columna | ||
| + | if columna in posiciones: | ||
| + | continue | ||
| + | # Comprobación de diagonales: para todas las filas anteriores, | ||
| + | # ver si no hay reina en diagonal | ||
| + | choque_diagonal = False | ||
| + | for f in range(fila): | ||
| + | if posiciones[f] + fila - f == columna or posiciones[f] - fila + f == columna: | ||
| + | choque_diagonal = True | ||
| + | break | ||
| + | # Si hemos encontrado una reina en alguna diagonal, | ||
| + | # saltamos ya a la siguiente columna | ||
| + | if choque_diagonal: | ||
| + | continue | ||
| + | # Si hemos llegado hasta aquí es porque no hay reinas en | ||
| + | # la vertical ni en las diagonales, así que colocamos una | ||
| + | # nueva reina en el tablero | ||
| + | posiciones.append(columna) | ||
| + | # Y procedemos a rellenar el resto del tablero recursivamente, | ||
| + | # salvo que estemos ya en la última fila. En este último caso, | ||
| + | # visualizamos el tablero con la solución | ||
| + | if len(posiciones) < 8: | ||
| + | reinas(posiciones) | ||
| + | else: | ||
| + | contador_soluciones += 1 | ||
| + | print(f" | ||
| + | mostrar_tablero(posiciones)) | ||
| + | # Después de todo esto, quitamos la reina que acabamos de colocar | ||
| + | # para seguir explorando soluciones | ||
| + | posiciones.pop() | ||
| + | | ||
| </ | </ | ||
informatica/programacion/python/cursos/introduccion_programacion_python/funciones.1681828207.txt.gz · Última modificación: por tempwin
