Ejercicios

Ejercicios de Clase 01

  1. Abra una terminal (consola) o notebook y utilícela como una calculadora para realizar las siguientes acciones:

    • Suponiendo que, de las cuatro horas de clases, tomamos dos descansos de 15 minutos cada uno y nos distraemos otros 13 minutos, calcular cuántos minutos efectivos de trabajo tendremos en las 16 clases.

    • Para la cantidad de alumnos presentes en el aula: ¿cuántas horas-persona de trabajo hay involucradas en este curso?

  2. Muestre en la consola de Ipython:

    • el nombre de su directorio actual

    • los archivos en su directorio actual

    • Cree un subdirectorio llamado tmp

    • si está usando linux, muestre la fecha y hora

    • Borre el subdirectorio tmp

  3. Para cubos de lados de longitud L = 1, 3, y 5: calcule su superficie y su volumen.

  4. Para esferas de radios r = 1, 3, 5 y 8, calcule su superficie y su volumen.

  5. Fíjese si alguno de los valores: \(x=0.49\), \(x=0.50\), \(x=0.51\) es un cero de la función \(f(x)=x^{2} + x/2 - 1/2\).

  6. Para el número complejo \(z= 1 + 0.5 i\)

    • Calcular \(z^2, z^3, z^4, z^5.\)

    • Calcular los complejos conjugados de \(z\), \(z^2\) y \(z^3\).

    • Escribir un programa que escriba las frases:

      • “El conjugado de z=1+0.5i es 1-0.5j”

      • “El conjugado de z=(1+0.5i)^2 es …” (con el valor correspondiente)

Ejercicios de Clase 02

  1. Escriba funciones que calculen:

  • El volumen de una esfera

  • El volumen de una caja de lados L1, L2, L3

  1. Escriba una función que tome como argumentos tres valores: a, b, c y calcule los ceros (raíces) del polinomio \(a x^{2} + b x + c\).

  2. Considere un polígono regular de \(N\) lados inscripto en un círculo de radio unidad:

    • Escriba una función que tome como argumento el número de lados \(N\) y calcule el ángulo interior del polígono regular correspondiente (por ejemplo el de un triángulo es 60 grados, de un cuadrado es 90 grados, y de un pentágono es 108 grados). Pruebe su función para valores de \(N= 3, 5, 6, 8, 9, 10, 12\).

    • ¿Puede calcular la longitud del lado de los polígonos regulares si se encuentran inscriptos en un círculo de radio unidad?

En todos los casos, pruebe las funciones escritas

  1. Para la cadena de caracteres:

s = '''Aquí me pongo a cantar
Al compás de la vigüela,
Que el hombre que lo desvela
Una pena estraordinaria
Como la ave solitaria
Con el cantar se consuela.'''
  • Forme un nuevo string de 10 caracteres que contenga los 5 primeros y los 5 últimos del string anterior s. Imprima por pantalla el nuevo string.

  • Forme un nuevo string que contenga los 10 caracteres centrales de s (utilizando un método que pueda aplicarse a otros strings también). Imprima por pantalla el nuevo string.

  • Cuente la cantidad de veces que aparecen los substrings es, la, que, co, en los siguientes dos casos: distinguiendo entre mayúsculas y minúsculas, y no distinguiendo. Imprima el resultado.

  • Cambie todas las letras “m” por “n” y todas las letras “n” por “m” en s. Imprima el resultado por pantalla.

  1. Utilizando funciones y métodos de strings en la cadena de caracteres:

    s1='En un lugar de la Mancha de cuyo nombre no quiero acordarme'
    
  • Obtenga la cantidad de caracteres.

  • Imprima la frase anterior pero con cada palabra empezando en mayúsculas.

  • Cuente cuantas letras ‘a’ tiene la frase, ¿cuántas vocales tiene?

  1. Centrado manual de frases

    1. Utilizando la función len() centre una frase corta en una pantalla de 80 caracteres. Utilice la frase: “Un ejercicio con cadena de caracteres”

    2. Agregue subrayado a la frase anterior

    3. Escriba una función que centre y subraye una frase dada como argumento. Se espera obtener algo así:

      Un ejercicio con cadena de caracteres
      -------------------------------------
      
    4. Repita el punto anterior utilizando métodos de strings

  2. Para Entregar: Manejos de listas:

    • Cree la lista N de longitud 50, donde cada elemento es un número entero de 1 a 50 inclusive (Ayuda: vea la expresión range).

    • Invierta la lista.

    • Extraiga de N una lista N1 que contenga sólo aquellos elementos que sean el cuadrado de algún número entero.

    • Extraiga de N una lista N2 que contenga sólo aquellos elementos que sean iguales al \(n^2-n\) para algún número entero \(n\).

    Ayuda: Puede resultar útil recordar el uso de comprensión de listas.

    Debe enviar por correo electrónico, con asunto “02_Suapellido”, un programa llamado 02_SuApellido.py (en todos los casos utilice su apellido, no la palabra “SuApellido”).

  3. Cree una lista de la forma L = [1,3,5,...,17,19,19,17,...,3,1] (Ayuda: vea la expresión range).

  4. Escriba una función que tome un número entero de tres cifras, y devuelva el mayor entero que se puede formar con esas cifras (Ayuda: considere convertir el número entero a otros tipos).

  5. Construya una lista L2 con 2000 elementos, todos iguales a 0.0005. Imprima su suma utilizando la función sum y comparar con el resultado que arroja la función que existe en el módulo math para realizar suma de números de punto flotante.

  6. Operación “rara” sobre una lista:

    • Defina la lista L = [0,1]

    • Realice la operación L.append(L)

    • Ahora imprima L, e imprima el último elemento de L.

    • Haga que una nueva lista L1 tenga el valor del último elemento de L y repita el inciso anterior.

