Nombre: Luis Fernando Apáez Álvarez
Importa la librería de numpy, utiliza el método linspace para crear un arreglo numérico "a" de la forma: [0,1,2,...,100], luego crea un arreglo "b" de la forma [100,99,98,...,0]. Suma ambos arreglos en una nueva variable "c" y divide "c" entre 100. Muestra el arreglo resultante y el resultado del método c.sum().
# Solucion
import numpy as np
a = np.linspace(0, 100, 101)
b = a[::-1]
c = a + b
print(f'Arreglo resultante: {c / 100}')
print(f'Resultado del método c.sum(): {c.sum()}')
print('Gauss be like 👽')
Arreglo resultante: [1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] Resultado del método c.sum(): 10100.0 Gauss be like 👽
Crea un arreglo matricial con el código: M = np.arange(1,145).reshape(12,12) muestra el resultado y luego extrae el último renglón como una nueva variable "m". Calcula la suma de todos los los valores de "M" y "m" con el método .sum y por medio de un ciclo sin ayuda de métodos.
# Solucion
M = np.arange(1, 145).reshape(12, 12)
print(M)
print()
# Extraemos el ultimo renglon
m = M[-1]
print(m)
print()
# Suma de todos los valores de M
suma_M = 0
for i in range(M.shape[0]):
for j in range(M.shape[1]):
suma_M += M[i][j]
print(f'Suma de todos los valores de M: {suma_M}')
print(f'Comprobación utilizando el método sum(): {M.sum()}')
print()
# Suma de todos los valores de m:
# Pasamos los valores de m a una lista
aux_m = [i for i in m]
suma_m = 0
# Sumamos los elementos de la lista
for i in aux_m:
suma_m += i
print(f'Suma de todos los valores de m: {suma_m}')
print(f'Comprobación utilizando el método sum(): {m.sum()}')
[[ 1 2 3 4 5 6 7 8 9 10 11 12] [ 13 14 15 16 17 18 19 20 21 22 23 24] [ 25 26 27 28 29 30 31 32 33 34 35 36] [ 37 38 39 40 41 42 43 44 45 46 47 48] [ 49 50 51 52 53 54 55 56 57 58 59 60] [ 61 62 63 64 65 66 67 68 69 70 71 72] [ 73 74 75 76 77 78 79 80 81 82 83 84] [ 85 86 87 88 89 90 91 92 93 94 95 96] [ 97 98 99 100 101 102 103 104 105 106 107 108] [109 110 111 112 113 114 115 116 117 118 119 120] [121 122 123 124 125 126 127 128 129 130 131 132] [133 134 135 136 137 138 139 140 141 142 143 144]] [133 134 135 136 137 138 139 140 141 142 143 144] Suma de todos los valores de M: 10440 Comprobación utilizando el método sum(): 10440 Suma de todos los valores de m: 1662 Comprobación utilizando el método sum(): 1662
Importa la librería de pandas como pd y utiliza el comando pd.read_csv('calis') para importar un dataframe con las calificaciones bimestrales de un alumno por materia desde el archivo csv que se adjuntó en la tarea (considera que el archivo debe estar en la misma carpeta de enrutamiento que tu trabajo). Reetiqueta los ínidices de fila con los índices [bim_1,bim_2,bim_3,bim_4], añade una columna con el encabezado prom_bim sonde se calcule el promedio bimestral por materia. Muestra el dataframe resultante y calcula el promedio anual del alumno para la materia de Inglés.
import pandas as pd
df = pd.read_csv('calis')
# Lista de indices
new_index = ['bim_1', 'bim_2', 'bim_3', 'bim_4']
# Configuramos el nuevo indice
df.index = new_index
# Agregamos una nueva columna y calculamos el promedio por fila
df['prom_bim'] = df.mean(axis=1)
# Mostramos el dataframe resultante
display(df)
# Promedio anual para la materia de ingles
print()
print(f'Promedio anuel (brrr) del alumno para la materia de inglés: {df["Ing"].mean()}')
Esp | Mat | Ing | Hist | Geo | Fis | Art | prom_bim | |
---|---|---|---|---|---|---|---|---|
bim_1 | 10 | 7 | 10 | 6 | 10 | 8 | 9 | 8.571429 |
bim_2 | 7 | 6 | 8 | 6 | 8 | 10 | 10 | 7.857143 |
bim_3 | 10 | 8 | 10 | 9 | 9 | 8 | 6 | 8.571429 |
bim_4 | 9 | 6 | 9 | 6 | 5 | 6 | 6 | 6.714286 |
Promedio anuel (brrr) del alumno para la materia de inglés: 9.25
Compile un patrón de búsqueda que encuentre todas las palabras que sean seguidas por puntos suspensivos. Utilice el método search para encontrar cada una de las posibles coincidencias: dwell
, flesh
y once
. Esto implica que tendrá que correr el método search
en tres ocasiones, modificando cada vez los parámetros de índices inicial y final.
Aclaración: los puntos suspensivos no deben ser parte de la coincidencia; en otras palabras, haga uso de un lookahead.
quote = """
To think that once I could not see beyond the veil of our reality.
To see those who dwell... behind.
My life now has purpose, for I have learned the frailty of flesh..., and bone.
I was once... a fool.
"""
# Compile un patron de busqueda que encuentre todas las palabras
# que sean seguidas por puntos suspensivos
import re
pattern = re.compile(r'(?<=\.{3}[ ,]) ?\w+')
match = pattern.findall(quote)
print(match)
['behind', ' and', 'a']
# once
pattern = re.compile(r'[dfo][wln]\w{2,3}')
match = pattern.search(quote)
print(match)
<re.Match object; span=(15, 19), match='once'>
# dwell
pattern = re.compile(r'[dfo][wln]\w{2,3}')
match = pattern.search(quote, 20, 100)
print(match)
<re.Match object; span=(85, 90), match='dwell'>
pattern = re.compile(r'[dfo][wln]\w{2,3}')
match = pattern.search(quote, 100, 170)
print(match)
<re.Match object; span=(161, 166), match='flesh'>
Sea output
la salida del comando ls -l
. Comiple un patŕon de búsqueda que encuentre una coincidencia por archivo .py
; la coincidencia debe incluir el peso del archivo, la fecha y hora de última modificación, y el nombre del archivo. Para esto, utilice el método findall
e imprima la lista que éste devuelve.
Nótese que el peso del archivo es la columna que sigue al segundo root
.
output = """
total 18676
-rw-rw-r-- 1 root root 507 sep 9 12:43 args
-rw-rw-r-- 1 root root 9383156 jun 30 12:03 docs
-rw-rw-r-- 1 root root 901 ago 12 19:27 cleanse.py
-rw-rw-r-- 1 root root 3222 sep 9 12:32 correct__counts.py
-rw-rw-r-- 1 root root 1935 ago 17 18:27 correct_tracking.py
-rw-rw-r-- 1 root root 2017 sep 1 22:52 correct_track.py
-rw-rw-r-- 1 root root 1172 jul 8 11:24 get_pass.py
-rw-rw-r-- 1 root root 382 may 10 13:06 get_errors.py
-rw-rw-r-- 1 root root 24150 may 10 19:23 get_status.py
-rw-rw-r-- 1 root root 1632 jul 29 11:58 get_unprocessed.py
-rw-rw-r-- 1 root root 601 jun 10 00:33 get_nums.py
-rw-rw-r-- 1 root root 659 ago 17 21:00 insert_docs.py
-rw-rw-r-- 1 root root 1277 jun 7 20:35 monthly_update_historic.py
-rw-rw-r-- 1 root root 1493 sep 10 02:04 monthly_update.py
-rw-rw-r-- 1 root root 2017 jun 28 19:18 out
-rw-rw-r-- 1 root root 596625 jul 10 16:51 query2.log
-rw-rw-r-- 1 root root 38104 may 10 20:04 query2.py
-rw-rw-r-- 1 root root 597313 jul 11 16:38 query3.log
-rw-rw-r-- 1 root root 597257 jul 13 18:19 query.log
-rw-rw-r-- 1 root root 647 sep 1 22:27 query.py
-rw-rw-r-- 1 root root 845 ago 12 19:25 restart_tracking.py
-rw-rw-r-- 1 root root 707 sep 10 02:04 update.py
-rw-rw-r-- 1 root root 7803707 ago 17 19:00 ids.txt
-rw-rw-r-- 1 root root 4096 may 1 18:32 verify_tracking_migration.py
-rw-rw-r-- 1 root root 355 sep 10 02:03 x
"""
# patron de busqueda que encuentre una coincidencia por archivo .py;
# la coincidencia debe incluir el peso del archivo, la fecha y hora de
# ultima modificacion, y el nombre del archivo:
pattern = re.compile(r'(?<=-rw-rw-r-- 1 root root) +.+\.py')
match = pattern.findall(output)
print(match)
[' 901 ago 12 19:27 cleanse.py', ' 3222 sep 9 12:32 correct__counts.py', ' 1935 ago 17 18:27 correct_tracking.py', ' 2017 sep 1 22:52 correct_track.py', ' 1172 jul 8 11:24 get_pass.py', ' 382 may 10 13:06 get_errors.py', ' 24150 may 10 19:23 get_status.py', ' 1632 jul 29 11:58 get_unprocessed.py', ' 601 jun 10 00:33 get_nums.py', ' 659 ago 17 21:00 insert_docs.py', ' 1277 jun 7 20:35 monthly_update_historic.py', ' 1493 sep 10 02:04 monthly_update.py', ' 38104 may 10 20:04 query2.py', ' 647 sep 1 22:27 query.py', ' 845 ago 12 19:25 restart_tracking.py', ' 707 sep 10 02:04 update.py', ' 4096 may 1 18:32 verify_tracking_migration.py']
# Quitamos los espacios en blanco al inicio de cada elemento de la lista anterior:
pattern2 = re.compile(r'(?<=\s)\d+.+')
match_clean = [pattern2.search(m)[0] for m in match]
print(match_clean)
['901 ago 12 19:27 cleanse.py', '3222 sep 9 12:32 correct__counts.py', '1935 ago 17 18:27 correct_tracking.py', '2017 sep 1 22:52 correct_track.py', '1172 jul 8 11:24 get_pass.py', '382 may 10 13:06 get_errors.py', '24150 may 10 19:23 get_status.py', '1632 jul 29 11:58 get_unprocessed.py', '601 jun 10 00:33 get_nums.py', '659 ago 17 21:00 insert_docs.py', '1277 jun 7 20:35 monthly_update_historic.py', '1493 sep 10 02:04 monthly_update.py', '38104 may 10 20:04 query2.py', '647 sep 1 22:27 query.py', '845 ago 12 19:25 restart_tracking.py', '707 sep 10 02:04 update.py', '4096 may 1 18:32 verify_tracking_migration.py']
Crea una función en python tal que dada una función matemática (evaluada sobre los números reales) cualquiera y un intervalo cualquiera, calcule su integral definida.
import numpy as np
# Solucion:
# Definiremos una funcion de prueba
def fun_cuad(x):
return np.sin(x)
# Definimos la funcion para hallar la integral de
# funcion matematica anterior sobre cualquier intervalo [a,b]
def integral_definida(f, a, b, delta) -> float:
""" Parámetros:
* f: Una función definida por el usuario;
* a: valor inicial del intervalo de integración;
* b: valor final del intervalo de integración;
* delta: número "pequeño" mayor a cero que nos permitirá saber qué tan
buena aproximación de la integral definida
estamos haciendo. Mientras más pequeño sea
dicho número mejor aproximación obtendremos."""
# Utilizamos un bucle while para saber si debemos afinar mas la
# particion que crearemos de modo que suma_superior - suma_inferior < delta.
# La siguiente variable almacenara el valor de suma_superior - suma_inferior
# lo inicializamos con el valor delta + 1 para que el bucle se comience a
# ejecutar
decision = delta + 1
# Si suma_superior - suma_inferior > delta, entonces debemos realizar una
# afinacion a la particion. El siguiente numero lo ocuparemos como 100 ** aux
# que nos indicara el numero de puntos en nuestra particion
aux = 1
while decision > delta:
# Particion generada
particion = np.linspace(a, b, 100 ** aux)
# Ancho de los subrectangulos
delta_x = particion[1] - particion[0]
# Calculamos la suma inferior y superior
suma_inferior = 0
suma_superior = 0
for i in range( (100 ** aux)-1 ):
suma_inferior += delta_x * f(particion[i])
suma_superior += delta_x * f(particion[i + 1])
aux += 1
decision = suma_superior - suma_inferior
return suma_inferior
# Probamos por ejemplo
integral_definida(fun_cuad, 0, 2 * np.pi, 0.001)
-1.5352302762394743e-16
Crea una función en python tal que dada una función matemática cualquiera (evaluada sobre los números reales) encuentre los ceros de la función en un intervalo si es que existen. Esto significa que se buscan los puntos $x\in[a,b]\subset \mathbb{R}$ tales que $f(x) = 0$ .
# Solucion:
# Metodo ocupado: fuerza bruta 👽
# Cargamos las librerias que ocuparemos
import numpy as np
import pandas as pd
# Definimos la funcion
def ceros(f, a, b, ratio = 0.00002, num_particion = 350000) -> set[float]:
"""Parámetros:
* f: Función a la cual veremos si tiene ceros o no;
* a: inicio del intervalo de búsqueda;
* b: fin del intervalo de búsqueda;
* ratio: Cota auxiliar en el procedimiento interno para mejorar
la aproximación que se está haciendo a los ceros. Si
disminuimos el ratio, tenemos que aumentar num_particion
considerablemente, lo cual trae un costo de tiempo
computacional alto;
* num_particion: número de puntos que generaremos entre el valor a y b.
Para aquellas funciones cuyos ceros son números enteros, está función
trabaja muy bien. Para aquellas funciones cuyos ceros son decimales,
esta función da, al menos, un decimal de precisión :)
En promedio, para funciones sencillas, se tarda en ejecutarse alrededor
de 13 segundos.
"""
# Creamos una particion
particion = np.linspace(a, b, num_particion)
# Evaluamos la funcion en cada valor de la particion
fun_particion = [f(x) for x in particion]
# Creamos un dataframe con las x y f(x)
df = pd.DataFrame([particion, fun_particion]).transpose().rename(columns={0: 'x', 1: 'f(x)'})
# Seleccionamos solo los valores de x tales que -ratio < f(x) < ratio
df_ratio = df[(df['f(x)'] < ratio) & (df['f(x)'] > -ratio)]
# Redondearemos y agruparemos en un conjunto para obtener valores unicos
raices = set(round(df_ratio['x'], 2))
# Caso en el que la funcion matematica no tiene ceros
if len(raices) == 0:
return 'La función no tiene ceros'
# Caso contrario retornamos los ceros (o una aproximacion de ellos)
else:
return raices
# Ponemos a prueba la funcion ceros():
%%time
ceros(lambda x: np.sin(x), -2 * np.pi, 2 * np.pi)
CPU times: total: 12.6 s Wall time: 12.7 s
{-6.28, -3.14, -0.0, 3.14, 6.28}
%%time
# Como ya sabemos que no tiene ceros podemos reducir
# considerablemente el numero de puntos en la particion
ceros(lambda x: x ** 2 + 1, -1, 1, num_particion=10)
CPU times: total: 0 ns Wall time: 3 ms
'La función no tiene ceros'
%%time
ceros(lambda x: x ** 2 + 5 * x + 6, -3, 3)
CPU times: total: 12.5 s Wall time: 12.6 s
{-3.0, -2.0}
%%time
# Al parecer la siguiente funcion no tiene ceros
ceros(lambda x: -x ** 2 + 12 * x -4, -3, 3)
CPU times: total: 12.8 s Wall time: 13 s
'La función no tiene ceros'
%%time
# Pero si reducimos el intervalo y aumentamos el numero de
# puntos en la particion hallamos un valor
ceros(lambda x: -x ** 2 + 12 * x - 4, 0, 3, num_particion=500000)
CPU times: total: 18 s Wall time: 18.3 s
{0.34}
%%time
# Nos movemos al intervalo [10-12] y aumentamos el numero de
# puntos en la particion:
ceros(lambda x: -x ** 2 + 12 * x - 4, 10, 12, num_particion=500000)
{11.66}
Crea una función en python tal que dada una matriz cuadrada (con entrada en los números complejos) de cualquier tamaño, calcule sus valores propios y sus vectores propios.
import numpy as np
# Definimos una matriz de prueba
array1 = np.array([ [-1, 3, 5],
[2, 4, 8],
[2, 4, -2]])
# Definicion de la funcion que calcula los eigenvectores
# y eigenvectores de una matriz cuadrada dada, en el caso de
# que existan.
def eigenvalores(array):
try:
# Calculo de los valores propios
ei = np.linalg.eig(array)[0]
# Calculo de los vectores propios
mat = np.linalg.eig(array)[1]
# Retornamos un mensaje
for i in range(len(mat)):
print(f'Eigenvalor {ei[i]} | Eigenvector asociado {mat[:, i]}')
# si la matriz no tiene valores propios, arrojamos un mensaje
except LinAlgError:
print('El array ingresado no tiene valores propios')
# Realizamos una prueba
eigenvalores(array1)
Eigenvalor 8.840368441135361 | Eigenvector asociado [-0.44134072 -0.81235587 -0.38117753] Eigenvalor -1.9062084041038665 | Eigenvector asociado [-0.89052581 0.44281752 -0.10429012] Eigenvalor -5.934160037031499 | Eigenvector asociado [-0.4416751 -0.5070981 0.74011798]
Crea una función en python tal que dado cualquier número natural se regrese la descomposición en factores de primos de dicho número. Esto significa que se regresaría una lista de duplas; cada entrada de la lista es una tupla donde la primera entrada es el número primo y la segunda entrada es el exponente. Ejemplo:
Para el número $ 3720937500 $ tiene una descompoción de la siguiente forma:
$ 3720937500 = 2^2 3^5 5^7 7^2$
por lo que lo que se buscaría es que la salida sea:
[(2,2),(3,5),(5,7),(7,2)]
Inicialmente, creamos un código en Python para calcular todos los números primos menores al número 120,000. Dicho código fue escrito en una libreta de google colab: Link a la libreta
El motivo por el cual se decidió escribir dicho código a parte fue, dado que, para calcular todos los primos menores a 300,000 , el tiempo total de ejecución osciló entre una hora 17 minutos. Así, una vez que ya se calculó una lista con dichos números primos, ésta fue almacenada en un dataframe que posteriormente se subió a github. Por ello, para acceder a dichos primos bastará con "traer" ese archivo y almacenarlo en un dataframe:
import pandas as pd
df_primos = pd.read_csv('https://luisapaez.github.io/Teoria_Galois/Primos.csv')
df_primos.head()
Unnamed: 0 | Primos | |
---|---|---|
0 | 1 | 2 |
1 | 2 | 3 |
2 | 3 | 5 |
3 | 4 | 7 |
4 | 5 | 11 |
# Solo nos interesa la columna 'Primos'
# la cual guardaremos en una lista
lista_primos = list(df_primos['Primos'])
print(lista_primos[25900: -1])
print(len(lista_primos))
[298709, 298723, 298733, 298757, 298759, 298777, 298799, 298801, 298817, 298819, 298841, 298847, 298853, 298861, 298897, 298937, 298943, 298993, 298999, 299011, 299017, 299027, 299029, 299053, 299059, 299063, 299087, 299099, 299107, 299113, 299137, 299147, 299171, 299179, 299191, 299197, 299213, 299239, 299261, 299281, 299287, 299311, 299317, 299329, 299333, 299357, 299359, 299363, 299371, 299389, 299393, 299401, 299417, 299419, 299447, 299471, 299473, 299477, 299479, 299501, 299513, 299521, 299527, 299539, 299567, 299569, 299603, 299617, 299623, 299653, 299671, 299681, 299683, 299699, 299701, 299711, 299723, 299731, 299743, 299749, 299771, 299777, 299807, 299843, 299857, 299861, 299881, 299891, 299903, 299909, 299933, 299941, 299951, 299969, 299977, 299983] 25997
Una vez que tenemos la información anterior, escribiremos el siguiente código:
# Pedimos al usuario que ingrese el numero del cual
# desea saber su descomposicion en numeros primos:
num_usuario = int(input('Ingrese un número entero mayor a 0: '))
num_aux = num_usuario
# Creamos una lista auxiliar para almacenar las duplas
duplas = []
# Intentaremos dividir al numero iterativamente por cada
# numero primo en la lista_primos
for primo in lista_primos:
# Veremos cuantas veces divide el numero primo al
# numero num_usuario, calculando la longitud de
# la lista num_primo
num_primo = []
while num_usuario % primo == 0 and num_usuario > 0:
num_primo.append(num_usuario)
num_usuario = num_usuario // primo
# Si el numero primo dividio minimo una vez al numero
# num_usuario, entonces crearemos una dupla y la asignamos
# a la lista duplas:
if len(num_primo) > 0:
# numero primo| Exponente
duplas.append((primo, len(num_primo)))
# Saltaremos a los primos que no esten dividiendo
# a nuestro numero en cuestion
else:
pass
# Comprobamos que podemos recuperar el numero que ingreso el usuario
# con la informacion de la tupla duplas:
valor = 1
for tupla in duplas:
valor *= (tupla[0]) ** tupla[1]
# Si el valor obtenido es igual al valor que
# ingreso el usuario, habremos acabado
if valor == num_aux:
print(duplas)
# Caso contrario, el numero que ingreso el usuario
# tiene un factor primo mayor a 299983
else:
print("Vaya, ha ocurrido un error. Seguramente el número que \
ingresaste tiene al menos un factor primo mayor a 299983 😓")
Ingrese un número entero mayor a 0: 3720937500 [(2, 2), (3, 5), (5, 7), (7, 2)]