Funciones de Python

Aprende a escribir tus propias funciones en Python. Define y llama a funciones, pasa valores mediante parámetros, argumentos por palabra clave y valores predeterminados (por defecto), y devuelve resultados con return. Descubre a qué variables puede acceder una función y cuáles puede modificar, describe tus funciones con cadenas de documentación (docstrings) y divide un programa en funciones pequeñas con nombres claros que construyas y pruebes una a una.

PrincipianteUnidad 4 de 10 del curso Curso de Introducción a la programación con Python

Lo que aprenderás

  1. Escribe una función con def, ejecútala mediante una llamada y sigue el orden en que Python ejecuta un programa que contiene funciones.
    • Define una función y llámala
      Escribe la cabecera de una función y un cuerpo con sangría, elige un nombre claro y ejecuta la función llamándola con paréntesis.
    • Sigue el flujo de ejecución
      Sigue el orden en que Python ejecuta las sentencias cuando unas funciones llaman a otras y predice la salida de un programa a partir de ese orden.
  2. Usa parámetros y argumentos para dar a una función los valores con los que trabaja, asociados por posición, por nombre o mediante valores predeterminados.
    • Usa parámetros y argumentos posicionales
      Añade parámetros a la cabecera de una función, pasa los argumentos correspondientes en una llamada e interpreta los errores que produce un número incorrecto de argumentos.
    • Llama a funciones con argumentos por palabra clave
      Pasa argumentos por el nombre del parámetro, combina argumentos posicionales y por palabra clave en el orden correcto y corrige los errores que causan las combinaciones incorrectas.
    • Asigna valores predeterminados a los parámetros
      Haz que los parámetros sean opcionales mediante valores predeterminados, ordena correctamente los parámetros obligatorios y opcionales e identifica cuándo se crea un valor predeterminado.
  3. Usa return para devolver un valor al código que llamó a una función, distingue entre devolver y mostrar, y escribe funciones cuyos resultados puedan guardarse, comprobarse y combinarse.
    • Devuelve un valor y úsalo
      Termina una función con return, usa el valor devuelto en variables y expresiones y comprende por qué devolver un valor es distinto de mostrarlo.
    • Devuelve valores desde distintas rutas de ejecución y combina resultados
      Escribe funciones con varias sentencias return, devuelve True o False, retorna de forma anticipada desde un bucle, devuelve dos valores y pasa el resultado de una función a otra.
  4. Predice a qué variables puede acceder una función y cuáles puede modificar, pasa datos mediante parámetros y valores de retorno y usa global solo cuando sea realmente necesario.
    • Trabaja con variables locales y parámetros
      Explica por qué las variables creadas dentro de una función solo existen durante su llamada, cómo encuentra Python un nombre y por qué reasignar un parámetro no modifica la variable del código que realiza la llamada.
    • Usa las variables globales con cuidado
      Lee valores globales de forma segura, comprende el error que causa asignar un valor a un nombre global, usa correctamente la sentencia global y da preferencia a los parámetros y valores de retorno.
  5. Describe funciones con cadenas de documentación, divide un problema en funciones pequeñas con nombres claros y construye y comprueba un programa función por función.
    • Documenta funciones con cadenas de documentación
      Escribe cadenas de documentación de una y varias líneas que sigan las convenciones habituales y consúltalas con help().
    • Descompón un problema en funciones
      Descompón una tarea en pasos, convierte cada paso en una función con entradas y salidas claras y organiza el programa en torno a una función main.
    • Construye y comprueba un programa función por función
      Desarrolla un programa en pasos pequeños, prueba cada función con entradas cuyos resultados conozcas y usa trazas de excepciones y salidas temporales para detectar errores de programación (bugs) dentro de las funciones.

Guía de estudio de Funciones en Python

5 capítulos

1

Define y llama a tus propias funciones

Una función da nombre a una parte útil del código para que puedas ejecutarla cuando necesites esa tarea. Escribir la definición y realizar una llamada son acciones distintas, y esa diferencia explica por qué algunos programas terminan sin mostrar nada. Escribirás definiciones con la sangría correcta, elegirás nombres legibles y seguirás la ejecución cuando una función llame a otra y después vuelva al código que la llamó.

1.1 Define una función y llámala

Una función es un bloque de código con nombre que realiza una tarea. Las funciones incorporadas como print() e input() ya te ofrecen tareas útiles que puedes llamar; def te permite crear las tuyas. Un buen nombre convierte varias líneas de trabajo en una llamada que indica qué quieres hacer.

Escribe la cabecera y el cuerpo
def greet():
    print("Hello!")
    print("Welcome to Python.")

greet()
greet()

La cabecera empieza con def, seguido del nombre, los paréntesis y los dos puntos. Las líneas con sangría forman el cuerpo. Usa cuatro espacios por cada nivel de sangría. Las líneas greet() sin sangría están fuera de la función, así que son llamadas del programa principal.

Cuando Python llega a la definición, crea la función y le da el nombre greet. Todavía no muestra ninguno de los mensajes. La primera llamada empieza en la primera línea del cuerpo y muestra «Hello!» seguido de «Welcome to Python.». La segunda vuelve a iniciar el cuerpo y muestra las mismas dos líneas. Hay cuatro líneas de salida en total.

Un nombre y una llamada son distintos

Los paréntesis de greet() lo convierten en una llamada, aunque esta función no necesite entradas. Una línea que solo contiene greet hace referencia a la función y no ejecuta nada. print(greet) muestra una descripción del objeto de función, incluida una dirección de memoria; no ejecuta el saludo.

Python debe haber ejecutado una definición antes de que una llamada use su nombre. Si un archivo empieza con greet() y define greet después, la primera línea lanza NameError: name 'greet' is not defined. Coloca la definición antes de la llamada del nivel superior.

Elige nombres que expliquen la tarea

Usa palabras en minúsculas unidas por guiones bajos, como print_receipt o convert_to_miles. Los nombres pueden contener letras, dígitos y guiones bajos, pero no pueden empezar por un dígito ni ser una palabra reservada como return. Los nombres distinguen entre mayúsculas y minúsculas: greet y Greet son nombres distintos.

Mantén disponibles los nombres incorporados. Después de input = "yes", el nombre input hace referencia a texto, así que input("Name? ") lanza TypeError: 'str' object is not callable. Llamar answer a la variable mantiene accesible la función incorporada.

Corrige primero la estructura

La ausencia de los dos puntos en la cabecera produce SyntaxError: expected ':'. Un cuerpo vacío o sin sangría produce un IndentationError. Una función que aún se está planificando necesita una sentencia; pass es un marcador provisional que no hace nada:

def print_receipt():
    pass

print_receipt()

Este programa se ejecuta sin salida. La llamada llega a pass y después al final del cuerpo. Sustituye el marcador provisional por la tarea real cuando vayas a implementarla. Si una línea debía pertenecer al cuerpo pero se ejecuta en un momento incorrecto, comprueba su sangría antes de modificar la llamada.

Puntos clave

  • Usa def name(): y un cuerpo con sangría para definir una función.
  • Una definición crea la función; los paréntesis forman una llamada que la ejecuta.
  • Ejecuta la definición de una función antes de realizar una llamada que necesite su nombre.
  • Elige nombres descriptivos en minúsculas con guiones bajos y evita los nombres incorporados.
  • Usa pass cuando una función en preparación necesite un cuerpo provisional válido.

1.2 Sigue el flujo de ejecución

Un programa con funciones no ejecuta todos los cuerpos en el orden en que aparecen en la página. Una llamada cambia el flujo de ejecución: Python entra en la función llamada, termina su tarea y reanuda el código que la llamó justo después de esa llamada.

Sigue una llamada dentro de otra
def line():
    print("----------")

def banner():
    line()
    print("  REPORT")
    line()

print("Start")
banner()
print("End")

Primero, Python define line y banner. No se ejecuta ninguno de los cuerpos. La siguiente sentencia muestra «Start». La llamada a banner() entra en su cuerpo, cuya primera sentencia llama a line().

Python entra ahora en line, muestra «----------» y llega al final. Vuelve a la siguiente sentencia de banner, que muestra « REPORT». La segunda llamada a line() muestra otra línea de guiones. Por último, termina banner, así que el programa principal se reanuda y muestra «End».

La salida es:

Start
----------
  REPORT
----------
End
Lleva un registro de las llamadas sin terminar

Mientras se ejecuta line, banner espera a que termine. El programa principal también espera a banner. Python registra estas llamadas sin terminar en la pila de llamadas. La llamada activa más interna termina primero, y cada código que realiza una llamada se reanuda en su siguiente sentencia.

Para seguir la ejecución en papel, numera las líneas del programa. Anota una línea del cuerpo solo cuando la ejecución llegue a ella mediante una llamada. En cada llamada, marca dónde se debe reanudar. Escribe la salida cuando se ejecute su print, conservando espacios y saltos de línea. Así separas la ruta que sigue el código de la salida que produce.

Define las funciones auxiliares antes de necesitarlas

La definición de una función auxiliar puede aparecer debajo de la definición de la función que la llama:

def show_report():
    draw_line()
    print("Ready")

def draw_line():
    print("====")

show_report()

Esto funciona porque ambas definiciones se han ejecutado antes de que la llamada final entre en show_report. Python busca draw_line cuando el cuerpo la llama realmente. Mover show_report() por encima de def draw_line(): haría que la llamada fallara al intentar usar la función auxiliar aún no definida.

Las llamadas repetidas empiezan de nuevo

Una llamada dentro de un bucle entra en el cuerpo en cada repetición:

for i in range(3):
    line()

Con la primera definición de line, esto muestra la línea de guiones tres veces. La función empieza en la primera sentencia de su cuerpo en cada llamada.

Si una llamada falla, Python muestra una traza de la excepción. Su última línea indica el tipo de error y el mensaje. Las entradas de llamadas anteriores van desde la llamada sin terminar más externa hasta la línea que falló. Leer primero el error final y después revisar la línea más interna y el código que la llamó te ayuda a localizar tanto la operación que falla como la ruta que le proporcionó los datos.

Puntos clave

  • Sigue las sentencias del cuerpo en el orden de las llamadas y registra la salida cuando se ejecute cada print.
  • La pila de llamadas registra las llamadas sin terminar y dónde se debe reanudar la ejecución.
  • Una función auxiliar puede definirse debajo de la función que la llama si su definición se ejecuta antes de la llamada.
  • Lee el error final de una traza de excepción y después revisa la línea que falla y el código que la llamó.
2

Pasa información a las funciones

Los parámetros permiten que una función trabaje con distintas entradas sin reescribir su cuerpo. El código que realiza la llamada proporciona argumentos, y Python vincula esos valores con los nombres de los parámetros antes de iniciar el cuerpo. Asociarás argumentos por posición y por nombre, combinarás correctamente estas formas y elegirás valores predeterminados para los casos habituales. También verás por qué un valor predeterminado se crea al ejecutar la definición y cómo afecta eso a una lista usada como valor predeterminado.

2.1 Usa parámetros y argumentos posicionales

Una función puede reutilizarse con distintas entradas cuando su cabecera da nombre a los valores que necesita. Estos nombres son parámetros. El código que realiza la llamada proporciona argumentos, que son los valores concretos usados en una llamada determinada.

