Rutas
/
Python
Python
/
Ejercicios
/
La magnífica lasaña de Guido
La magnífica lasaña de Guido

La magnífica lasaña de Guido

Ejercicio de aprendizaje

Introducción

Python es un lenguaje de programación de tipado dinámico y fuerte. Emplea tanto el duck typing como el tipado gradual mediante las anotaciones de tipo.

Aunque Python admite muchos estilos de programación diferentes, internamente todo en Python es un objeto. Esto incluye números, strings, arrays e incluso funciones.

Profundizaremos en qué significa todo esto a medida que avancemos por el track.

Este primer ejercicio presenta 4 características fundamentales del lenguaje Python:

  1. Asignación de nombres (variables y constantes),
  2. Funciones (la palabra clave def y la palabra clave return),
  3. Comentarios, y
  4. Docstrings.

Note

En general, el contenido, las pruebas y las herramientas de análisis del track de Python siguen las convenciones de estilo descritas en PEP 8 y PEP 257 para el estilo del código Python, con la sugerencia adicional (y firme) de que no haya nombres de variable de una sola letra ni variables llamadas "_".

En el track de Python, las variables siempre se escriben en snake_case, y las constantes en SCREAMING_SNAKE_CASE.


Asignación de nombres (variables y constantes)

Los programadores pueden vincular nombres (también llamados variables) a cualquier tipo de objeto usando el operador de asignación =: <name> = <value>. Un nombre se puede reasignar (o volver a vincular) a valores diferentes (tipos de objeto diferentes) a lo largo de su vida.

>>> my_first_variable = 1  #<-- my_first_variable bound to an integer object of value one.
>>> my_first_variable = 2  #<-- my_first_variable re-assigned to integer value 2.

>>> print(type(my_first_variable))
<class 'int'>

>>> print(my_first_variable)
2

>>> my_first_variable = "Now, I'm a string." #<-- You may re-bind a name to a different object type and value.
>>> print(type(my_first_variable))
<class 'str'>

>>> my_first_variable = 'You can call me "str".' #<-- Strings can be declared using single or double quote marks.
>>> print(my_first_variable)
You can call me "str".

Constantes

Las constantes son nombres pensados para asignarse solo una vez en un programa. Deben definirse a nivel de módulo (fichero) y, por lo general, son visibles para todas las funciones y clases del programa. Usar SCREAMING_SNAKE_CASE indica que el nombre no debe reasignarse ni su valor modificarse.

Funciones

La palabra clave def inicia una definición de función. Cada función puede tener cero o más parámetros formales entre paréntesis (), seguidos de dos puntos :. Las instrucciones del cuerpo de la función comienzan en la línea siguiente a def y deben estar sangradas en un bloque.

# The body of a function is indented by 2 spaces, & prints the sum of the numbers.
def add_two_numbers(number_one, number_two):
  total = number_one + number_two
  print(total)  

>>> add_two_numbers(3, 4)
7


# Inconsistent indentation in your code blocks will raise an error.
>>> def add_three_numbers_misformatted(number_one, number_two, number_three):
...     result = number_one + number_two + number_three   # This was indented by 4 spaces.
...    print(result)     #this was only indented by 3 spaces
...
...
  File "<stdin>", line 3
    print(result)
    ^
IndentationError: unindent does not match any outer indentation level

Las funciones devuelven explícitamente un valor u objeto mediante la palabra clave return:

# Function definition on first line, explicit return used on final line.
>>> def add_two_numbers(number_one, number_two):
        return number_one + number_two   


# Calling the function in the Python shell returns the sum of the numbers.
>>> add_two_numbers(3, 4)
7

# Assigning the function call to a variable and printing it 
# will also return the value.
>>> sum_with_return = add_two_numbers(5, 6)
>>> print(sum_with_return)
11

Las funciones que no tienen una expresión explícita después de un return devolverán implícitamente el objeto None. Los detalles de None se tratarán en un ejercicio posterior. A efectos de este ejercicio y de esta explicación, None es un marcador de posición que representa nada, o null:


# This function will return `None`
def square_a_number(number):
    square = number * number
    return # <-- note that this return is not followed by an expression

# Calling the function in the Python shell appears 
# to not return anything at all.
>>> square_a_number(2)
>>>


# Using print() with the function call shows that 
# the function is actually returning the **None** object.
>>> print(square_a_number(2))
None

Las funciones que omiten return también devolverán implícitamente el objeto None. Esto significa que, si no usas return en una función, Python devolverá el objeto None por ti.

# This function omits a return keyword altogether.
def add_two_numbers(number_one, number_two):
  result = number_one + number_two

>>> add_two_numbers(5, 7)
>>> print(add_two_numbers(5, 7))
None

# Assigning the function call to a variable and printing 
# the variable will also show None.
>>> sum_without_return = add_two_numbers(5, 6)
>>> print(sum_without_return)
None

Llamar a funciones

Las funciones se llaman o se invocan usando su nombre seguido de (). La notación de punto (.) se usa para llamar a funciones definidas dentro de una clase o un módulo.

>>> def raise_to_power(number, power):
...     return number ** power
...

>>> raise_to_power(3,3) # <--Invoking the function with the arguments 3 and 3.
27


# A mismatch between the number of parameters and the number of arguments will raise an error.
>>> raise_to_power(4,)
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: raise_to_power() missing 1 required positional argument: 'power'


# Calling methods or functions in classes and modules.
>>> start_text = "my silly sentence for examples."
>>> str.upper(start_text)  # <--Calling the upper() method from the built-in str class on start_text.
'MY SILLY SENTENCE FOR EXAMPLES.'