Ejercicios de Clase 03

  1. Escribir, utilizando conjuntos (set), funciones que tomen como argumento un string y:

    1. Retorne verdadero si el argumento tiene algún número, Falso en otro caso,

    2. Retorne verdadero si el argumento está formado por todos números, Falso en otro caso.

  2. De los primeros 100 números naturales imprimir aquellos que no son divisibles por ninguno de: 2, 3, 5 o 7.

  3. Usando estructuras de control, calcule el valor de la suma:

    \[s_{1} = \frac{1}{2} \left(\sum_{k=1}^{100}k^{-1} \right)\]

    para los casos:

    1. Incluyendo todos los valores de k

    2. Incluyendo únicamente los valores pares de k.

  4. Escriba una función que estime la suma

    \[s_{2} = \sum_{k=1}^{\infty} \frac{(-1)^{k} (k+1)}{2 k^{3} + k^{2}}\]

    La función toma como argumentos un error relativo \(\epsilon\) deseado y devuelve el valor de la suma y el error relativo estimado. Pruebe su función para un valor \(\epsilon=10^{-5}\)

  5. Escriba una función que tome como argumento un párrafo de texto y devuelva un string con el párrafo en un “cartel” de un cierto ancho:

    cartelizar(parrafo, ancho)
    

    Por ejemplo, para el texto:

    s = "Ullam vel totam cum neque exercitationem ut. Quae omnis rerum sit reprehenderit accusamus. Molestiae molestiae sit totam sint. Neque pariatur temporibus ut minima accusantium. Ad perferendis natus nisi dolor. Et sint maiores exercitationem reiciendis ut ab et."
    
    sout = cartelizar(s, 60)
    

    debe devolver el string:

    sout = '* ******************************************************** *\n* Ullam vel totam cum neque exercitationem ut. Quae omnis  *\n*  rerum sit reprehenderit accusamus. Molestiae molestiae  *\n*   sit totam sint. Neque pariatur temporibus ut minima    *\n*  accusantium. Ad perferendis natus nisi dolor. Et sint   *\n* ******************************************************** *'
    

    que al imprimirlo se verá:

    print(sout)
    
    * ******************************************************** *
    * Ullam vel totam cum neque exercitationem ut. Quae omnis  *
    *  rerum sit reprehenderit accusamus. Molestiae molestiae  *
    *   sit totam sint. Neque pariatur temporibus ut minima    *
    *  accusantium. Ad perferendis natus nisi dolor. Et sint   *
    * ******************************************************** *
    
  6. En 1949, D. R. Kaprekar, un matemático de la India especializado en matemática recreacional, describió un algoritmo que consiste en:

    1. Tomar un número de cuatro cifras

    2. Reacomodar las cifras para obtener el mayor número posible

    3. Obtener reacomodando las cifras también el menor posible

    4. Restarlos

    5. GOTO 1

    Este algoritmo tiene un “punto fijo” igual a 6174 y es al que el algoritmo llega si se inicia con un número que no tiene las cifras repetidas. Si alguna cifra es repetida el punto fijo puede ser el trivial, igual a cero. Escribir una función rutina_kaprekar(numero) que tome un número de cuatro cifras y devuelva el punto fijo y el número de números necesarios hasta alcanzarlo.

    Por ejemplo: Para el número 1392, la secuencia es:

    1392 -> 8082 -> 8532 -> 6174 -> 6174 -> …

    por lo que tendremos al aplicar la función:

    rutina_kaprekar(1392)
    
    6174, 4
    

Consejo

Tenga en cuenta que si un número tiene menos de cuatro cifras debe agregarle ceros. Por ejemplo el número 978 debe entenderse como 0978 por lo que el mayor número que puede escribirse con estas cifras es 9870.