Asocia valores a nombres
def rectangle_area(width, height):
    print("Area:", width * height)

rectangle_area(4, 2.5)
rectangle_area(3, 7)

Los parámetros son width y height. En la primera llamada, los argumentos son 4 y 2.5. Los argumentos posicionales se asocian de izquierda a derecha: width recibe 4 y height recibe 2,5. El cuerpo muestra «Area: 10.0». La siguiente llamada da valores nuevos a los mismos nombres de parámetros y muestra «Area: 21».

Cada parámetro actúa como una variable dentro de esa llamada. No necesitas asignar valores a width y height antes; la llamada los proporciona. Una función sin parámetros también necesita paréntesis vacíos tanto en su definición como en sus llamadas.

El orden puede cambiar el significado
def describe_pet(animal, name):
    print(name, "is a", animal)

describe_pet("cat", "Milo")
describe_pet("Milo", "cat")

La primera llamada muestra «Milo is a cat». La segunda muestra «cat is a Milo». Ambas llamadas son válidas en Python, así que ningún error señala el cambio de significado. Lee el orden de la cabecera antes de elegir argumentos posicionales, sobre todo cuando varios parámetros aceptan el mismo tipo de valor.

Los argumentos pueden ser expresiones

Python evalúa cada expresión de argumento antes de iniciar el cuerpo. Con side = 6, la llamada rectangle_area(side, side) pasa 6 dos veces y muestra «Area: 36». El nombre de la variable del código que realiza la llamada no tiene que coincidir con ninguno de los nombres de los parámetros. La llamada rectangle_area(side + 1, 2) pasa 7 y 2; no pasa el texto «side + 1».

Interpreta un error en el número de argumentos

Cada parámetro sin valor predeterminado necesita un argumento. Con la función de área anterior:

LlamadaQué falla
rectangle_area(4)Falta height.
rectangle_area(4, 2, 1)Se proporcionaron tres argumentos para dos parámetros.

La primera lanza TypeError: rectangle_area() missing 1 required positional argument: 'height'. La segunda lanza TypeError: rectangle_area() takes 2 positional arguments but 3 were given. Revisa la cabecera de la función indicada y después cuenta cómo la llamada ocupa sus parámetros.

Pasa el tipo de valor que necesita la tarea

Python no exige un tipo solo porque un parámetro se llame width. rectangle_area("4", 2) muestra «Area: 44» porque multiplicar texto por un entero repite ese texto. Como input() devuelve texto, convierte la entrada numérica antes de pasarla:

width = float(input("Width: "))
rectangle_area(width, 2)

Aquí, float() convierte el texto introducido en un número antes de que lo reciba la función de área.

Puntos clave

  • Un parámetro es un nombre de la cabecera; un argumento es un valor proporcionado por una llamada.
  • Los argumentos posicionales ocupan los parámetros de izquierda a derecha.
  • Python evalúa las expresiones de los argumentos antes de ejecutar el cuerpo de la función.
  • Cada parámetro obligatorio necesita un valor; la falta o el exceso de argumentos lanza TypeError.
  • Convierte la entrada numérica de texto a número antes de pasarla a un cálculo.

2.2 Llama a funciones con argumentos por palabra clave

Un argumento por palabra clave nombra en la llamada su parámetro de destino. Esto facilita la lectura de una llamada cuando varios valores podrían confundirse. Python asocia la palabra clave con el nombre de la cabecera en lugar de usar su posición.

Asocia por nombre
def describe_pet(animal, name):
    print(name, "is a", animal)

describe_pet(name="Milo", animal="cat")
describe_pet(animal="cat", name="Milo")

Ambas llamadas muestran «Milo is a cat». El orden de los argumentos por palabra clave puede cambiar porque cada valor indica el parámetro que ocupa. La misma idea hace que rectangle_area(width=4, height=2.5) sea legible sin comprobar qué dimensión iba primero.

Una palabra clave no es una variable nueva en el código que realiza la llamada. En describe_pet(name="Milo", animal="cat"), name= dirige «Milo» al parámetro. No asigna «Milo» a una variable del nivel superior llamada name. Escribe los argumentos por palabra clave sin espacios alrededor de =, siguiendo el estilo habitual de Python.

Combina argumentos posicionales y por palabra clave
describe_pet("cat", name="Milo")

El primer argumento ocupa animal por posición. La palabra clave ocupa name, así que cada parámetro recibe exactamente un valor. Los argumentos posicionales deben ir primero. La llamada describe_pet(name="Milo", "cat") se rechaza con SyntaxError: positional argument follows keyword argument.

Para revisar una llamada combinada, ocupa las posiciones de izquierda a derecha y después asocia las palabras clave. Comprueba que ninguna posición se ocupe dos veces y que no quede vacía ninguna obligatoria.

Corrige las palabras clave duplicadas o desconocidas
LlamadaDiagnóstico
describe_pet("cat", animal="dog")animal recibe tanto «cat» como «dog».
describe_pet(animal="cat", nmae="Milo")La cabecera no tiene ningún parámetro llamado nmae.

El duplicado lanza TypeError: describe_pet() got multiple values for argument 'animal'. El nombre mal escrito lanza TypeError: describe_pet() got an unexpected keyword argument 'nmae'. Compara los nombres carácter a carácter; las mayúsculas y minúsculas también importan. Cambiar el orden de los argumentos no corrige una asignación duplicada a un parámetro.

Reconoce las palabras clave en las funciones incorporadas
print("a", "b", "c", sep="-")
print("Loading", end="...")
print("done")

La primera línea muestra «a-b-c». sep proporciona el texto situado entre los valores mostrados. Las dos llamadas siguientes producen «Loading...done» en una línea: end sustituye el salto de línea habitual después de «Loading».

Algunas funciones incorporadas también aceptan argumentos por nombre; por ejemplo, round(3.14159, ndigits=2) da 3,14. Usa los nombres de parámetros documentados para la función que llamas. Una palabra descriptiva que inventes no se reconoce solo porque parezca adecuada para la tarea.

Puntos clave

  • Los argumentos por palabra clave se asocian con los nombres de los parámetros, así que su orden puede variar.
  • Coloca los argumentos posicionales antes de los argumentos por palabra clave.
  • Ocupa cada parámetro exactamente una vez y escribe cada palabra clave con exactitud.
  • Una palabra clave en una llamada dirige un valor; no asigna una variable del código que realiza la llamada.
  • En print, sep controla los separadores y end controla la terminación.

2.3 Asigna valores predeterminados a los parámetros

Un valor predeterminado permite que una llamada omita un argumento cuando una elección habitual resulta adecuada. Escribe el valor predeterminado junto a su parámetro en la cabecera. Proporcionar un argumento sustituye el valor predeterminado para esa llamada.

Haz que un parámetro sea opcional
def greet(name, greeting="Hello"):
    print(greeting + ",", name + "!")

greet("Ana")
greet("Ana", "Welcome")
greet("Ana", greeting="Hi")

La salida es «Hello, Ana!», «Welcome, Ana!» y «Hi, Ana!». name es obligatorio porque no tiene un valor predeterminado. Por tanto, greet() lanza un TypeError, aunque el otro parámetro sea opcional.

En estas cabeceras, los parámetros obligatorios van antes de los que tienen valores predeterminados. def greet(greeting="Hello", name): no es válido. Python informa de un error de sintaxis porque un parámetro sin valor predeterminado aparece después de uno que sí lo tiene. Mueve name antes de greeting para mantenerlo como obligatorio.

Cambia una opción
def order_coffee(size, shots=1, milk="none"):
    print(size, "coffee,", shots, "shot(s), milk:", milk)

order_coffee("large", milk="oat")

Esto muestra «large coffee, 1 shot(s), milk: oat». La palabra clave llega a milk mientras shots conserva 1. Una llamada posicional como order_coffee("medium", 2) modifica shots y deja milk en «none». La asociación posicional no se salta un parámetro opcional para llegar al siguiente.

Las funciones incorporadas también ofrecen valores predeterminados: una llamada normal a print() separa los valores con un espacio y termina con un salto de línea. round(3.7) da el número entero 4; round(3.14159, 2) solicita dos decimales y da 3,14.

Los valores predeterminados se crean al ejecutar la definición
rate = 0.05

def price_with_tax(price, tax_rate=rate):
    return price * (1 + tax_rate)

rate = 0.08
print(price_with_tax(100))
print(price_with_tax(100, rate))

El valor predeterminado guarda 0,05 cuando se ejecuta def. Cambiar rate después no modifica ese valor guardado. Las llamadas muestran «105.0» y «108.0»: solo la segunda proporciona explícitamente la nueva tasa.

Evita compartir una lista por accidente

Una lista contiene elementos, y append añade un elemento a esa misma lista. Con una lista como valor predeterminado, todas las llamadas que omiten el argumento la comparten:

def add_item(item, basket=[]):
    basket.append(item)
    print(basket)

add_item("apple")
add_item("pear")

Esto muestra ['apple'] y después ['apple', 'pear']. La lista predeterminada se creó una vez, no una vez por llamada. Para crear una lista nueva cada vez que se omita el argumento, usa None como señal:

def add_item(item, basket=None):
    if basket is None:
        basket = []
    basket.append(item)
    print(basket)

Ahora esas dos llamadas muestran ['apple'] y ['pear']. Una lista proporcionada explícitamente sigue usándose tal como se recibe. Describe los parámetros opcionales y sus valores predeterminados en la cadena de documentación para que quienes llamen a la función sepan qué valores se eligen al omitirlos.

Puntos clave

  • Un argumento opcional omitido usa su valor predeterminado; un argumento explícito lo sustituye.
  • Coloca los parámetros obligatorios antes de los que tienen valores predeterminados.
  • Usa una palabra clave para cambiar una opción posterior sin ocupar las posiciones opcionales anteriores.
  • Las expresiones de los valores predeterminados se evalúan una vez al ejecutar def.
  • Una lista mutable como valor predeterminado se comparte entre las llamadas que omiten el argumento.
  • Usa None y crea una lista en el cuerpo cuando cada argumento omitido necesite una lista nueva.
3

Devuelve resultados mediante valores de retorno

Un cálculo resulta más útil cuando su resultado puede alimentar otro cálculo, una condición o una salida en pantalla. La sentencia return lo hace posible al devolver un valor al código que realiza la llamada. Distinguirás entre devolver y mostrar, seguirás el primer return que se ejecute y comprobarás las rutas que podrían terminar sin un resultado útil. Después crearás funciones booleanas, terminarás búsquedas correctamente y combinarás los resultados de funciones pequeñas.

3.1 Devuelve un valor y úsalo

Una función puede dar al código que la llama un resultado que pueda usar. La sentencia return termina la llamada y devuelve su valor. En el punto de llamada, la llamada representa ese valor devuelto.

Guarda y combina resultados
def rectangle_area(width, height):
    return width * height

area = rectangle_area(4, 2.5)
print(area)
print(rectangle_area(3, 4) + rectangle_area(2, 5))

La primera llamada devuelve 10,0, que se asigna a area; el primer print lo muestra. En la última línea, las dos llamadas devuelven 12 y 10. Python suma esos resultados y muestra «22». La propia función no contiene ningún print, así que puede proporcionar tanto un resultado que se guarde como una parte de un cálculo mayor.