# Importing the math module
>>> import math

>>> math.pow(2,4)  # <--Calling the pow() function from the math module.
16.0

Comentarios

Los comentarios en Python empiezan con un # que no forma parte de un string y terminan al final de la línea. A diferencia de muchos otros lenguajes de programación, Python no admite marcas de comentario multilínea. Cada línea de un bloque de comentarios debe empezar con el carácter #.

Docstrings

La primera instrucción del cuerpo de una función puede ser, opcionalmente, un docstring, que resume de forma concisa el propósito de la función o del objeto. Los docstrings se declaran usando triples comillas dobles (""") sangradas al mismo nivel que el bloque de código:


# An example from PEP257 of a multi-line docstring
# reformatted to use Google style non-type hinted docstrings.
# Some additional details can be found in the Sphinx documentation:
# https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html#getting-started

def complex(real=0.0, imag=0.0):
    """Form a complex number.

    Keyword Arguments:
        real (float): The real part of the number (default 0.0)
        imag (float): The imaginary part of the number (default 0.0)
        
    """

    if imag == 0.0 and real == 0.0:
        return complex_zero

Los docstrings los leen herramientas de documentación automatizadas como Sphinx y se devuelven llamando al atributo especial .__doc__ de la función, el método o la clase. Las convenciones generales de los docstrings se describen en PEP257, pero los formatos exactos varían según el proyecto y el equipo. Los ejercicios de concepto de Exercism intentan seguir el estilo de Google para código sin anotaciones de tipo.

Los docstrings también pueden funcionar como pruebas unitarias ligeras, algo que se tratará en un ejercicio posterior.

# An example on a user-defined function using a Google style docstring. 
>>> def raise_to_power(number, power):
    """Raise a number to an arbitrary power.

    Parameters:
        number (int): The base number.
        power (int): The power to raise the base number to.
    
    Returns:
        int: The number raised to the specified power.
    
    Takes a number and raises it to the specified power, returning the result.

    """

    return number ** power
...

# Calling the .__doc__ attribute of the function and printing the result.
>>> print(raise_to_power.__doc__)
Raise a number to an arbitrary power.

Parameters:
    number (int): The base number.
    power (int): The power to raise the base number to.

Returns:
    int: The number raised to the specified power.

Takes a number and raises it to the specified power, returning the result.

Instrucciones

Vas a escribir código para ayudarte a cocinar una lasaña magnífica de tu libro de recetas favorito.

Tienes cinco tareas, todas relacionadas con la preparación de tu receta.


Note

Hemos empezado por ti la primera definición de función en el fichero auxiliar, pero tendrás que escribir tú mismo el resto de las definiciones de función. También tendrás que definir tú mismo las constantes. Lee con atención las líneas de comentario #TODO del fichero auxiliar. Cuando termines una tarea, elimina el comentario TODO.


1. Define el tiempo de horneado esperado en minutos como una constante

Define la constante EXPECTED_BAKE_TIME, que representa cuántos minutos debe hornearse la lasaña en el horno. Según tu libro de recetas, la lasaña debe estar en el horno 40 minutos:

>>> print(EXPECTED_BAKE_TIME)
40

2. Calcula el tiempo de horneado restante en minutos

Completa la función bake_time_remaining(), que toma como argumento los minutos que la lasaña lleva en el horno y devuelve cuántos minutos más necesita hornearse según la constante EXPECTED_BAKE_TIME.

>>> bake_time_remaining(30)
10

3. Calcula el tiempo de preparación en minutos

Define la función preparation_time_in_minutes(), que toma como argumento el number_of_layers que quieres añadir a la lasaña y devuelve cuántos minutos tardarías en prepararlas. Supón que cada capa tarda 2 minutos en prepararse.

>>> def preparation_time_in_minutes(number_of_layers):
        ...
        ...
        
>>> preparation_time_in_minutes(2)
4

4. Calcula el tiempo total transcurrido (preparación + horneado) en minutos

Define la función elapsed_time_in_minutes(), que toma dos parámetros como argumentos:

  • number_of_layers (el número de capas añadidas a la lasaña)
  • elapsed_bake_time (el número de minutos que la lasaña ya lleva horneándose en el horno).

Esta función debe devolver el total de minutos que llevas en la cocina cocinando: tu tiempo de preparación colocando capas más el tiempo que la lasaña lleva horneándose en el horno.

>>> def elapsed_time_in_minutes(number_of_layers, elapsed_bake_time):
        ...
        ...
        
>>> elapsed_time_in_minutes(3, 20)
26

5. Actualiza la receta con notas

Vuelve a repasar la receta y añade «notas» en forma de docstrings de función.

def elapsed_time_in_minutes(number_of_layers, elapsed_bake_time):
    """Calculate the elapsed cooking time.
    
    Parameters:
        number_of_layers (int): The number of layers in the lasagna.
        elapsed_bake_time (int): Time the lasagna has been baking in the oven.
    
    Returns:
        int: The total time elapsed (in minutes) preparing and baking.

    This function takes two integers representing the number of lasagna 
    layers and the time already spent baking the lasagna. It calculates 
    the total elapsed minutes spent cooking (preparing + baking).
    
    """
Editar en GitHub El enlace se abre en una ventana o pestaña nueva
Python Exercism

¿Listo para empezar La magnífica lasaña de Guido?

Regístrate en Exercism para aprender y dominar Python con 17 conceptos146 ejercicios y mentoría humana real, todo gratis.