#!/usr/bin/env python
# coding: utf-8
#
# # Clase 1b: Ejercicios prácticos
# _En esta clase vamos a afianzar los conocimientos de Python que acabamos de adquirir haciendo algunos ejercicios, y así retener las peculiaridades de la sintaxis y aclarar algunos detalles a tener en cuenta cuando se trabaja en modo interactivo._
# ## Funciones
# Lo más importante para programar, y no solo en Python, es saber organizar el código en piezas más pequeñas que hagan tareas independientes y combinarlas entre sí. Las **funciones** son el primer nivel de organización del código: reciben unas *entradas*, las *procesan* y devuelven unas *salidas*.
# ![Black box](../static/blackbox.jpg)
# ### Ejercicio 1: Función de una entrada
# Vamos a crear una función que compruebe si un número es mayor o menor que cinco. La salida ahora no nos importa mucho: lo importante es que al declarar los argumentos de entrada en la definición de la función, podremos usarlos dentro de ella con el nombre que decidamos.
#
¡No olvides los dos puntos! Si el sangrado del código no avanza automáticamente, es que te los has dejado.
# In[1]:
def comparar_cinco(num):
if num < 5:
return "El número es menor que cinco"
elif num == 5:
return "El número es igual a cinco"
else:
return "El número es mayor que cinco"
# In[2]:
print(comparar_cinco(2))
# In[3]:
mi_numero = 7 # Aquí la variable se llama `mi_numero`
print(comparar_cinco(mi_numero)) # ¡Dentro de la función eso me da igual!
# Apuntes:
#
#
- Podríamos haber puesto un `elif num > 5` en la última parte en vez de un `else`. En este caso es obvio, pero en otros puede no ser tan evidente.
# - Algunos prefieren sacar los `return` fuera del condicional, o incluso que solo haya uno. http://stackoverflow.com/q/9191388/554319 ¡Cuestión de gustos!
#
#
#
# ### Ejercicio 2: Sumatorio
# Vamos a escribir ahora una función que sume los `n` primeros números naturales. Observa que podemos escribir una **cadena de documentación** (_docstring_) justo debajo de la definición de la función para explicar lo que hace.
# In[4]:
def sumatorio(num):
"""Suma los `num` primeros números.
Ejemplos
--------
>>> sumatorio(4)
10
"""
suma = 0
for nn in range(1, num + 1):
suma = nn + suma
return suma
# Lo que hemos hecho ha sido inicializar el valor de la suma a 0 e ir acumulando en ella los `num` primeros números naturales.
# In[5]:
sumatorio(4)
# In[6]:
help(sumatorio)
# Observa lo que sucede si no inicializamos la suma:
# In[7]:
def sumatorio_mal(num):
for nn in range(1, num + 1):
suma = nn + suma
return suma
# In[8]:
sumatorio_mal(4)
# Para comprobar el resultado correcto, nada como acudir a la función `sum` de Python, que suma los elementos que le pasemos:
# In[9]:
list(range(1, 4 + 1))
# In[10]:
sum(range(1, 4 + 1))
# ### Ejercicio 3: Sumatorio con cota superior
# Ahora nuestra función es un poco más rara: tiene que sumar los $n$ primeros números naturales y no pasarse de un determinado límite. Además, queremos el valor de la suma.
# In[11]:
def suma_tope(tope):
"""Suma números naturales consecutivos hasta un tope.
"""
suma = 0
nn = 1
while suma + nn <= tope:
suma = suma + nn
nn += 1
return suma
# In[12]:
suma_tope(9)
# In[13]:
suma_tope(9) == 1 + 2 + 3
# In[14]:
suma_tope(10) == 1 + 2 + 3 + 4
# La palabra clave `assert` recibe una expresión verdadera o falsa, y falla si es falsa. Si es verdadera no hace nada, con lo cual es perfecto para hacer comprobaciones a mitad del código que no estorben mucho.
# In[15]:
assert suma_tope(11) == 1 + 2 + 3 + 4
# In[16]:
assert suma_tope(10 + 5) == 1 + 2 + 3 + 4
# ### Ejercicio 4: Normativa de exámenes
# La normativa de exámenes de la UPM es: *"si un examen dura más de 3 horas, entonces debe tener un descanso"*. Los argumentos de la función son el tiempo en horas y un valor `True` o `False` que indica si hay descanso o no, y la función devuelve si el examen cumple o no con la normativa.
# In[17]:
def cumple_normativa(tiempo, descanso):
"""Comprueba si un examen cumple la normativa de la UPM.
"""
if tiempo <= 3:
return True
else:
#if descanso:
# return True
#else:
# return False
return descanso # ¡Equivalente!
# In[18]:
cumple_normativa(2, False)
# In[19]:
if not cumple_normativa(5, descanso=False):
print("¡Habla con Delegación de Alumnos!")
# ### Ejercicio 5
# Hallar $x = \sqrt{S}$.
#
# 1. $\displaystyle \tilde{x} \leftarrow \frac{S}{2}$.
# 2. $\displaystyle \tilde{x} \leftarrow \frac{1}{2}\left(\tilde{x} + \frac{S}{\tilde{x}}\right)$.
# 3. Repetir (2) hasta que se alcance un límite de iteraciones o un criterio de convergencia.
#
# http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
# In[20]:
def raiz(S):
x = S / 2
while True:
temp = x
x = (x + S / x) / 2
if temp == x:
return x
# Aquí estoy usando un truco de la aritmética en punto flotante: como la convergencia se alcanza rápidamente, llega un momento en que el error es menor que la precisión de la máquina y el valor no cambia de un paso a otro.
# In[21]:
raiz(10)
# Se deja como ejercicio implementar otras condiciones de convergencia: error relativo por debajo de un umbral o número máximo de iteraciones.
# In[22]:
import math
math.sqrt(10)
# In[23]:
raiz(10) ** 2
# In[24]:
math.sqrt(10) ** 2
# Ahora tienes curiosidad, ¿verdad? :) http://puntoflotante.org/
# ### Ejercicio 6
# Secuencia de Fibonacci: $F_n = F_{n - 1} + F_{n - 2}$, con $F_0 = 0$ y $F_1 = 1$.
#
# $$0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...$$
# Con iteración:
# In[25]:
def fib(n):
a, b = 0, 1
for i in range(n):
a, b = b, a + b # Bendita asignación múltiple
return a
# In[26]:
fib(0), fib(3), fib(10)
# Con recursión:
# In[27]:
def fib_recursivo(n):
if n == 0:
res = 0
elif n == 1:
res = 1
else:
res = fib_recursivo(n - 1) + fib_recursivo(n - 2)
return res
# Imprimir una lista con los $n$ primeros:
# In[28]:
def n_primeros(n):
F = fib_recursivo
lista = []
for ii in range(n):
lista.append(F(ii))
return lista
# In[29]:
n_primeros(10)
# ---
# _En esta clase hemos visto cómo crear funciones que encapsulen tareas de nuestro programa y las hemos aplicado para respondernos ciertas preguntas sencillas._
#
# **Referencias**
#
# * Libro "Learn Python the Hard Way" http://learnpythonthehardway.org/book/
# * Python Tutor, para visualizar código Python paso a paso http://pythontutor.com/
# * Libro "How To Think Like a Computer Scientist" http://interactivepython.org/runestone/static/thinkcspy/toc.html
# * Project Euler: ejercicios para aprender Python https://projecteuler.net/problems
# * Python Challenge (!) http://www.pythonchallenge.com/
# Si te ha gustado esta clase:
#
#
#
#
# ---
# #### ¡Síguenos en Twitter!
# ######
# #####
Curso AeroPython por Juan Luis Cano Rodriguez y Alejandro Sáez Mollejo se distribuye bajo una Licencia Creative Commons Atribución 4.0 Internacional.
# #####
# ---
# _Las siguientes celdas contienen configuración del Notebook_
#
# _Para visualizar y utlizar los enlaces a Twitter el notebook debe ejecutarse como [seguro](http://ipython.org/ipython-doc/dev/notebook/security.html)_
#
# File > Trusted Notebook
# In[2]:
get_ipython().run_cell_magic('html', '', '\n\n')
# In[1]:
# Esta celda da el estilo al notebook
from IPython.core.display import HTML
css_file = '../static/styles/style.css'
HTML(open(css_file, "r").read())