Un valor devuelto también puede comprobarse en una condición o pasarse a otra función. Esto separa la tarea de calcular de la decisión del código que realiza la llamada sobre cómo usar la respuesta.

Mostrar y devolver tienen tareas distintas
def double_print(n):
    print(n * 2)

result = double_print(5)
print(result)

La llamada muestra «10», pero ese número mostrado no se devuelve como resultado. double_print llega al final de su cuerpo, así que devuelve None. Por eso la última línea muestra «None».

OperaciónAdónde va el valor
print(value)Lo muestra para que una persona lo lea.
return valueLo envía al código que realiza la llamada para que el programa lo use.

double_print(5) + 1 primero muestra «10» y después lanza TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'. Sustituye el cuerpo por return n * 2 cuando el código que realiza la llamada necesite el doble del número. Una función destinada solo a producir un efecto, como mostrar un mensaje, puede devolver None de forma adecuada; estas funciones se denominan a veces funciones sin valor de retorno útil. Una función que devuelve un resultado útil se denomina a veces función con valor de retorno útil.

Detente en el primer return ejecutado
def to_fahrenheit(celsius):
    return celsius * 9 / 5 + 32
    print("Converted")

print(to_fahrenheit(20))

Esto muestra «68.0». Nunca se llega al print del cuerpo porque return ya ha terminado la llamada. Elimina esa sentencia inalcanzable o mueve una acción necesaria antes del retorno. La conversión devuelve números de coma flotante porque / produce un número de coma flotante. Las entradas 100 y -40 dan 212,0 y -40,0.

Un return sin expresión también termina una llamada y devuelve None. Toda llamada a función tiene un resultado, aunque no se haya proporcionado un valor útil.

Haz visibles los resultados en un archivo de programa

Una llamada aislada a rectangle_area(3, 4) calcula 12 y después descarta el resultado sin usar en un archivo. Usa print(rectangle_area(3, 4)) para mostrarlo o asígnalo a una variable. La consola interactiva muestra los resultados de las expresiones salvo None, así que una prueba correcta en la consola puede parecer distinta de ejecutar la misma línea en un archivo.

Puntos clave

  • return value termina la llamada y hace que esta represente ese valor.
  • Mostrar presenta un valor en pantalla; devolver lo pone a disposición del código que realiza la llamada.
  • Llegar al final del cuerpo o usar un return sin valor devuelve None.
  • Las sentencias posteriores a un return ejecutado no se ejecutan en esa llamada.
  • Usa un resultado devuelto guardándolo, mostrándolo, comprobándolo o combinándolo.

3.2 Devuelve valores desde distintas rutas de ejecución y combina resultados

Distintas entradas pueden necesitar distintas respuestas. Una función puede tener varias sentencias return, pero una llamada se detiene en la primera que ejecuta. Sigue la ruta real a través de sus ramas y bucles para encontrar el resultado.

Ordena las comprobaciones que se solapan
def letter_grade(score):
    if score >= 90:
        return "A"
    if score >= 80:
        return "B"
    if score >= 70:
        return "C"
    return "F"

Para 85, la primera condición es falsa y la segunda es verdadera. La función devuelve «B» sin comprobar las condiciones restantes. Para 42, las tres condiciones son falsas, así que el return final proporciona «F». Las sentencias if independientes funcionan porque cada rama cuya condición se cumple termina la llamada.

Aquí debe comprobarse primero el umbral más alto. Si score >= 70 fuera primero, una puntuación de 95 devolvería «C». Con rangos que se solapan, una coincidencia amplia al principio puede ocultar una respuesta posterior más específica.

Cubre la ruta sin ninguna rama coincidente
def sign(n):
    if n > 0:
        return "positive"
    elif n < 0:
        return "negative"
    return "zero"

La última línea cubre el cero. Sin ella, sign(0) llegaría al final y devolvería None. Sigue una entrada de cada rama y de cualquier caso restante; probar solo entradas positivas y negativas no detectaría este vacío.

Devuelve una comparación booleana
def is_even(n):
    return n % 2 == 0

if is_even(10):
    print("Even")

La comparación ya produce True o False. is_even(10) devuelve True, mientras que is_even(7) devuelve False. Usa el resultado directamente en una condición. Añadir == True no mejora la comprobación.

Termina la búsqueda antes de informar de que no hay coincidencias
def smallest_divisor(n):
    for d in range(2, n):
        if n % d == 0:
            return d
    return n

Para 91, los candidatos del 2 al 6 fallan y después el 7 lo divide exactamente. Devolver 7 termina tanto el bucle como la función. Para 13, el bucle no encuentra ningún divisor, así que el return final da 13.

Una prueba de primalidad debe permitir que la búsqueda continúe después de un candidato que no sirve:

def is_prime(n):
    if n < 2:
        return False
    for d in range(2, n):
        if n % d == 0:
            return False
    return True

El True final está fuera del bucle. Colocarlo en un else dentro del bucle devolvería un valor después de comprobar solo el primer candidato: el 9 se aceptaría erróneamente porque no es divisible por 2. Con la función corregida, 9 y 1 devuelven False; 2, 7 y 97 devuelven True. Para 2, el bucle no tiene candidatos y la ejecución llega al True final.

Devuelve dos valores
def share(total, people):
    return total // people, total % people

each, left = share(17, 5)
print(each, left)

La llamada devuelve una tupla, un resultado agrupado que contiene 3 y 2. La asignación lo desempaqueta en dos nombres, así que la salida es «3 2». Mostrar la llamada directamente produciría «(3, 2)». El número de nombres debe coincidir con el número de valores que se desempaquetan.

Combina llamadas de dentro hacia fuera
def add(a, b):
    return a + b

def to_fahrenheit(celsius):
    return celsius * 9 / 5 + 32

print(to_fahrenheit(add(10, 15)))

add devuelve primero 25. Ese valor se convierte en el argumento de to_fahrenheit, que devuelve 77,0. Por último, print muestra «77.0». Cada llamada interna debe devolver el valor que necesita la siguiente función.

Puntos clave

  • El primer return ejecutado termina una llamada, así que ordena con cuidado las comprobaciones que se solapan.
  • Incluye un resultado útil para cada ruta de entrada que deba gestionar la función.
  • Una función booleana puede devolver directamente una comparación.
  • Dentro de un bucle de búsqueda, devuelve el resultado encontrado; informa de que no hay coincidencias cuando fallen todos los candidatos.
  • Los valores devueltos separados por comas forman una tupla que puede desempaquetarse.
  • En las llamadas anidadas, el resultado interno se convierte en el argumento de la llamada externa.
4

Identifica dónde se pueden usar las variables: ámbito local y global

Un nombre dentro de una función puede parecer idéntico a otro de fuera y, aun así, hacer referencia a una variable distinta. El ámbito indica dónde puede usarse un nombre, y la asignación ayuda a determinar a cuál se refiere Python. Seguirás los parámetros y otras variables locales durante una llamada, distinguirás entre reasignar y modificar una lista compartida, y leerás ajustes globales. También corregirás un error habitual de ámbito y harás explícitos los cambios de valores en las llamadas.

4.1 Trabaja con variables locales y parámetros

El ámbito describe dónde puede usarse un nombre. Los parámetros y los nombres a los que se asignan valores dentro de una función son locales a la llamada de esa función. El código que realiza la llamada y una función pueden usar nombres similares sin compartir las mismas variables locales.

Mantén los nombres locales dentro de su llamada
def make_greeting():
    message = "Hi"
    print(message)

make_greeting()

Esto muestra «Hi». Añadir print(message) después de la llamada lanza NameError: name 'message' is not defined: el nombre local no está disponible allí. Para poner el valor a disposición del código que realiza la llamada, devuélvelo y guárdalo:

def make_greeting():
    return "Hi"

message = make_greeting()
print(message)

El message del nivel superior es una variable nueva del código que realiza la llamada y recibe el valor devuelto. La función no hace visibles fuera sus propios nombres locales.

Cada llamada recibe variables locales nuevas. Si un cuerpo establece count = 0, suma 1 y lo muestra, dos llamadas muestran «1» y «1». La segunda no continúa con el contador de la primera. Distintas funciones también pueden usar nombres locales como total de forma independiente.

Sigue la ocultación y la búsqueda de nombres
x = 10

def show():
    x = 5
    print(x)

show()
print(x)

La salida es «5» y después «10». La x local oculta la x global dentro de show; la asignación no modifica el valor del nivel superior. Una variable global pertenece al ámbito del nivel superior del archivo. Las asignaciones ordinarias fuera de las funciones crean variables globales.

Para una función definida en el nivel superior del archivo, Python busca un nombre entre sus nombres locales, después entre los globales del archivo y, por último, entre los incorporados, como print. Se usa la primera coincidencia. Por tanto, los nombres locales y globales son lugares distintos que revisar cuando un valor parece incorrecto.

Reasignar un parámetro no modifica el nombre del código que realiza la llamada
def add_bonus(points):
    points = points + 10
    print(points)

score = 50
add_bonus(score)
print(score)

points empieza con el valor 50. Su reasignación local lo convierte en 60, así que la primera salida es «60». El score del código que realiza la llamada sigue valiendo 50. Para actualizar ese nombre explícitamente, usa una función que devuelva points + 10 y después escribe score = add_bonus(score).

Modificar una lista es una operación distinta

Una lista puede compartirse mediante dos nombres:

def add_guest(guests, name):
    guests.append(name)

party = ["Ana"]
add_guest(party, "Ben")
print(party)

El parámetro guests y la variable party del código que realiza la llamada hacen referencia a la misma lista. append modifica su contenido, así que la salida es «['Ana', 'Ben']». En cambio, asignar guests = [] dentro de la función haría que solo el nombre local apuntara a una lista nueva; party seguiría haciendo referencia a la original. Al seguir un argumento de tipo lista, pregúntate si la línea modifica el objeto compartido o solo reasigna un nombre local.

Puntos clave

  • Los parámetros y los nombres a los que se asignan valores dentro de una función son locales a su llamada.
  • Cada llamada recibe variables locales nuevas; los valores de retorno llevan los resultados al exterior.
  • Un nombre local puede ocultar uno global sin modificar el valor global.
  • Reasignar un parámetro deja intacta la variable del código que realiza la llamada.
  • Modificar una lista compartida cambia la lista que ve el código que realiza la llamada.

4.2 Usa las variables globales con cuidado

Una función puede leer un nombre global sin una declaración. Asignar un valor a un nombre en su cuerpo sigue una regla distinta, y confundir estas operaciones es una causa habitual de UnboundLocalError.

Lee un ajuste fijo
TAX_RATE = 0.25

def tax(amount):
    return amount * TAX_RATE

print(tax(80))

La salida es «20.0». amount es local; TAX_RATE se lee de las variables globales del archivo. Las mayúsculas identifican una constante por convención e indican que el programa debe mantener fijo el ajuste. Python no impone esa convención.

La asignación convierte un nombre en local en todo el cuerpo
total = 0

def add_to_total(amount):
    total = total + amount

add_to_total(5)