Ejercicios de Clase 04

  1. Un método para calcular el área de un polígono (no necesariamente regular) que se conoce como fórmula del área de Gauss o fórmula de la Lazada (shoelace formula) consiste en describir al polígono por sus puntos en un sistema de coordenadas. Cada punto se describe como un par \((x,y)\) y la fórmula del área está dada mediante la suma de la multiplicación de los valores en una diagonal a los que se le resta los valores en la otra diagonal, como muestra la figura

    _images/shoelace.png
    \[2 A = (x_{1} y_{2} + x_{2} y_{3} + x_{3} y_{4} + \dots) - (x_{2} y_{1} + x_{3} y_{2} + x_{4} y_{3} + \dots)\]
    _images/ejemplo_shoelace.png
    • Utilizando una descripción adecuada del polígono, escribir una función que implemente la fórmula de Gauss para calcular su área y aplicarla al ejemplo de la figura.

    • Verificar que el resultado no depende del punto de inicio.

  2. Escriba funciones para analizar la divisibilidad de enteros:

    • La función es_divisible que retorna True si el argumento x es divisible por alguno de los elemntos del segundo argumento: divisores. El argumento divisores es opcional y si está presente es una variable del tipo lista que contiene los valores para los cuáles debemos examinar la divisibilidad.

    El valor por defecto de divisores es [2,3,5,7]. Las siguientes expresiones deben retornar el mismo valor: python  es_divisible(x)   es_divisible(x, [2,3,5,7])

    • La función es_divisible_por cuyo primer argumento (mandatorio) es x, y luego puede aceptar un número indeterminado de argumentos:

    es_divisible_por(x)  # retorna verdadero siempre
    es_divisible_por(x, 2) # verdadero si x es par
    es_divisible_por(x, 2, 3, 5, 7) # igual resultado que es_divisible(x)
    es_divisible_por(x, 2, 3, 5, 7, 9, 11, 13)  # o cualquier secuencia de argumentos debe funcionar
    
  3. PARA ENTREGAR. Describimos una grilla de sudoku como un string de nueve líneas, cada una con 9 números, con números entre 1 y 9. Escribir un conjunto de funciones que permitan chequear si una grilla de sudoku es correcta. Para que una grilla sea correcta deben cumplirse las siguientes condiciones

    • Los números están entre 1 y 9

    • En cada fila no deben repetirse

    • En cada columna no deben repetirse

    • En todas las regiones de 3x3 que no se solapan, empezando de cualquier esquina, no deben repetirse

    1. Escribir una función que convierta un string con formato a una lista bidimensional. El string estará dado con nueve números por línea, de la siguiente manera (los espacios en blanco en cada línea pueden variar):

    sudoku = """145327698
            839654127
            672918543
            496185372
            218473956
            753296481
            367542819
            984761235
            521839764"""
    
    1. Escribir una función check_repetidos() que tome por argumento una lista (unidimensional) y devuelva verdadero si la lista tiene elementos repetidos y falso en caso contrario.

    2. Escribir la función check_sudoku() que toma como argumento una grilla (como una lista bidimensional de 9x9) y devuelva verdadero si los números corresponden a la resolución correcta del Sudoku y falso en caso contrario. Note que debe verificar que los números no se repiten en filas, ni en columnas ni en recuadros de 3x3. Para obtener la posición de los recuadros puede investigar que hacen las líneas de código:

    j, k = (i // 3) * 3, (i % 3) * 3
    r = [grid[a][b] for a in range(j, j+3) for b in range(k, k+3)]
    

    suponiendo que grid es el nombre de nuestra lista bidimensional, cuando i toma valores entre 0 y 8.

    Debe enviar por correo electrónico, con asunto “04_SuApellido”, un programa llamado 04_SuApellido.py (en todos los casos utilice su apellido, no la palabra “SuApellido”) .

  4. Escriba una función crear_sen(A, w) que acepte dos números reales \(A, w\) como argumentos y devuelva la función f(x).

Al evaluar la función f en un dado valor \(x\) debe dar el resultado: \(f(x) = A \sin(w x)\) tal que se pueda utilizar de la siguiente manera:

from math import pi
f = crear_sen(3, 2)
f(pi/2)
# Debería imprimir el resultado de 3*sin(2 * pi/2) aprox. cero
  1. Escriba una serie de funciones que permitan trabajar con polinomios. Vamos a representar a un polinomio como una lista de números reales, donde cada elemento corresponde a un coeficiente que acompaña una potencia. En cada caso elija los argumentos que considere necesario.

    • Una función que devuelva el orden del polinomio (un número entero)

    • Una función que sume dos polinomios y devuelva un polinomio (objeto del mismo tipo)

    • Una función que multiplique dos polinomios y devuelva el resultado en otro polinomio

    • Una función devuelva la derivada del polinomio (otro polinomio).

    • Una función que acepte el polinomio y devuelva la función correspondiente.

  2. Escriba una función direccion_media(ang1, ang2, ...) cuyos argumentos son direcciones en el plano, expresadas por los ángulos en grados a partir de un cierto eje, y calcule la dirección promedio, expresada en ángulos. Pruebe su función con las listas:

    a1 = direccion_media(0, 180, 370, 10)
    a2 = direccion_media(30, 0, 80, 180)
    a3 = direccion_media(80, 180, 540, 280)
    
  3. Las funciones de Bessel de orden \(n\) cumplen las relaciones de recurrencia

    \[J_{n -1}(x)- \frac{2n }{x}\, J_{n }(x) + J_{n +1}(x) = 0\]
    \[J^{2}_{0}(x) + \sum_{n=1}^{\infty} 2 J^{2}_{n}(x) = 1\]

    Para calcular la función de Bessel de orden \(N\), se empieza con un valor de \(M \gg N\), y utilizando los valores iniciales \(J_{M}=1\), \(J_{M+1}=0\) se utiliza la primera relación para calcular todos los valores de \(n < M\). Luego, utilizando la segunda relación se normalizan todos los valores.

    Nota

    Estas relaciones son válidas si \(M \gg x\) (use algún valor estimado, como por ejemplo \(M=N+20\)).

    Utilice estas relaciones para calcular \(J_{N}(x)\) para \(N=3,4,7\) y \(x=2.5, 5.7, 10\). Para referencia se dan los valores esperados

    \[\begin{split}\begin{align} J_3( 2.5) = 0.21660\\ J_4( 2.5) = 0.07378\\ J_7( 2.5) = 0.00078\\ J_3( 5.7) = 0.20228\\ J_4( 5.7) = 0.38659\\ J_7( 5.7) = 0.10270\\ J_3(10.0) = 0.05838\\ J_4(10.0) = -0.21960\\ J_7(10.0) = 0.21671\\ \end{align}\end{split}\]
  4. Dada una lista de números, vamos a calcular valores relacionados a su estadística.

    • Realizar una función calc_media(x, que="aritmetica") que calcule los valores de la media aritmética, la media geométrica o la media armónica dependiendo del valor del argumento que. Las medias están dadas por:

      \[A(x_1, \ldots, x_n) = \bar{x} = \frac{x_1 + \cdots + x_n}{n}\]
      \[G(x_1, \ldots, x_n) = \sqrt[n]{x_1 \cdots x_n}\]
      \[H(x_1, \ldots, x_n) = \frac{n}{\frac{1}{x_1} + \cdots + \frac{1}{x_n}}\]
    • Realizar una función que calcule la mediana de una lista de números (el argumento en este caso es del tipo list). La mediana se define como el valor para el cual la mitad de los valores de la lista es menor que ella. Si el número de elementos es par, se toma el promedio entre los dos adyacentes.

    Realizar los cálculos para las listas de números:

    L1 = [6.41, 1.28, 11.54, 5.13, 8.97, 3.84, 10.26, 14.1, 12.82, 16.67, 2.56, 17.95, 7.69, 15.39]
    L2 = [4.79, 1.59, 2.13, 4.26, 3.72, 1.06, 6.92, 3.19, 5.32, 2.66, 5.85, 6.39, 0.53]
    
    • La moda se define como el valor que ocurre más frecuentemente en una colección. Note que la moda puede no ser única. En ese caso debe obtener todos los valores. Escriba una función que retorne la moda de una lista de números. Utilícela para calcular la moda de la siguiente lista de números enteros:

    L = [8, 9, 10, 11, 10, 6, 10, 17, 8, 8, 5, 10, 14, 7, 9, 12, 8, 17, 10, 12, 9, 11, 9, 12, 11, 11, 6, 9, 12, 5, 12, 9, 10, 16, 8, 4, 5, 8, 11, 12]
    

Ejercicios de Clase 05

  1. Realice un programa que:

  • Lea el archivo names.txt

  • Guarde en un nuevo archivo (llamado “pares.txt”) palabra por medio del archivo original (la primera, tercera, …) una por línea, pero en el orden inverso al leído

  • Agregue al final de dicho archivo, las palabras pares pero separadas por un punto y coma (;)

  • En un archivo llamado “longitudes.txt” guarde las palabras ordenadas por su longitud, y para cada longitud ordenadas alfabéticamente.

  • En un archivo llamado “letras.txt” guarde sólo aquellas palabras que contienen las letras w,x,y,z, con el formato:

    • w: Walter, ….

    • x: Xilofón, …

    • y: ….

    • z: ….

  • Cree un diccionario, donde cada key es la primera letra y cada valor es una lista, cuyo elemento es una tuple (palabra, longitud). Por ejemplo:

d['a'] = [('Aaa',3),('Anna', 4), ...]
  1. Realice un programa para:

    • Leer los datos del archivo aluminio.dat y poner los datos del elemento en un diccionario de la forma:

    d = {'S': 'Al', 'Z':13, 'A':27, 'M': '26.98153863(12)', 'P': 1.0000, 'MS':'26.9815386(8)'}
    
    • Modifique el programa anterior para que las masas sean números (float) y descarte el valor de la incerteza (el número entre paréntesis)

    • Agregue el código necesario para obtener una impresión de la forma:

    Elemento: Al
    Número Atómico: 13
    Número de Masa: 27
    Masa: 26.98154
    

Note que la masa sólo debe contener 5 números decimales

Ejercicios de Clase 06

  1. Implemente los métodos __add__, producto y abs

    • __add__() debe retornar un objeto del tipo Vector y contener en cada componente la suma de las componentes de los dos vectores que toma como argumento.

    • producto toma como argumentos dos vectores y retorna un número real con el valor del producto interno

    • abs toma como argumentos el propio objeto y retorna el número real correspondiente

    Su uso será el siguiente:

    v1 = Vector(1,2,3)
    v2 = Vector(3,2,1)
    v = v1 + v2
    pr = v1.producto(v2)
    a = v1.abs()
    
  2. Utilizando la definición de la clase Punto

class Punto:
  "Clase para describir un punto en el espacio"

  num_puntos = 0

  def __init__(self, x=0, y=0, z=0):
    "Inicializa un punto en el espacio"
    self.x = x
    self.y = y
    self.z = z
    Punto.num_puntos += 1
    return None

  def __del__(self):
    "Borra el punto y actualiza el contador"
    Punto.num_puntos -= 1

  def __str__(self):
    return f"Punto en el espacio con coordenadas: x = {self.x}, y = {self.y}, z = {self.z}"

  def __repr__(self):
    return f"Punto(x = {self.x}, y = {self.y}, z = {self.z})"

  def __call__(self):
    return self.__str__()

  @classmethod
  def total(cls):
    "Imprime el número total de puntos"
    print(f"En total hay {cls.num_puntos} puntos definidos")

Complete la implementación de la clase Vector con los métodos pedidos

class Vector(Punto):
  "Representa un vector en el espacio"

  def __add__(self, v2):
    "Calcula un vector que contiene la suma de dos vectores"
    print("Aún no implementada la suma de dos vectores")
    # código calculando v = suma de self + v2
    # ...

  def __mul__(self, v2):
    "Calcula el producto interno entre dos vectores"
    print("Aún no implementado el producto interno de dos vectores")
    # código calculando el producto interno pr = v1 . v2

  def abs(self):
    "Devuelve la distancia del punto al origen"
    print("Aún no implementado la norma del vector")
    # código calculando la magnitud del vector

  def angulo_entre_vectores(self, v2):
    "Calcula el ángulo entre dos vectores"
    print("Aún no implementado el ángulo entre dos vectores")
    angulo = 0
    # código calculando angulo = arccos(v1 * v2 / (|v1||v2|))
    return angulo

  def coordenadas_cilindricas(self):
    "Devuelve las coordenadas cilindricas del vector como una tupla (r, theta, z)"
    print("No implementada")

  def coordenadas_esfericas(self):
    "Devuelve las coordenadas esféricas del vector como una tupla (r, theta, phi)"
    print("No implementada")
  1. PARA ENTREGAR: Cree una clase Polinomio para representar polinomios. La clase debe guardar los datos representando todos los coeficientes. El grado del polinomio será menor o igual a 9 (un dígito).

    Nota

    Utilice el archivo 06_polinomio.py en el directorio data, que renombrará de la forma usual 06_Apellido.py. Se le pide que programe:

  • Un método de inicialización __init__ que acepte una lista de coeficientes. Por ejemplo para el polinomio \(4 x^3 + 3 x^2 + 2 x + 1\) usaríamos:

>>> p = Polinomio([1,2,3,4])
  • Un método grado que devuelva el orden del polinomio

>>> p = Polinomio([1,2,3,4])
>>> p.grado()
3
  • Un método get_coeficientes, que devuelva una lista con los coeficientes:

>>> p.get_coeficientes()
[1, 2, 3, 4]
  • Un método set_coeficientes, que fije los coeficientes de la lista:

>>> p1 = Polinomio()
>>> p1.get_coeficientes()
[]
>>> p1.set_coeficientes([1, 2, 3, 4])
>>> p1.get_coeficientes()
[1, 2, 3, 4]
  • El método suma_pol(pol2) que le sume otro polinomio y devuelva un polinomio (objeto del mismo tipo)

  • El método mul(pol2) que multiplica al polinomio por una constante y devuelve un nuevo polinomio

  • Un método, derivada(n), que devuelva la derivada de orden n del polinomio (otro polinomio):

>>> p1 = p.derivada()
>>> p1.get_coeficientes()
[2, 6, 12]
>>> p2 = p.derivada(n=2)
>>> p2.get_coeficientes()
[6, 24]
  • Un método que devuelva la integral (antiderivada) del polinomio de orden n, con constante de integración cte (otro polinomio).

>>> p1 = p.integrada()
>>> p1.get_coeficientes()
[0, 1, 1, 1, 1]
>>>
>>> p2 = p.integrada(cte=2)
>>> p2.get_coeficientes()
[2, 1, 1, 1, 1]
>>>
>>> p3 = p.integrada(n=3, cte=1.5)
>>> p3.get_coeficientes()
[1.5, 1.5, 0.75, 0.16666666666666666, 0.08333333333333333, 0.05]
  • Un método from_string(expr) (pida ayuda si se le complica) que crea un polinomio desde un string en la forma:

>>> p = Polinomio()
>>> p.from_string('x^5 + 3x^3 - 2 x+x^2 + 3 - x')
>>> p.get_coeficientes()
[3, -3, 1, 3, 0, 1]
>>>
>>> p1 = Polinomio()
>>> p1.from_string('y^5 + 3y^3 - 2 y + y^2+3', var='y')
>>> p1.get_coeficientes()
[3, -2, 1, 3, 0, 1]
  • Escriba un método llamado __str__, que devuelva un string (que define cómo se va a imprimir el polinomio). Un ejemplo de salida será:

>>> p = Polinomio([1,2.1,3,4])
>>> print(p)
4 x^3 + 3 x^2 + 2.1 x + 1
  • Escriba un método llamado __call__, de manera tal que al llamar al objeto, evalúe el polinomio en un dado valor de x

>>> p = Polinomio([1,2,3,4])
>>> p(x=2)
49
>>>
>>> p(0.5)
3.25
  • Escriba un método llamado __add__(self, p), que evalúe la suma de polinomios usando el método suma_pol definido anteriormente. Eso permitirá usar la operación de suma en la forma:

>>> p1 = Polinomio([1,2,3,4])
>>> p2 = Polinomio([1,2,3,4])
>>> p1 + p2
  • Escriba los métodos llamados __mul__(self, value) y __rmul__(self, value), que devuelvan el producto de un polinomio por un valor constante, llamando al método mul definido anteriormente. Eso permitirá usar la operación producto en la forma:

>>> p1 = Polinomio([1,2,3,4])
>>> k = 3.5
>>> p1 * k
>>> k * p1

Ejercicios de Clase 07

El módulo time calcula el tiempo en segundos desde el comienzo de la era de la computación (?), que para los fines prácticos, da inicio el 1 de enero de 1970 ;-D. Veamos unos ejemplos de su uso:

import time

ahora = time.time()
print (ahora)
# duerme 5 segundos
time.sleep(5) # zzzz.....

ahora = time.time()
print (ahora)
1709038864.1231098
1709038869.1235564

Utilizando las funciones anteriores, escriba el decorador @time_me que calcula e imprime el tiempo que tarda en ejecutarse una función. No empiece desde cero!! Use como plantilla para empezar el decorador @debug_me y modifíquelo adecuadamente.

# descomente el decorador una vez que lo tenga programado
# @time_me
def mi_calculo_recontralargo(n):
    l= [x for x in range(n)]
    return sum(l)
mi_calculo_recontralargo(20000000)
199999990000000
  1. Construya una función partition(lst,predicate) que dada una lista lst y una función predicate, separe la lista lst en dos: una lista que contiene los valores para los cuales la función predicate devuelve True, y otra lista que contiene los valores para los que predicate devuelve False:

    def is_even(x):
        return x % 2 == 0
    
    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    evens, odds = divide_list(numbers, is_even)
    
    print(evens) # Output: [2, 4, 6, 8, 10]
    print(odds)  # Output: [1, 3, 5, 7, 9]
    
  2. Dado la cadena de caracteres

    s1='En un lugar de la Mancha de cuyo nombre no quiero acordarme'
    

    Utilice reduce, map y/o filter (y las funciones auxiliares necesarias) para:

    • Obtener la cantidad de caracteres.

    • Imprimir la frase anterior pero con cada palabra empezando en mayúsculas.

    • Contar cuantas letras ‘a’ tiene la frase.

    • Contar cuántas vocales tiene.

Ejercicios de Clase 08

  1. Genere arrays en 2d, cada uno de tamaño 10x10 con:

    1. Un array con valores 1 en la “diagonal principal” y 0 en el resto (Matriz identidad).

    2. Un array con valores 0 en la “diagonal principal” y 1 en el resto.

    3. Un array con valores 1 en los bordes y 0 en el interior.

    4. Un array con números enteros consecutivos (empezando en 1) en los bordes y 0 en el interior.

  2. Diga qué resultado produce el siguiente código, y explíquelo

# Ejemplo propuesto por Jake VanderPlas
print(sum(range(5),-1))
from numpy import *
print(sum(range(5),-1))
  1. Escriba una función suma_potencias(p, n) (utilizando arrays y Numpy) que calcule la operación

    \[s_{2} = \sum_{k=0}^{n}k^{p}\]

    .

  2. Usando las funciones de numpy sign y maximum definir las siguientes funciones, que acepten como argumento un array y devuelvan un array con el mismo shape:

  • función de Heaviside, que vale 1 para valores positivos de su argumento y 0 para valores negativos.

  • La función escalón, que vale 0 para valores del argumento fuera del intervalo \((-1,1)\) y 1 para argumentos en el intervalo.

  • La función rampa, que vale 0 para valores negativos de \(x\) y \(x\) para valores positivos.

Ejercicios de Clase 09

  1. Realizar un programa para visualizar la función

    \[f(x,n,w) = x^n |\sin(w x)|\]

    El programa debe realizar el gráfico para \(w=10\), con cuatro curvas para \(n=1,2,3,4\), similar al que se muestra en la siguiente figura

    _images/ejerc_vis_f1.png
  2. Para la función definida a trozos:

    \[\begin{split}f(x) = \begin{cases} f_{1}(x) = x^{2}/8 & - \pi < x \le \pi/2 \\ f_{2}(x) = -0.3 x & \pi/2 < x < \pi \\ f_{3}(x) = -(x - 2 \pi)^{2}/6 & \pi \le x \le 5 \pi/2 \\ f_{4}(x) = (x - 2 \pi)/5 & 5 \pi/2 < x \le 3 \pi \end{cases}\end{split}\]

    realizar la siguiente figura de la manera más fiel posible.

    _images/ejercicio_08_1.png

    Pistas: Buscar información sobre plt.text(), plt.fill_between() y sobre plt.xticks y plt.yticks.

  3. Rehacer la siguiente figura:

    _images/ejercicio_08_2.png
  4. Notando que la curva en color negro corresponde a la suma de las dos curvas en rojo, rehacer la siguiente figura:

    _images/ejercicio_08_3.png
  5. Crear una hoja de estilo que permita hacer gráficos adecuados para posters y presentaciones. Debe modificar los tamaños para hacerlos legibles a mayores distancias (sugerencia 16pt). El tamaño de la letra de los nombres de ejes y en las leyendas debe ser mayor también. Las líneas deben ser más gruesas (sugerencia: ~4), los símbolos de mayor tamaño (sugerencia ~10).

Ejercicios de Clase 10

  1. Dado un array a de números, creado por ejemplo usando:

    a = np.random.uniform(size=100)
    

    Encontrar el número más cercano a un número escalar dado (por ejemplo x=0.5). Utilice los métodos discutidos.

  2. Vamos a estudiar la frecuencia de aparición de cada dígito en la serie de Fibonacci, generada siguiendo las reglas:

    \[a_{1} = a_{2} = 1, \quad a_{i} = a_{i-1} + a_{i-2}.\]

    Se pide:

    1. Crear una función que acepta como argumento un número entero \(N\) y retorna una secuencia (lista, tupla, diccionario o array) con los elementos de la serie de Fibonacci.

    2. Crear una función que devuelva un histograma de ocurrencia de cada uno de los dígitos en el primer lugar del número. Por ejemplo para los primeros 8 valores (\(N=8\)): \(1,1,2,3,5,8,13,21\) tendremos que el \(1\) aparece 3 veces, el \(2\) aparece \(2\) veces, \(3, 5, 8\) una vez. Normalizar los datos dividiendo por el número de valores \(N\).

    3. Utilizando las dos funciones anteriores graficar el histograma para un número \(N\) grande y comparar los resultados con la ley de Benford

      \[P(n) = \log_{10}\left(1+ \frac{1}{d} \right).\]
  3. PARA ENTREGAR: Estimar el valor de π usando diferentes métodos basados en el método de Monte Carlo:

    1. Crear una función para calcular el valor de \(\pi\) usando el “método de cociente de áreas”. Para ello:

    • Generar puntos en el plano dentro del cuadrado de lado unidad cuyo lado inferior va de \(x=0\) a \(x=1\)

    • Contar cuantos puntos caen dentro del (cuarto de) círculo unidad. Este número tiende a ser proporcional al área del círculo

    • La estimación de \(\pi\) será igual a cuatro veces el cociente de números dentro del círculo dividido por el número total de puntos.

    1. Crear una función para calcular el valor de \(\pi\) usando el “método del valor medio”: Este método se basa en la idea de que el valor medio de una función se puede calcular de la siguiente manera:

    \[\langle f \rangle = \frac{1}{b-a} \int_{a}^{b} f(x)\, dx\]

    Tomando la función particular \(f(x)= \sqrt{1- x^{2}}\) entre \(x=0\) y \(x=1\), obtenemos:

    \[\langle f \rangle = \int_{0}^{1} \sqrt{1- x^{2}}\, dx = \frac{\pi}{4}\]

    Entonces, tenemos que estimar el valor medio de la función \(f\) y, mediante la relación anterior obtener \(\pi = 4 \langle f(x) \rangle\). Para obtener el valor medio de la función notamos que si tomamos \(X\) es una variable aleatoria entre 0 y 1, entonces el valor medio de \(f(X)\) es justamente \(\langle f \rangle\). Su función debe entonces

    • Generar puntos aleatoriamente en el intervalo \([0,1]\)

    • Calcular el valor medio de \(f(x)\) para los puntos aleatorios \(x\).

    • El resultado va a ser igual al valor de la integral, y por lo tanto a \(\pi/4\).

    1. Utilizar las funciones anteriores con diferentes valores para el número total de puntos \(N\). En particular, hacerlo para 20 valores de \(N\) equiespaciados logarítmicamente entre 100 y 10000. Para cada valor de \(N\) calcular la estimación de \(\pi\). Realizar un gráfico con el valor estimado como función del número \(N\) con los dos métodos (dos curvas en un solo gráfico)

    2. Para \(N=15000\) repetir el “experimento” muchas veces (al menos 1000) y realizar un histograma de los valores obtenidos para \(\pi\) con cada método. Graficar el histograma y calcular la desviación standard. Superponer una función Gaussiana con el mismo ancho. El gráfico debe ser similar al siguiente (el estilo de graficación no tiene que ser el mismo)

    _images/ejercicio_09_1.png
    1. El método de la aguja del bufón se puede utilizar para estimar el valor de \(\pi\), y consiste en tirar agujas (o palitos, fósforos, etc) al azar sobre una superficie rayada

    _images/Streicholz-Pi-wiki.jpg

    Por simplicidad vamos a considerar que la distancia entre rayas \(t\) es mayor que la longitud de las agujas \(\ell\)

    _images/Buffon_needle_wiki.png

    La probabilidad de que una aguja cruce una línea será:

    \[P = \frac{2 \ell}{t\, \pi}\]

    por lo que podemos calcular el valor de \(\pi\) si estimamos la probabilidad \(P\). Realizar una función que estime \(\pi\) utilizando este método y repetir las comparaciones de los dos puntos anteriores pero ahora utilizando este método y el de las áreas.

Ejercicios de Clase 12

  1. Calcular (utilizando quad) y graficar para valores de \(k=1,2,5,10\)m como función del límite superior \(L\), el valor de las integrales:

    \[I_{1}(k,L) = \int_{0}^{L} x^{k} e^{-k x / 2} dx\]

    y

    \[I_{2}(k,L) = \int_{0}^{L} x^{k} e^{-k x / 2} \sin{(k x)} dx\]

con rango de variación de \(L\) entre \(0\) y \(2 \pi\).

  1. En el archivo palabras.words.gz hay una larga lista de palabras, en formato comprimido. Siguiendo la idea del ejemplo dado en clases realizar un histograma de las longitudes de las palabras.

  2. Modificar el programa del ejemplo de la clase para calcular el histograma de frecuencia de letras en las palabras (no sólo la primera). Considere el caso insensible a la capitalización: las mayúsculas y minúsculas corresponden a la misma letra (‘á’ es lo mismo que ‘Á’ y ambas corresponden a ‘a’).

  3. Utilizando el mismo archivo de palabras, Guardar todas las palabras en un array y obtener los índices de las palabras que tienen una dada letra (por ejemplo la letra ‘j’), los índices de las palabras con un número dado de letras (por ejemplo 5 letras), y los índices de las palabras cuya tercera letra es una vocal. En cada caso, dar luego las palabras que cumplen dichas condiciones.

  4. En el archivo colision.npy hay una gran cantidad de datos que corresponden al resultado de una simulación. Los datos están organizados en trece columnas. La primera corresponde a un parámetro, mientras que las 12 restantes corresponde a cada una de las tres componentes de la velocidad de cuatro partículas. Calcular y graficar:

    1. la distribución de ocurrencias del primer parámetro.

    2. la distribución de ocurrencias de energías de la tercera partícula.

    3. la distribución de ocurrencias de ángulos de la cuarta partícula, medido respecto al tercer eje. Realizar los cuatro gráficos utilizando un formato adecuado para presentación (charla o poster).

  5. Leer el archivo colision.npy y guardar los datos en formato texto con un encabezado adecuado. Usando el comando mágico %timeit o el módulo timeit, comparar el tiempo que tarda en leer los datos e imprimir el último valor utilizando el formato de texto y el formato original npy. Comparar el tamaño de los dos archivos.

  6. El submódulo scipy.constants tiene valores de constantes físicas de interés. Usando este módulo compute la constante de Stefan-Boltzmann \(\sigma\) utilizando la relación:

    \[\sigma = \frac{2 \pi^5 k_B^4}{15 h^3 c^2}\]

    Confirme que el valor obtenido es correcto comparando con la constante para esta cantidad en scipy.constants

  7. Usando Scipy y Matplotlib grafique las funciones de onda del oscilador armónico unidimensional para las cuatro energías más bajas (\(n=1,2,3,4\)), en el intervalo \([-5,5]\). Asegúrese de que están correctamente normalizados.

Las funciones están dadas por:

\[\psi _{n}(x)={\frac {1}{\sqrt {2^{n}\,n!}}}\cdot \left({\frac {\omega }{\pi}}\right)^{1/4}\cdot e^{-{\frac {\omega x^{2}}{2 }}}\cdot H_{n}\left({\sqrt{\omega}}\, x\right),\qquad n=0,1,2,\ldots .\]

donde \(H_{n}\) son los polinomios de Hermite, y usando \(\omega = 2\).

Trate de obtener un gráfico similar al siguiente (tomado de wikipedia. Realizado por By AllenMcC. - File:HarmOsziFunktionen.jpg, CC BY-SA 3.0)

_images/HarmOsziFunktionen.png

Ejercicios de Clase 13

  1. En el archivo co_nrg.dat se encuentran los datos de la posición de los máximos de un espectro de CO2 como función del número cuántico rotacional J (entero). Haga un programa que lea los datos. Los ajuste con polinomios (elija el orden adecuado) y grafique luego los datos (con símbolos) y el ajuste con una línea sólida roja. Además, debe mostrar los parámetros obtenidos para el polinomio.

  2. Para Entregar: Queremos hacer un programa que permita fitear una curva como suma de N funciones gaussianas:

    1. Usando distribuciones normales e histogramas cree conjuntos de datos con dos, tres y cuatro máximos.

    2. Haga una función, que debe tomar como argumento los arrays con los datos: x, y, y valores iniciales para las Gaussianas: fit_gaussianas(x, y, *params) donde params son los 3N coeficientes (tres coeficientes para cada Gaussiana). Debe devolver los parámetros óptimos obtenidos.

    3. Realice un programita que grafique los datos dados y la función que resulta de sumar las gaussianas en una misma figura.

    4. Si puede agregue líneas o flechas indicando la posición del máximo y el ancho de cada una de las Gaussianas obtenidas.

Ejercicios de Clase 15

  1. Utilizando Matplotlib:

    • Hacer un gráfico donde dibuje una parábola \(y = x^{2}\) en el rango \([-5,5]\).

    • En el mismo gráfico, agregar un círculo en \(x=-5\).

    • El círculo debe moverse siguiendo la curva, como se muestra en la figura

    _images/pelota.gif
  2. Caída libre 2: Realizar animaciones del ejercicio de caída libre, de forma tal que:

    • La animación tenga un cartel indicando el tiempo, y la velocidad y altura correspondiente a ese tiempo.

    • Agregar una “cola fantasma” a la partícula, que muestre posiciones anteriores.