Tracks
/
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 con tipado dinámico y fuerte. Además, emplea tanto duck typing como tipado gradual mediante anotaciones de tipo.

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

Profundizaremos en lo que significa todo eso a medida que avancemos por la pista.

Este primer ejercicio presenta 4 características principales 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 de la pista 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 enfática) de que no haya nombres de variables de una sola letra ni variables llamadas «_».

En la pista de Python, las variables siempre se escriben en snake_case, y las constantes en SCREAMING_SNAKE_CASE.


Asignación de nombres (variables y constantes)

Quien programa puede 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 revincular) 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 que están pensados para asignarse solo una vez en un programa. Se deben definir a nivel de módulo (archivo) y, por lo general, son visibles para todas las funciones y clases del programa. Usar SCREAMING_SNAKE_CASE indica que el nombre no se debe reasignar ni se debe modificar su valor.

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 sentencias del cuerpo de la función empiezan en la línea que sigue a def y deben estar indentadas 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 devuelven implícitamente el objeto None. Los detalles de None se verán en un ejercicio posterior. Para este ejercicio y 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 devuelven 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 comentarios de varias líneas. Cada línea de un bloque de comentarios debe empezar con el carácter #.

Docstrings

La primera sentencia del cuerpo de una función puede ser, de forma opcional, un docstring, que resume de manera concisa el propósito de la función o del objeto. Los docstrings se declaran usando triples comillas dobles (""") indentadas 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 son leídos por herramientas automáticas de documentación como Sphinx y se devuelven al llamar al atributo especial .__doc__ del nombre de la función, el método o la clase. Las convenciones generales de los docstrings están descritas 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, lo cual se verá 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 algo de código para ayudarte a cocinar una lasaña espectacular de tu libro de cocina favorito.

Tienes cinco tareas, todas relacionadas con cocinar tu receta.


Note

Ya iniciamos la primera definición de función para ti en el archivo stub, pero tendrás que escribir tú mismo el resto de las definiciones de función. También tendrás que definir las constantes por tu cuenta. Lee con atención las líneas de comentario #TODO del archivo stub. 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 cocina, la lasaña debe estar en el horno durante 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 reales que la lasaña ha estado en el horno y devuelve cuántos minutos le falta todavía por hornear, con base en 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 agregar 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 que se agregan a la lasaña)
  • elapsed_bake_time (el número de minutos que la lasaña ya ha pasado horneándose en el horno).

Esta función debe devolver el total de minutos que has estado cocinando en la cocina: tu tiempo de preparación armando las capas más el tiempo que la lasaña ha pasado 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

Repasa la receta y agrega «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 una pestaña nuevas
Python Exercism

¿Todo 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.