La asignación convierte total en local en toda add_to_total. Para calcular el lado derecho, Python intenta leer ese nombre local antes de que tenga un valor. No recurre al total global. La llamada lanza UnboundLocalError: cannot access local variable 'total' where it is not associated with a value.

La decisión se basa en todo el cuerpo, no solo en las líneas ya ejecutadas. Un cuerpo con print(count) seguido de count = 10 también trata count como local en la línea que lo muestra. Un count global no puede proporcionar el valor local que falta.

Declara una asignación global deliberada
total = 0

def add_to_total(amount):
    global total
    total = total + amount

add_to_total(5)
add_to_total(7)
print(total)

Ahora tanto la lectura como la asignación hacen referencia al nombre global, así que la salida es «12». Coloca global total antes de cualquier uso de total en la función. Usar el nombre antes de su declaración es un error de sintaxis.

Una declaración por sí sola no crea un valor. Una asignación posterior puede crear una variable global que no existía: el cuerpo de una función que contenga global level y después level = 1 crea el level global cuando se llama a la función.

Muestra el cambio mediante entradas y un resultado

La misma suma acumulada puede escribirse con una interfaz explícita:

def add_to_total(total, amount):
    return total + amount

total = 0
total = add_to_total(total, 5)
total = add_to_total(total, 7)
print(total)

Esto también muestra «12». Cada llamada muestra el valor anterior que se pasa, y la asignación muestra adónde va el nuevo. Puedes comprobar add_to_total(10, 3) por separado sin preparar antes un estado global oculto. Si varias funciones modifican la misma variable global, su comportamiento depende del orden en que se ejecutan.

Operación dentro de una función¿Se necesita una declaración?
Leer un ajuste globalNo.
Reasignar un nombre globalglobal name antes de usarlo.
Añadir al final de una lista global existenteNo; el nombre no se reasigna.

Leer una lista compartida y modificar su contenido usa la referencia existente. Sustituir el valor de ese nombre global por una lista distinta es una asignación, así que se aplica la regla de asignación.

Puntos clave

  • Lee un nombre global sin una declaración especial.
  • Una asignación en cualquier parte de una función convierte ese nombre en local salvo que se declare global.
  • Leer una variable local sin un valor asignado lanza UnboundLocalError.
  • Coloca global name antes de usar un nombre que la función reasigne deliberadamente en el ámbito global.
  • Da preferencia a los parámetros y valores de retorno cuando un valor cambiante pueda pasarse explícitamente.
  • Modificar una lista y reasignar su nombre siguen reglas distintas.
5

Documenta y diseña programas con funciones

Las buenas funciones necesitan tareas claras además de código correcto. Quien llama a una función debe poder saber qué necesita, qué devuelve y qué efectos produce sin estudiar cada línea de su cuerpo. Escribirás cadenas de documentación, dividirás un programa completo en funciones auxiliares y las conectarás mediante una función principal pequeña. Después comprobarás cada parte por separado con resultados esperados, entradas límite y las pistas de una traza de excepción.

5.1 Documenta funciones con cadenas de documentación

Quien llama a una función necesita conocer su tarea sin leer toda su implementación. Una cadena de documentación proporciona esa descripción. Python reconoce una cadena como la cadena de documentación de la función cuando es la primera sentencia del cuerpo.

Escribe primero una descripción breve
def to_fahrenheit(celsius):
    """Convert a temperature from degrees Celsius to degrees Fahrenheit."""
    return celsius * 9 / 5 + 32

print(to_fahrenheit.__doc__)

La salida es la frase que está entre las comillas. Python guarda la cadena de documentación en __doc__; las comillas triples no forman parte de la frase guardada. help(to_fahrenheit) muestra la descripción junto con la firma to_fahrenheit(celsius). Pasa el nombre de la función a help, sin llamar a la función.

La convención habitual es usar comillas dobles triples, incluso para una cadena de documentación de una línea. Empieza con una orden como «Devuelve el área de un rectángulo.» y termina con un punto. Mantén una descripción breve y sus comillas de cierre en una sola línea. No necesitas repetir el nombre de la función ni la lista de parámetros porque la ayuda ya los incluye.

Añade detalles cuando sean necesarios para llamar a la función
def split_bill(total, people, tip_rate=0.2):
    """Return each person's share of a bill, including the tip.

    total: the bill before the tip
    people: the number of people sharing the bill
    tip_rate: the tip as a fraction of the bill (default 0.2)
    """
    return total * (1 + tip_rate) / people

La primera línea indica el resultado. Una línea en blanco la separa de los detalles sobre las entradas. El valor predeterminado se documenta como 0,2, una fracción de la cuenta; esto evita que quien llama a la función use 20 como valor para una propina del 20 %. Las comillas de cierre de una cadena de documentación de varias líneas van en una línea aparte.

Para split_bill(84, 4), la función aplica la propina predeterminada y devuelve 25,2. Quien la llama puede conocer el significado de las tres entradas antes de elegir los argumentos. Incluye las unidades cuando sean relevantes y describe efectos como mostrar algo, para que se puedan predecir tanto el resultado como el comportamiento visible.

Distingue la documentación de los comentarios
FormaFinalidad principal
Primera cadena del cuerpoDescribe la función para quien la llama y aparece en help.
Comentario con # en el cuerpoExplica un detalle del código a quien lee la implementación.

Una cadena situada después de una asignación u otra sentencia del cuerpo no es la cadena de documentación de la función. Es una expresión de cadena sin usar, y __doc__ es None si no hay una cadena de documentación como primera sentencia. Un comentario con # tampoco se convierte en la descripción de la ayuda.

Escribe el resumen mientras decides la tarea de la función. Si la frase necesita varias acciones sin relación entre sí, reconsidera si conviene dividir la función. Cuando cambies parámetros, valores predeterminados, valores devueltos o efectos en pantalla, actualiza la cadena de documentación al mismo tiempo; quienes llaman a la función confían en ella como parte de la interfaz.

Puntos clave

  • La cadena de documentación de una función es la primera sentencia de su cuerpo.
  • Usa comillas dobles triples y una frase imperativa breve terminada en punto.
  • En las descripciones más largas, separa el resumen de los detalles con una línea en blanco.
  • Describe las entradas relevantes, las unidades, los valores predeterminados, los resultados y los efectos.
  • Consulta la documentación guardada con help(name) o name.__doc__.

5.2 Descompón un problema en funciones

La descomposición consiste en dividir una tarea en tareas más pequeñas. Cada función se responsabiliza de una tarea, con entradas claras y un resultado o efecto claro. Así, el programa principal puede leerse como una secuencia breve de pasos con nombre.

Planifica los datos antes de escribir los cuerpos

Para un programa que informa de la media de unas puntuaciones de pruebas y de una calificación con letra, identifica tres tipos de trabajo: leer puntuaciones, calcular una media y elegir una calificación. Decide qué recibe y devuelve cada función auxiliar. Deja la salida en pantalla en main, donde se reúnen los resultados.

def get_score(prompt):
    return float(input(prompt))

def average(a, b, c):
    return (a + b + c) / 3

def letter_grade(score):
    if score >= 90:
        return "A"
    if score >= 80:
        return "B"
    if score >= 70:
        return "C"
    return "F"

def main():
    first = get_score("Test 1: ")
    second = get_score("Test 2: ")
    third = get_score("Test 3: ")
    avg = average(first, second, third)
    print("Average:", round(avg, 1), "Grade:", letter_grade(avg))

main()

Con las puntuaciones 78, 92 y 85, average devuelve 85,0. Ese resultado se convierte en el argumento de letter_grade, que devuelve «B». La salida en pantalla es «Average: 85.0 Grade: B».

main coordina la secuencia; no necesita saber cómo elige letter_grade su respuesta. Usar una función mediante su tarea e interfaz, sin seguir cada sentencia de su cuerpo, es abstracción procedimental. Ya usas print de esta forma.

Ofrece una interfaz clara al código que realiza la llamada

La interfaz de una función consta de su nombre, sus parámetros, el resultado devuelto y su comportamiento documentado. average(a, b, c) necesita tres números y devuelve su media. El código que la llama no tiene que leer una solicitud de datos ni capturar texto mostrado para obtener ese número. Puedes reescribir el cálculo manteniendo las entradas y la salida acordadas, y las llamadas existentes seguirán funcionando.

Usa nombres como calculate_total y print_receipt para acciones, e is_even o has_discount para preguntas booleanas. Los nombres de parámetros como price y quantity explican qué valores corresponden a cada posición. Los nombres de una sola letra pueden ser adecuados cuando su significado está claro, como en las tres entradas de average.

Convierte la repetición en parámetros

Si varias partes de un programa muestran títulos distintos entre las mismas líneas de signos igual, convierte el título en un parámetro de print_heading(title). La estructura repetida pertenece a un solo cuerpo, mientras que el texto variable pertenece a las llamadas. Así, un cambio posterior en la longitud de la línea solo necesita una modificación.

Elige cómo dividir las funciones para que las tareas sean más fáciles de entender o reutilizar. Colocar todas las sentencias en una única main larga oculta las tareas más pequeñas. Convertir cada expresión trivial en una función auxiliar usada una sola vez puede añadir nombres sin mejorar la legibilidad. Una comprobación útil es ver si una frase breve puede describir cada tarea y sus entradas y salidas.

Termina el archivo con la llamada real a main() después de todas las definiciones. Un programa que solo contiene definiciones creará sus funciones y terminará sin ejecutar sus cuerpos.

Puntos clave

  • Descompón la tarea en tareas más pequeñas con entradas y salidas identificadas.
  • Separa los cálculos de la entrada de datos y la salida en pantalla cuando deban reutilizarse o comprobarse.
  • Haz que main coordine las funciones auxiliares y llama a main() después de las definiciones.
  • Usa parámetros para las partes que varían en el código repetido.
  • Una interfaz estable permite llamar a una función sin depender de su cuerpo.
  • Elige cómo dividir las funciones para que el programa sea más fácil de entender.

5.3 Construye y comprueba un programa función por función

Crear varias funciones antes de ejecutar alguna dificulta localizar un fallo. El desarrollo incremental consiste en escribir una parte pequeña, comprobarla y después añadir la siguiente. Mantienes un programa que funciona y reduces la cantidad de código nuevo que debes revisar.

Usa un esbozo de función durante la planificación

Un esbozo de función tiene la cabecera prevista y un cuerpo provisional. Una cadena de documentación y pass mantienen válida la definición, pero la función devuelve None hasta que la implementes. Un retorno fijo puede ayudar a probar la salida en pantalla del código que la llama sin dar por hecho que el cálculo real ya funciona.

Empieza con una función auxiliar de cálculo cuyo resultado puedas obtener de forma independiente. Una vez que se comporte correctamente, conéctala con la siguiente. Deja la entrada interactiva para cuando los cálculos puedan comprobarse con llamadas directas.

Decide los resultados esperados antes de ejecutar

Con las funciones average y letter_grade, las puntuaciones 70, 75 y 72 tienen una media aproximada de 72,33, así que su calificación esperada es «C». Comprueba ambas etapas:

print(average(70, 75, 72))
print(letter_grade(average(70, 75, 72)) == "C")

Las salidas son «72.33333333333333» y «True». La comparación comprueba directamente la calificación esperada; mirar solo la salida del propio programa sin una expectativa independiente puede hacer que una respuesta errónea pero plausible pase inadvertida.

Prueba los límites además de las entradas habituales

Para un umbral de 90, prueba 90 y 89,9. La función de calificación correcta devuelve «A» y «B». Si su primera condición fuera score > 90, solo la comprobación del límite exacto revelaría que 90 pasa erróneamente a la siguiente condición.

Incluye un valor habitual, límites exactos, valores cercanos y entradas extremas que la función deba gestionar. En la función de calificación, comprobar 70 y 0 recorre el límite mínimo para aprobar y la ruta final de «F». Una comprobación como print(letter_grade(85) == "B") es sencilla porque la función recibe un valor y devuelve su resultado.

Lee la traza de la excepción y revisa el valor recibido

Supón que main llama a letter_grade(input("Score: ")). Introducir «85» envía una cadena a una comparación con un número. El error final es TypeError: '>=' not supported between instances of 'str' and 'int'. La traza señala la comparación dentro de la función auxiliar, mientras que una línea de llamada anterior señala main.

El fallo se produce en la comparación, pero la corrección corresponde al lugar donde se prepara la entrada: conviértela con float() antes de pasarla. Un print("letter_grade got", score) temporal como primera línea ayuda a revelar una entrada inesperada. Si su tipo no está claro, revisa el código que realiza la llamada y la conversión que usa. Elimina las salidas de depuración después de corregir el error.

Relaciona los síntomas con las causas probables
SíntomaQué revisar
Un resultado es NoneUn retorno que falta o una ruta sin cubrir.
No aparece ningún efectoUna llamada que falta o un resultado devuelto sin usar.
Un resultado plausible tiene un significado incorrectoArgumentos intercambiados.
NameErrorUn nombre de función o variable mal escrito o no disponible.

Después de corregir una función auxiliar, vuelve a ejecutar las comprobaciones que recorran las rutas afectadas y el código que la llama para conectarla con el programa.

Puntos clave

  • Construye y comprueba una función antes de añadir la siguiente.
  • Obtén los resultados esperados de forma independiente antes de compararlos con las llamadas.
  • Prueba los límites exactos y los valores cercanos para detectar errores en las comparaciones.
  • Usa la traza de la excepción para localizar el fallo y el código que realiza las llamadas.
  • Elimina las salidas de depuración temporales una vez corregido el problema.

Ejemplos de Funciones en Python

5 Lecciones Interactivas

1

Escribe una función y sigue sus llamadas

10 pasos
Crea un saludo reutilizable y después sigue una función que llama a una auxiliar hasta volver al programa principal.
  1. 1
    IntroducciónDa nombre a una tarea

    Una función te permite escribir una tarea útil una vez y elegir cuándo ejecutarla. Empezarás con un saludo y después seguirás un informe que llama a una función auxiliar.

    Al leer, distingue dos preguntas: «¿Ha creado Python esta función?» y «¿La ha llamado ya el programa?». La primera hace que el nombre esté disponible; la segunda inicia el trabajo del cuerpo. Esta distinción explica por qué un archivo lleno de definiciones puede terminar sin salida.

  2. 2
    ExplicaciónEscribe el cuerpo reutilizable
    def greet():
        print("Hello!")
        print("Welcome to Python.")
    

    La cabecera usa def, un nombre, paréntesis y dos puntos. Las dos líneas con sangría de cuatro espacios forman el cuerpo. Python crea la función al ejecutar esta definición, pero todavía no se ejecuta ninguno de los print.

    La siguiente sentencia sin sangría estará fuera de la función. La sangría indica a Python dónde termina esta tarea; forma parte de la estructura del programa.

  3. 3
    EjemploEjecútala dos veces

    Añade estas líneas después de la definición:

    greet()
    greet()
    

    La primera llamada entra en el cuerpo y muestra «Hello!» seguido de «Welcome to Python.». La segunda vuelve a empezar en la primera línea del cuerpo y muestra ambos mensajes de nuevo. Hay cuatro líneas de salida.

    Los paréntesis vacíos siguen siendo importantes: greet por sí solo hace referencia al objeto de función. No lo llama, y print(greet) muestra una descripción de la función en lugar del saludo.

  4. 4
    DesafíoPredice qué ocurre si falta una llamada

    ¿Qué muestra este archivo?

    def ready():
        print("Ready")
    
    ready
    print("Waiting")
    

    ---reveal---

    Solo muestra «Waiting». La definición crea ready, y el nombre por sí solo hace referencia a esa función sin ejecutarla. Para mostrar también el mensaje, cambia ready por ready(). La llamada se ejecutaría entonces antes del print final y produciría «Ready» y «Waiting» en líneas separadas.

  5. 5
    ConsejoMantén utilizables los nombres y los cuerpos

    Usa nombres como print_receipt: palabras en minúsculas unidas por guiones bajos que describen la tarea. Evita sustituir un nombre incorporado. Asignar texto a input oculta la función, así que un input(...) posterior intenta llamar al texto y falla.

    Un cuerpo sin terminar necesita una sentencia. Usa un pass con sangría como marcador provisional. Un comentario por sí solo no es un cuerpo, y un pass sin sangría quedaría fuera de la función.

  6. 6
    EjemploEntra en una función que realiza una llamada
    def line():
        print("----------")
    
    def banner():
        line()
        print("  REPORT")
        line()
    
    print("Start")
    banner()
    print("End")
    

    Primero se ejecutan ambas definiciones sin mostrar nada. La sentencia del nivel superior muestra «Start» y después banner() entra en el cuerpo de banner. Su primera línea llama a line, así que banner debe esperar mientras esa función auxiliar muestra sus guiones. No avances hasta el título antes de que termine la función auxiliar.

  7. 7
    ExplicaciónReanuda la ejecución un nivel cada vez

    Cuando termina line, la ejecución se reanuda en el print del título dentro de banner. Después, banner llama a line por segunda vez y produce la segunda línea de guiones. Cuando termina banner, el programa principal se reanuda y muestra «End».

    La pila de llamadas de Python registra las llamadas sin terminar y sus puntos de retorno. Mientras se ejecuta la función auxiliar, banner y el programa principal esperan. Un seguimiento en papel puede marcar estos puntos de retorno y registrar la salida cuando se ejecute realmente cada print.

  8. 8
    DesafíoSigue otra llamada a una función auxiliar

    ¿Cuál es el orden de la salida?

    def inner():
        print("I")
    
    def outer():
        print("O")
        inner()
        print("P")
    
    outer()
    print("Q")
    

    ---reveal---

    Las líneas son «O», «I», «P» y «Q». El cuerpo externo muestra primero su mensaje, se pausa para ejecutar inner y después se reanuda en su siguiente print. La sentencia final del nivel superior solo se ejecuta cuando termina outer. El orden de las definiciones por sí solo no determina el orden de la salida.

  9. 9
    DesafíoMueve una definición de forma segura

    Un archivo define show con un cuerpo que llama a border. Después define border y termina con un bucle que llama a show() dos veces. ¿Causará un error que la función auxiliar esté definida más abajo y cuántas veces se ejecutará border?

    ---reveal---

    El programa funciona: ambas definiciones se han ejecutado antes de que el bucle llame a show. Cada llamada entra en show desde la primera línea de su cuerpo y llega a una llamada a border, así que la función auxiliar se ejecuta dos veces. Mover el bucle por encima de la definición de la función auxiliar haría que su nombre no estuviera disponible cuando se necesitara por primera vez.

  10. 10
    RepasoLee desde la primera sentencia activa

    Al seguir la ejecución de un programa con funciones:

    • Revisa la cabecera y la sangría para localizar cada cuerpo.
    • Empieza por las sentencias del nivel superior y entra en un cuerpo solo mediante una llamada.
    • Marca la siguiente sentencia del código que realiza la llamada antes de seguir una función auxiliar.
    • Registra la salida cuando se ejecute su print.

    Si una llamada falla, lee el error final de la traza y después revisa la línea del cuerpo que falla y el código que la llamó. La ruta de llamadas suele ser la clave para comprender el error.

2

Ocupa las posiciones de los parámetros

13 pasos
Asocia valores por posición o por nombre y después investiga los valores predeterminados creados al ejecutar la definición.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónReutiliza una tarea con valores distintos
  2. 2
    EjemploAsocia la primera y la segunda entrada
  3. 3
    ExplicaciónEvalúa los argumentos antes del cuerpo
  4. 4
    DesafíoComprueba el número de argumentos
  5. 5
    ExplicaciónUsa nombres para mostrar qué representa cada valor
  6. 6
    DesafíoCorrige una posición ocupada dos veces
  7. 7
    ConsejoInterpreta las opciones por palabra clave de las funciones incorporadas
  8. 8
    EjemploHaz opcional la elección habitual
  9. 9
    DesafíoSalta una opción por su nombre
  10. 10
    Idea claveUn valor predeterminado recuerda el momento de su creación
  11. 11
    EjemploDescubre por qué una lista predeterminada conserva elementos
  12. 12
    DesafíoCombina valores predeterminados con entradas por nombre
  13. 13
    RepasoCompara la cabecera con la llamada
3

Sigue los valores de vuelta al código que realiza la llamada

14 pasos
Distingue la salida de los resultados y después crea ramas, búsquedas y llamadas anidadas que devuelvan los valores necesarios.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónObserva qué recibe el código que realiza la llamada
  2. 2
    EjemploSustituye la llamada por su resultado
  3. 3
    ExplicaciónDistingue la pantalla del resultado
  4. 4
    DesafíoEncuentra el valor usado en la suma
  5. 5
    ConsejoComprueba dónde se ejecuta la llamada
  6. 6
    EjemploDetente en la primera calificación que corresponda
  7. 7
    DesafíoCubre la entrada que queda entre las ramas
  8. 8
    Idea claveDeja que una comparación responda a la pregunta
  9. 9
    EjemploDevuelve un divisor encontrado
  10. 10
    DesafíoCorrige un resultado positivo prematuro
  11. 11
    EjemploDesempaqueta un resultado agrupado
  12. 12
    EjemploPasa un resultado interno hacia fuera
  13. 13
    DesafíoCombina una ruta anticipada y un resultado
  14. 14
    RepasoSigue conjuntamente las rutas y los valores devueltos
4

Sigue los nombres y los objetos compartidos

11 pasos
Distingue los nombres locales de los globales y después haz explícita la actualización de un total en el código que realiza la llamada.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónPregúntate a dónde pertenece el nombre
  2. 2
    EjemploDa a cada llamada su propio contador
  3. 3
    ExplicaciónDistingue los nombres que se ocultan
  4. 4
    DesafíoHaz explícita la actualización en el código que realiza la llamada
  5. 5
    EjemploSigue una lista compartida a través de un parámetro
  6. 6
    EjemploLee una variable global sin una declaración
  7. 7
    Idea claveLa asignación determina de antemano el ámbito local
  8. 8
    DesafíoElige el ámbito de una actualización
  9. 9
    ConexiónPasa el valor cambiante a través de la llamada
  10. 10
    DesafíoDistingue la mutación de la reasignación
  11. 11
    RepasoIdentifica la operación antes de predecir su efecto
5

Diseña y comprueba un informe de puntuaciones

12 pasos
Documenta una función auxiliar, planifica sus entradas y resultados y comprueba los límites y los datos de las llamadas antes de conectar el programa.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónConstruye un programa a partir de tareas claras
  2. 2
    EjemploColoca la descripción donde la ayuda pueda encontrarla
  3. 3
    ExplicaciónAñade detalles que afecten a una llamada
  4. 4
    DesafíoEncuentra la documentación que falta
  5. 5
    ExplicaciónElige una tarea para cada función auxiliar
  6. 6
    EjemploConecta las funciones auxiliares en main
  7. 7
    DesafíoSepara el cálculo de la salida en pantalla
  8. 8
    ConsejoMantén un programa que funcione mientras lo construyes
  9. 9
    EjemploComprueba un límite que pueda revelar un error
  10. 10
    DesafíoLocaliza dónde entra un tipo incorrecto
  11. 11
    DesafíoMantén la documentación y la comprobación de acuerdo
  12. 12
    RepasoUsa la interfaz para orientar las comprobaciones

Ejercicios de Funciones en Python

40 Preguntas de Práctica en 4 sets

Set 1: Interpreta llamadas y sigue sus resultados10 Preguntas de Práctica

Pregunta 1 de 10

¿Qué salida produce este programa?

def announce():
    print("Open")

print("Ready")
  1. «Open» y después «Ready».
  2. Solo «Ready» en una línea.
  3. «Ready» y después «Open» debajo.
  4. No se muestra ninguna salida en absoluto.
Mostrar respuestaOcultar respuesta
Respuesta: B
El programa muestra «Ready» porque se ejecuta esa sentencia del nivel superior. Definir announce crea la función, pero nunca entra en su cuerpo, así que «Open» no aparece. La función incorporada print sí se ejecuta aunque nunca se llame a la función recién definida.

Pregunta 2 de 10

¿Cuál es el orden de la salida?

def mark():
    print("M")

def stage():
    print("S")
    mark()
    print("T")

print("R")
stage()
  1. «M», «S», «T», «R»
  2. «R», «M», «S», «T»
  3. «R», «S», «T», «M»
  4. «R», «S», «M», «T»
Mostrar respuestaOcultar respuesta
Respuesta: D
El print del nivel superior produce «R»; después, stage muestra «S» y llama a mark, que muestra «M». Cuando termina esa llamada interna, stage se reanuda y muestra «T». Mover «M» al final pasa por alto que el código que realiza la llamada espera a su función auxiliar antes de continuar.

Pregunta 3 de 10

¿Qué muestra esta llamada?

def describe_trip(origin, destination):
    print(origin, "to", destination)

describe_trip("Mesa", "Salem")
  1. «Mesa to Salem»
  2. «Salem to Mesa»
  3. «origin to destination»
  4. «Mesa Salem to»
Mostrar respuestaOcultar respuesta
Respuesta: A
El primer argumento posicional ocupa origin y el segundo ocupa destination, así que el cuerpo muestra «Mesa to Salem». Invertir los nombres exigiría invertir los argumentos o las funciones de los parámetros en el cuerpo. Python asocia posiciones sin interpretar qué significan los nombres de las ciudades.

Pregunta 4 de 10

¿Cómo puedes llamar a esta función usando «Inez» para la persona y «West» para la habitación?

def show_booking(person, room):
    print(person, room)
  1. show_booking(person="Inez", "West")
  2. show_booking("Inez", person="West")
  3. show_booking(room="West", person="Inez")
  4. show_booking(name="Inez", room="West")
Mostrar respuestaOcultar respuesta
Respuesta: C
Nombrar room y person ocupa ambos parámetros correctamente incluso en orden inverso. Proporcionar un valor posicional después de person="Inez" es un error de sintaxis, así que los valores deseados por sí solos no hacen válida esa llamada. Las palabras clave también deben usar los nombres exactos de la cabecera y no ocupar un parámetro dos veces.

Pregunta 5 de 10

¿Qué se muestra?

def label(text, copies=2):
    print(text * copies)

label("Go")
  1. «Go»
  2. «GoGo»
  3. «Go2»
  4. «Go Go»
Mostrar respuestaOcultar respuesta
Respuesta: B
La llamada proporciona text y omite copies, así que copies toma su valor predeterminado de 2. Multiplicar «Go» por 2 repite el texto como «GoGo» sin insertar un espacio. Mostrar solo «Go» ignoraría el valor predeterminado usado por esta llamada.

Pregunta 6 de 10

¿Qué muestra la última línea?

def triple(value):
    print(value * 3)

answer = triple(4)
print(answer)
  1. «None»
  2. «12»
  3. «4»
  4. Nada; se omite la última línea.
Mostrar respuestaOcultar respuesta
Respuesta: A
La función auxiliar muestra «12», después llega al final de su cuerpo y devuelve None. La asignación guarda ese valor devuelto en answer, así que la última línea muestra «None». El 12 mostrado es un efecto del print interno y no se convierte automáticamente en el valor de retorno de la función auxiliar.

Pregunta 7 de 10

¿Qué devuelve esta función para first_factor(25)?

def first_factor(n):
    for candidate in range(2, n):
        if n % candidate == 0:
            return candidate
        return n
  1. 5 después de comprobar los candidatos del 2 al 5.
  2. None porque el primer candidato falla.
  3. 25 después de comprobar todos los candidatos.
  4. 25 después de comprobar solo el candidato 2.
Mostrar respuestaOcultar respuesta
Respuesta: D
El candidato 2 no divide 25, así que la ejecución llega a return n en esa primera iteración del bucle y devuelve 25. La función nunca comprueba el candidato 5. Un return después de todo el bucle permitiría continuar la búsqueda, pero aquí la sangría coloca esa alternativa dentro del bucle.

Pregunta 8 de 10

¿Cuáles son las dos líneas de salida?

level = 7

def show_level():
    level = 3
    print(level)

show_level()
print(level)
  1. «3» y después «3»
  2. «7» y después «3»
  3. «3» y después «7»
  4. «7» y después «7»
Mostrar respuestaOcultar respuesta
Respuesta: C
La asignación dentro de show_level crea un level local, así que la función auxiliar muestra «3». Deja el valor global en 7, que muestra el print final. Esperar dos 3 trata una asignación local como si reasignara la variable global con el mismo nombre.

Pregunta 9 de 10

¿Qué función cumple la primera cadena en esta función?

def square(n):
    """Return the square of n."""
    return n * n
  1. Una descripción guardada que muestra help(square).
  2. El texto devuelto por cada llamada a square.
  3. Un mensaje mostrado antes de la multiplicación.
  4. Un valor predeterminado usado cuando se omite n.
Mostrar respuestaOcultar respuesta
Respuesta: A
Como la cadena es la primera sentencia del cuerpo, se convierte en la cadena de documentación de la función y se guarda en square.__doc__. Llamar a square sigue devolviendo la expresión numérica n * n. Una cadena de documentación describe la función; no es una salida automática ni su sentencia return.

Pregunta 10 de 10

Un programa lee una distancia, la convierte y muestra un mensaje. ¿Qué interfaz permite comprobar la conversión sin introducir datos?
  1. Un conversor sin parámetros que lee la distancia.
  2. Un conversor que recibe la distancia y devuelve el valor convertido.
  3. Un conversor que recibe la distancia y muestra el valor convertido.
  4. Un conversor sin parámetros que modifica una distancia global.
Mostrar respuestaOcultar respuesta
Respuesta: B
Una función auxiliar con un parámetro de distancia y un número devuelto puede llamarse directamente con una entrada conocida y compararse con un resultado esperado. Una función auxiliar que solo muestra la respuesta proporciona None al código que la llama. Mantener la entrada y la salida en pantalla en el código que realiza la llamada facilita reutilizar y comprobar el cálculo.
Set 2: Sigue las entradas, el ámbito y los resultados que faltan10 Preguntas de Práctica

Guarda esta unidad para ver todas las respuestas y practicar cada set.

Pregunta 1 de 10

¿Cómo debe completarse el cuerpo de esta función sin terminar para que el archivo sea válido, pero la función aún no haga nada?

def print_ticket():
    # Work to be added later
  1. Añadir un pass sin sangría debajo del comentario.
  2. Añadir otro comentario con sangría debajo.
  3. Añadir un pass con sangría debajo del comentario.
  4. Añadir un print_ticket() sin sangría debajo.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 2 de 10

¿Qué muestra este programa?

def show_scaled(value, factor):
    print(value * factor)

entry = "6"
show_scaled(entry, 3)
  1. «666»
  2. «18»
  3. «6 6 6»
  4. «9»
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 3 de 10

¿Qué valor se devuelve?

step = 4

def advance(position, amount=step):
    return position + amount

step = 9
result = advance(10)
  1. 19
  2. 9
  3. 10
  4. 14
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 4 de 10

¿Qué único cambio hace que result contenga 16 sin mostrarlo dentro de la función auxiliar?

def square(n):
    print(n * n)

result = square(4)
  1. Sustituir el cuerpo por return print(n * n).
  2. Sustituir el cuerpo por return n * n.
  3. Añadir return después del print existente.
  4. Sustituir la llamada por result = print(square(4)).
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 5 de 10

¿Qué se muestra?

def pack(total, size):
    return total // size, total % size

def double(n):
    return n * 2

boxes, spare = pack(29, 6)
print(double(boxes) + spare)
  1. «12»
  2. «9»
  3. «14»
  4. «13»
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 6 de 10

¿Qué se muestra después de ambas llamadas?

def add_guest(guests):
    guests.append("Sol")

def replace_guests(guests):
    guests = ["Tao"]

party = ["Ren"]
add_guest(party)
replace_guests(party)
print(party)
  1. ['Tao']
  2. ['Ren']
  3. ['Ren', 'Sol']
  4. ['Ren', 'Sol', 'Tao']
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 7 de 10

¿Qué ocurre cuando se llama a inspect()?

count = 11

def inspect():
    print(count)
    count = 2

inspect()
  1. Lanza UnboundLocalError antes de mostrar un valor.
  2. Muestra «11» y después cambia el count global a 2.
  3. Muestra «11» y después crea el count local con valor 2.
  4. Muestra «2» porque la asignación local se ejecuta primero.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 8 de 10

¿Qué contiene show.__doc__?

def show():
    value = 2
    """Display the current value."""
    print(value)
  1. La frase «Display the current value.»
  2. None
  3. El número 2
  4. La línea de código print(value)
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 9 de 10

Tres partes de un programa muestran un título entre líneas separadoras idénticas. ¿Qué cambio elimina la lógica repetida y mantiene los distintos títulos?
  1. Crear una función independiente sin parámetros para cada título.
  2. Guardar cada título en una variable global que lea una función de salida.
  3. Colocar los tres bloques sin cambios dentro de main.
  4. Escribir print_heading(title) y pasar cada título.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 10 de 10

Una categoría debe ser «completa» a partir de 50 y «parcial» por debajo de 50. ¿Qué par de entradas de prueba revela mejor una condición accidental > 50?
  1. 50 y 49
  2. 51 y 52
  3. 25 y 30
  4. 49 y 48
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Set 3: Diagnostica llamadas y corrige el comportamiento del programa10 Preguntas de Práctica

Guarda esta unidad para ver todas las respuestas y practicar cada set.

Pregunta 1 de 10

¿Por qué funciona este programa aunque tick esté definida debajo de report?

def report():
    tick()

def tick():
    print("Done")

report()
  1. Python ejecuta una vez todos los cuerpos antes de cualquier llamada.
  2. La definición de report mueve tick por encima de ella.
  3. El cuerpo de report se copia en la definición de tick.
  4. Ambas definiciones se ejecutan antes de que report() llame a tick.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 2 de 10

¿Qué valor de argumento llega a width?

def show_width(width):
    print(width)

base = 8
show_width(base + 3)
  1. 8
  2. 11
  3. El texto «base + 3»
  4. Ningún valor porque los nombres son distintos.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 3 de 10

¿Por qué falla esta llamada?

def mark_pages(first, last):
    print(first, last)

mark_pages(4, first=9)
  1. El argumento por palabra clave va después de uno posicional.
  2. No pueden usarse juntos dos argumentos enteros.
  3. first recibe dos valores y last no recibe ninguno.
  4. Las palabras clave deben coincidir con las variables del código que llama.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 4 de 10

¿Cuáles son las dos listas mostradas?

def collect(value, bucket=[]):
    bucket.append(value)
    return bucket

print(collect("red"))
print(collect("blue", []))
  1. ['red'] y después ['blue']
  2. ['red'] y después ['red', 'blue']
  3. ['red', 'blue'] y después ['blue']
  4. ['blue'] y después ['red', 'blue']
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 5 de 10

¿Cuál es la salida completa?

def shift(n):
    return n + 2
    print("shifted")

shift(5)
print("done")
  1. «shifted» y después «done»
  2. «7» y después «done»
  3. Solo «done»
  4. Solo «shifted»
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 6 de 10

Una función debe devolver True exactamente cuando un entero sea primo. ¿Por qué este cuerpo acepta erróneamente 35?

def is_prime(n):
    if n < 2:
        return False
    for d in range(2, n):
        if n % d == 0:
            return False
        else:
            return True
  1. Prueba todos los candidatos, pero se salta el 5.
  2. Devuelve False con el candidato 5.
  3. Trata como primo todo número impar menor que 2.
  4. Devuelve True con el candidato 2 antes de probar el 5.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 7 de 10

¿Qué se muestra?

total = 2

def add(amount):
    global total
    total = total + amount
    return total

first = add(4)
second = add(first)
print(total, second)
  1. «6 12»
  2. «12 12»
  3. «8 8»
  4. «6 6»
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 8 de 10

Una función cambia su duración predeterminada de 15 minutos a 20 minutos, con el mismo cálculo y las mismas unidades. ¿Qué cambio necesita la documentación?
  1. Actualizar a 20 minutos el valor predeterminado documentado del parámetro opcional.
  2. Cambiar el nombre de la función en la cadena de documentación para mencionar 20 minutos.
  3. Mover la cadena de documentación después del cálculo para documentar su nuevo resultado.
  4. Eliminar la descripción del parámetro porque la cabecera muestra su nombre.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 9 de 10

Una función auxiliar numérica conserva el mismo nombre, parámetros, valores devueltos y efectos documentados después de simplificar su cuerpo. ¿Por qué puede mantenerse sin cambios el código que la llama?
  1. El código que la llama recibe todas las variables locales del nuevo cuerpo.
  2. Python guarda el cuerpo anterior hasta que se reescriba todo el código que la llama.
  3. El código que la llama usa una interfaz cuyo comportamiento se conserva.
  4. Una cadena de documentación hace que Python corrija automáticamente cada llamada.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 10 de 10

Una función auxiliar numérica falla en if score >= 60: después de que el código que la llama pase input("Score: "). ¿Qué corrección resuelve el tipo de entrada?
  1. Cambiar la comparación a score >= "60".
  2. Convertir la entrada con float() antes de llamar a la función auxiliar.
  3. Añadir un print después de la comparación para mostrar score.
  4. Eliminar el parámetro y leer un score global en su lugar.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Set 4: Combina las reglas de las funciones en situaciones nuevas10 Preguntas de Práctica

Guarda esta unidad para ver todas las respuestas y practicar cada set.

Pregunta 1 de 10

¿Qué muestra la última línea?

def change(values):
    values.append("B")
    values = ["C"]
    values.append("D")
    return values

original = ["A"]
result = change(original)
print(original, result)
  1. ['A'] ['C', 'D']
  2. ['A', 'B', 'D'] ['C']
  3. ['C', 'D'] ['C', 'D']
  4. ['A', 'B'] ['C', 'D']
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 2 de 10

¿Cómo debe llamarse una función que muestra un recibo de pago según el estilo habitual de Python?
  1. print_receipt
  2. print-receipt
  3. 2print_receipt
  4. print receipt
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 3 de 10

¿Qué se muestra?

def outer():
    inner()
    print("Y")

outer()

def inner():
    print("X")
  1. «X» y después «Y»
  2. Solo «Y», seguido de un NameError
  3. Ninguna salida; se produce NameError dentro de outer.
  4. Solo «X», seguido de un NameError
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 4 de 10

¿Cuál es la salida completa, incluidos los saltos de línea?

print("N", "S", sep="/", end="|")
print("E", "W", sep="-")
  1. Dos líneas: «N/S|» y después «E-W»
  2. Una línea: «N/S|E-W»
  3. Una línea: «N S|E W»
  4. Dos líneas: «N/S» y después «|E-W»
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 5 de 10

Una llamada nueva que omita items debe empezar con una lista nueva, pero una lista proporcionada debe ampliarse sobre el objeto original. ¿Qué cuerpo de sustitución es correcto?

def add_code(code, items=None):
    # replacement body
  1.     items = []
        items.append(code)
        return items
    
  2.     if items == []:
            items = []
        items.append(code)
        return items
    
  3.     if items is None:
            return []
        items.append(code)
        return items
    
  4.     if items is None:
            items = []
        items.append(code)
        return items
    
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 6 de 10

¿Qué cambio permite que esta función devuelva el primer candidato que cumpla la condición, o None solo después de que fallen todos los candidatos?

def find_divisor(n):
    for d in range(3, n):
        if n % d == 0:
            return d
        else:
            return None
  1. Cambiar return None por return False en el else.
  2. Eliminar el else y colocar return None después del bucle.
  3. Colocar ambas sentencias return después del bucle.
  4. Mover return d antes de la condición if dentro del bucle.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 7 de 10

¿Cómo puede el código que realiza la llamada actualizar stock explícitamente sin que la función auxiliar modifique una variable global?

stock = 18

def remove(stock, amount):
    return stock - amount

# caller statement
  1. remove(stock, 4)
  2. stock = remove(4, stock)
  3. stock = remove(stock, 4)
  4. remove(stock=4, amount=stock)
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 8 de 10

Una función auxiliar provisional solo contiene una cadena de documentación y pass. El código que la llama suma su resultado a 7 y obtiene TypeError. ¿Qué debe implementarse a continuación?
  1. Devolver el resultado numérico que promete la tarea de la función auxiliar.
  2. Mostrar el número prometido antes de la sentencia pass.
  3. Mover la cadena de documentación debajo de pass para que sea ejecutable.
  4. Repetir la llamada a la función auxiliar antes de sumar su resultado a 7.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 9 de 10

¿Qué se muestra?

def add_fee(amount):
    return amount + 3

def twice(amount):
    return amount * 2

print(twice(add_fee(5)))
  1. «13»
  2. «8»
  3. «10»
  4. «16»
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 10 de 10

¿Qué se muestra?

rate = 2

def scale(value, factor=rate):
    return value * factor

def reset():
    global rate
    rate = 5

reset()
print(scale(3), scale(3, rate))
  1. «15 15»
  2. «6 6»
  3. «6 15»
  4. «15 6»
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

¿Te atascas con una pregunta tuya? Ayuda con Tareas

Términos Clave

56 Términos Clave, cada uno con su definición

A

Abstracción procedimental
La abstracción procedimental permite que el código use una función mediante su tarea acordada sin depender de cómo realiza esa tarea su cuerpo.
El código que realiza una llamada puede usar letter_grade(avg) sin seguir cada comparación de umbrales del cuerpo.
Argumento
Un argumento es un valor proporcionado en una llamada a función, después de evaluar cualquier expresión que produzca ese valor.
En area(side + 1, 2), Python calcula el primer argumento antes de iniciar el cuerpo de la función de área.
Argumento por palabra clave
Un argumento por palabra clave nombra su parámetro de destino en una llamada, así que la asociación depende del nombre en lugar de la posición.
La llamada describe_pet(name="Milo", animal="cat") ocupa los parámetros en un orden fácil de leer.
Argumento posicional
Un argumento posicional se asocia a un parámetro por su orden en una llamada, de modo que el primer valor ocupa la primera posición.
Para describe_pet(animal, name), describe_pet("cat", "Milo") coloca «cat» en animal.

Á

Ámbito
El ámbito es la parte de un programa donde puede usarse un nombre y determina qué variable identifica una referencia.
Un nombre creado solo dentro de make_greeting() no está disponible para un print del nivel superior después de la llamada.

C

Cabecera
La cabecera de una función es la línea inicial que contiene def, el nombre de la función, los paréntesis de los parámetros y dos puntos.
En def print_line(length):, la cabecera da nombre a la tarea y a su entrada antes de que empiece el cuerpo.
Cadena de documentación
Una cadena de documentación es la cadena situada como primera sentencia del cuerpo de una función, que se guarda con ella para describir su uso a quienes la llaman.
La cadena de documentación de un conversor puede explicar las unidades de temperatura de entrada y salida antes de que alguien lea la fórmula.
Cadena de documentación de una línea
Una cadena de documentación de una línea es una frase imperativa breve, por convención entre comillas dobles triples y terminada en punto.
«Devuelve el área de un rectángulo.» describe la tarea sin repetir la firma de la función.
Cadena de documentación de varias líneas
Una cadena de documentación de varias líneas tiene un resumen, una línea en blanco y más detalles sobre entradas, valores predeterminados, resultados y efectos.
Una función para repartir una cuenta puede documentar que tip_rate=0.2 es una fracción de la cuenta y no 20.
Código que realiza la llamada
El código que realiza la llamada es el código que invoca una función y espera a que termine antes de continuar después de la llamada.
Cuando banner() llama a line(), el cuerpo de banner es el código que realiza la llamada a la función que dibuja la línea.
Constante
Una constante es un ajuste que debe permanecer fijo; la convención de Python escribe en mayúsculas los nombres de constantes del nivel del archivo.
Una función puede leer TAX_RATE = 0.25 para calcular un impuesto sin declarar global ese nombre.
Cuerpo de la función
El cuerpo de la función es el bloque de sentencias con sangría situado debajo de su cabecera, que se recorre desde el principio en cada llamada.
Dos líneas de print con sangría debajo de def greet(): pertenecen al cuerpo de la función.

D

Definición de función
Una definición de función es una sentencia def con una cabecera y un cuerpo con sangría que crea una función con un nombre.
Python crea greet en def greet(): y espera a una llamada antes de ejecutar su cuerpo.
Desarrollo incremental
El desarrollo incremental construye un programa mediante pequeñas incorporaciones y comprueba cada parte antes de conectar más trabajo.
Comprobar primero una función auxiliar de media reduce el código que revisar cuando un informe de calificaciones posterior falla.
Descomposición
La descomposición divide un problema en tareas más pequeñas que pueden implementarse, entenderse y comprobarse individualmente como funciones.
Un programa de informes de puntuaciones separa la lectura de puntuaciones, el cálculo de una media y la elección de una calificación.
Desempaquetado
El desempaquetado asigna los valores individuales de un resultado agrupado a los nombres correspondientes, conservando su orden original.
Si share(17, 5) devuelve 17 // 5, 17 % 5, la asignación each, left = share(17, 5) coloca 3 en each y 2 en left.

E

end
El parámetro end de print controla el texto que se añade después de los valores mostrados y usa un salto de línea de forma predeterminada.
Usar end="..." permite que el siguiente print continúe después de los puntos en lugar de empezar una línea nueva.
Esbozo de función
Un esbozo de función es una función sin terminar con la cabecera prevista y un cuerpo provisional que permite ejecutar el código que la llama durante el desarrollo.
Una cadena de documentación y pass crean un esbozo válido, aunque sus llamadas siguen devolviendo None hasta que se implemente.
Estado oculto
El estado oculto es información de la que una función depende o que modifica sin mostrarla mediante sus parámetros y el resultado devuelto.
Una función que actualiza un total global necesita que ese total esté preparado antes de una comprobación independiente.

F

Flujo de ejecución
El flujo de ejecución es el orden en que se ejecutan las sentencias, incluidos los saltos a funciones y los retornos al código que las llama.
Un informe puede mostrar «Start», entrar en banner(), terminar sus llamadas a funciones auxiliares y después mostrar «End».
Función
Una función es un bloque de código con nombre que realiza una tarea cuando se llama, lo que permite reutilizar la misma lógica en un programa.
Un programa de recibos puede llamar a print_receipt() cada vez que necesite mostrar otro recibo.
Función booleana
Una función booleana responde a una pregunta de sí o no devolviendo True o False, a menudo directamente a partir de una comparación.
El cuerpo return n % 2 == 0 permite usar is_even(n) directamente como condición de un if.
Función con valor de retorno útil
Una función con valor de retorno útil devuelve un resultado útil que el código que la llama puede usar en una expresión, asignación o condición.
Un conversor de temperatura que devuelve un número puede proporcionar datos a una tabla en pantalla o a una comparación con un límite.
Función sin valor de retorno útil
Una función sin valor de retorno útil es una función usada para producir un efecto, como mostrar algo, que no proporciona ningún resultado útil más allá de None.
Una función de saludo puede mostrar «Hello!» correctamente aunque el código que la llama reciba None.

H

help
La función help muestra información sobre una función, incluidas su firma y su cadena de documentación guardada, si la hay.
Usa help(to_fahrenheit) para consultar el conversor sin proporcionarle primero una temperatura.

I

Interfaz
La interfaz de una función consta de su nombre, sus parámetros, su resultado devuelto y su comportamiento documentado: el acuerdo que usa el código que la llama.
Un cálculo puede reescribirse sin modificar las llamadas si la interfaz sigue proporcionando el mismo resultado prometido.

L

Llamada a función
Una llamada a función es una expresión que ejecuta una función y se escribe con su nombre y unos paréntesis que contienen los argumentos, si los hay.
La línea greet() ejecuta el saludo, mientras que una línea que solo contiene greet no lo hace.
Llamada anidada
Una llamada anidada es una llamada a función dentro de la expresión de un argumento de otra llamada, cuyo resultado se necesita antes de ejecutar la llamada externa.
En print(to_fahrenheit(add(10, 15))), se ejecuta la suma antes de la conversión y después se muestra el resultado.

M

main
Una función main coordina las tareas más pequeñas de un programa y conecta las entradas, los resultados de las funciones auxiliares y la salida final en pantalla.
Una llamada final a main() ejecuta los pasos de un informe de puntuaciones después de que se hayan ejecutado todas las definiciones de las funciones auxiliares.
Mutación
La mutación modifica el contenido de un objeto existente, de modo que otro nombre que haga referencia al mismo objeto puede observar ese cambio.
Añadir «Ben» mediante un parámetro de lista modifica la lista de invitados que pasó el código que realiza la llamada.

N

None
None es el valor especial de Python que significa «sin valor» y también sirve como señal de que se ha omitido una entrada opcional.
Con basket=None, la función puede crear una lista nueva dentro de if basket is None:.

O

Ocultación de nombres
La ocultación de nombres ocurre cuando un nombre local oculta uno global con la misma escritura dentro de una función sin sustituir la vinculación global.
Si una función auxiliar asigna x = 5 localmente mientras que x = 10 es global, la x de la función auxiliar produce 5 y una x global posterior sigue produciendo 10.

P

Parámetro
Un parámetro es un nombre de la cabecera de una función que recibe el valor de un argumento como variable local para una llamada.
La cabecera def area(width, height): proporciona a cada llamada de área nombres locales para sus dos dimensiones.
Parámetro obligatorio
Un parámetro obligatorio no tiene valor predeterminado y debe recibir un valor en cada llamada válida, por posición o mediante una palabra clave aceptada.
Con def greet(name, greeting="Hello"):, omitir name causa un error por falta de un argumento.
Parámetro opcional
Un parámetro opcional tiene un valor predeterminado, lo que permite omitirlo en una llamada o sustituir ese valor mediante un argumento explícito.
Una llamada a una función para pedir café puede establecer milk="oat" mientras deja un parámetro opcional anterior de cantidad de dosis de café con su valor predeterminado.
Paso combinado de argumentos posicionales y por palabra clave
El paso combinado de argumentos posicionales y por palabra clave proporciona algunos valores por posición y otros por palabra clave, con los valores posicionales primero.
En describe_pet("cat", name="Milo"), la primera posición se ocupa por posición y la segunda por nombre.
pass
La sentencia pass es un marcador provisional que no realiza ninguna acción y permite que el cuerpo de una función prevista sea código Python válido.
Una función que solo contiene pass puede llamarse mientras aún se está escribiendo su comportamiento real de salida en pantalla.
Pila de llamadas
La pila de llamadas es el registro de Python de las llamadas que han empezado pero no han terminado, incluido dónde se reanuda el código que las llama.
Mientras se ejecuta una función auxiliar de líneas dentro de una llamada a banner, ambas llamadas sin terminar ocupan un lugar en la pila de llamadas.
Prueba de valores límite
Una prueba de valores límite comprueba una entrada situada exactamente en un límite de decisión, a menudo junto con un valor cercano que sigue la otra ruta.
Las puntuaciones 90 y 89,9 revelan una condición de calificación que usa por accidente > en lugar de >=.

R

Reasignación
La reasignación da a un nombre existente un valor u objeto nuevo; reasignar un parámetro cambia esa vinculación local.
La línea points = points + 10 modifica el parámetro local y deja intacta la puntuación del código que realiza la llamada.
Resultado esperado
Un resultado esperado es una respuesta obtenida de forma independiente antes de una comprobación, que se usa para evaluar lo que realmente devuelve una función.
Calcular una media a mano te permite detectar una salida del programa que parece plausible pero es incorrecta.
Retorno anticipado
Un retorno anticipado termina una función antes de ejecutar sus sentencias posteriores, a menudo cuando una rama o una búsqueda ya ha encontrado la respuesta.
Una búsqueda de divisores devuelve 7 para 91 en cuanto ese candidato lo divide exactamente y termina también el bucle.
Ruta de retorno
Una ruta de retorno es un recorrido por las ramas y los bucles de una función que llega a una sentencia return o al final del cuerpo.
Una función de signo necesita un resultado para cero, además de las rutas que devuelven etiquetas de positivo y negativo.

S

Salida de depuración
Una salida de depuración muestra temporalmente un valor mientras se investiga un error de programación y se elimina cuando termina la investigación.
Un print en la primera línea puede revelar la puntuación inesperada que llega a una función auxiliar desde el código que la llama.
Sentencia global
La sentencia global hace que un nombre dentro de una función se refiera a la vinculación del nivel del archivo en las lecturas y asignaciones posteriores.
Coloca global total antes de que la función use total para actualizar un contador acumulado compartido.
Sentencia return
Una sentencia return termina la llamada actual a función y envía su resultado al código que la llamó; sin una expresión, envía None.
La sentencia return width * height permite que el código que realiza la llamada guarde un área o la use en otro cálculo.
sep
El parámetro sep de print controla el texto que se inserta entre los valores mostrados y usa un espacio de forma predeterminada.
La llamada print("a", "b", "c", sep="-") muestra las tres letras como «a-b-c».

T

Traza de la excepción
Una traza de la excepción es un informe de error que muestra la ruta de llamadas sin terminar, la línea que falla y el tipo de error y mensaje finales.
En un traceback, lee primero el error final y después revisa la línea de la función auxiliar que falla y el código que le proporcionó las entradas al llamarla.
Tupla
Una tupla es una secuencia agrupada de valores; los valores separados por comas en un return forman una sola tupla como resultado para el código que realiza la llamada.
La sentencia return total // people, total % people agrupa una parte del reparto y un resto.
TypeError
Un TypeError informa de una operación inadecuada sobre un valor o de una llamada con una combinación de argumentos no válida.
Llamar a una función de dos parámetros con un argumento lanza TypeError por la entrada que falta.

U

UnboundLocalError
Un UnboundLocalError se produce cuando una función intenta leer un nombre local antes de que ese nombre tenga un valor.
Una asignación posterior a count hace que un print(count) anterior también sea local, aunque exista una variable global.

V

Valor de retorno
Un valor de retorno es el resultado que una llamada proporciona al código que la realiza, donde puede guardarse, comprobarse o pasarse a otra operación.
Después de area = rectangle_area(4, 2.5), area contiene el resultado devuelto 10,0 para usarlo más adelante.
Valor predeterminado
Un valor predeterminado es un valor que se guarda para un parámetro al ejecutar la definición y se usa cuando una llamada omite ese argumento.
En def greet(name, greeting="Hello"):, una llamada puede omitir el saludo y seguir proporcionando el nombre.
Valor predeterminado mutable
Un valor predeterminado mutable es un objeto predeterminado guardado cuyo contenido puede cambiar, por lo que las llamadas que omiten el argumento pueden compartir cambios anteriores.
Añadir un elemento a una lista de cesta predeterminada puede dejar ese elemento visible durante la siguiente llamada.
Variable global
Una variable global pertenece al ámbito global de un archivo y las funciones de ese archivo pueden leerla según las reglas de búsqueda de nombres.
Un x = 10 del nivel superior sigue valiendo 10 cuando una función auxiliar asigna su propia variable local independiente x = 5.
Variable local
Una variable local pertenece a una llamada a función e incluye sus parámetros y los nombres ordinarios a los que se asignan valores en esa función.
Cada llamada puede inicializar su propio count = 0, así que dos llamadas pueden mostrar el valor 1 de forma independiente.

Sobre esta unidad

Por StudeliInformar de un error

Crea tus propios Materiales de Estudio

Convierte tus notas, diapositivas y documentos en Guías de Estudio, Preguntas de Práctica, Flashcards y 6 herramientas más.

Comenzar