Haz un pequeño programa que le pida al usuario introducir dos números ($x_1$ y $x_2$), calcule la siguiente operación y muestre el resultado de la misma ($x$):
$$ x = \frac{20 * x_1 - x_2}{x_2 + 3} $$Si intentas operar con el resultado de la función input obtendrás un error que te informa que no se pueden restar dos datos de tipo str. Usa la función int para convertir los datos introducidos por teclado a datos numéricos.
In [1]:
x1 = int(input("Introduce un número: "))
x2 = int(input("Y ahora otro: "))
x = (20 * x1 - x2)/(x2 + 3)
print("x =",x)
Haz un programa que le pida al usuario un número (de ninjas). Si dicho número es menor que 50 y es par, el programa imprimirá "puedo con ellos!", en caso contrario imprimirá "no me vendría mal una ayudita..."
Nota: para saber si un número es par o no debes usar el operador $\%$ y para saber si dos condiciones se cuplen a la vez, el operador lógico and
In [2]:
num = int(input("Introduce número de ninjas: "))
if num < 50 and num%2==0:
print("Puedo con ellos!")
else:
print("No me vendría mal una ayudita...")
In [3]:
num = int(input("Intoduce un número: "))
# Opción 1: si el usuario introduce un número negativo pedir otro número
while num < 0:
num = int(input("Introduce un número: "))
i = 0
while i <= num:
print(i)
i += 1
In [4]:
num = int(input("Intoduce un número: "))
# Opción 2: si el usuario introduce un número negativo, contar hacia atrás
sign = lambda x: (1, -1)[x < 0]
i = 0
s = sign(num)
while i*s <= num*s:
print(i)
i += s
In [5]:
# Para generar del 0 al 10 ambos inclusive:
for i in range(0,11):
print(i)
In [6]:
# Para generar del 2 al 10 sólo con números pares
for i in range(2, 11, 2):
print(i)
Cuando en un bucle se lee una instrucción break
o una instrucción continue
, se interumpe la iteración actual. Ahora bien, en el caso de break
, se abandona el bucle y en el caso de continue
se pasa a la siguiente iteración. Por ejemplo, el siguiente bucle imprime si un número es par o impar:
In [7]:
for num in range(2,10):
if num % 2 == 0:
print(num, "es par!")
continue
print(num, "es impar!")
In [8]:
lista_compra = ['Leche', 'Chocolate', 'Arroz', 'Macarrones']
print("Penúltimo elemento: ", lista_compra[-2])
print("Del segundo al cuarto elemento: ", lista_compra[1:5])
print("Los tres últimos elementos: ", lista_compra[-3:])
print("Todos: ", lista_compra)
del lista_compra[2]
print(lista_compra)
In [9]:
# solución 1:
[x for x in range(10) if x%2==0]
Out[9]:
In [10]:
# solución 2:
list(range(0,10,2))
Out[10]:
In [11]:
[[j for j in range(i*i, i*i+3)] for i in range(1,3)]
Out[11]:
Vuelve a hacer la lista de la compra que hiciste en el último ejercicio, pero esta vez guarda cada elemento de la lista de la compra junto con su precio. Después, imprime los siguientes elementos:
In [12]:
tuplas_compra = [('Leche', 2), ('Chocolate', 1), ('Arroz', 1.5),
('Macarrones', 2.1)]
print("Precio del tercer elemento: ", tuplas_compra[2][1])
print("Nombre del último elemento: ", tuplas_compra[-1][0])
print("Nombre y precio del primer elemento", tuplas_compra[0])
Al usar la función set
para eliminar los elementos repetidos de una lista perdemos el orden original de nuestra lista. Además, no funcionará si nuestra lista es de diccionarios o de listas, debido a que no son objetos hashables.
Usando la tupla que creaste en el ejercicio sobre tuplas, crea un diccionario de tu lista de la compra. Una vez tengas el diccionario creado:
format
: "he comprado __
y me ha costado __
".del
In [13]:
dict_compra = dict(tuplas_compra)
for compra in dict_compra.items():
print("he comprado {} y me ha costado {}".format(compra[0], compra[1]))
print('He comprado leche?', 'Leche' in dict_compra)
del dict_compra['Arroz']
print(dict_compra)
Ahora que hemos visto cómo crear arrays a partir de un objeto y otros para crear arrays con tipos prefijados, crea distintos arrays con las funciones anteriores para 1D, 2D y 3D e imprímelas por pantalla. Prueba a usar distintos tipos para ver cómo cambian los arrays. Si tienes dudas sobre cómo usarlos, puedes consultar la documentación oficial.
In [14]:
import numpy as np
print(np.ones(5, dtype=np.int8))
print(np.random.random(5))
print(np.full(shape=(3,3), fill_value=4, dtype=np.int8))
print(np.arange(6))
print(np.linspace(start=1, stop=6, num=10))
print(np.eye(N=2))
print(np.identity(n=3, dtype=np.int8))
Gracias a las distintas formas de indexar un array que nos permite NumPy, podemos hacer operaciones de forma vectorizada, evitando los bucles. Esto supone un incremento en la eficiencia del código y tener un código más corto y legible. Para ello, vamos a realizar el siguiente ejercicio.
Genera una matriz aleatoria cuadrada de tamaño 1000. Una vez creada, genera una nueva matriz donde las filas y columnas 0 y $n-1$ estén repetidas 500 veces y el centro de la matriz quede exactamente igual a la original. Un ejemplo de esto lo podemos ver a continuación:
$$ \left( \begin{matrix} 1 & 2 & 3 \\ 2 & 3 & 4 \\ 3 & 4 & 5 \end{matrix} \right) \Longrightarrow \left( \begin{matrix} 1 & 1 & 1 & 2 & 3 & 3 & 3 \\ 1 & 1 & 1 & 2 & 3 & 3 & 3 \\ 1 & 1 & 1 & 2 & 3 & 3 & 3 \\ 2 & 2 & 2 & 3 & 4 & 4 & 4 \\ 3 & 3 & 3 & 4 & 5 & 5 & 5 \\ 3 & 3 & 3 & 4 & 5 & 5 & 5 \\ 3 & 3 & 3 & 4 & 5 & 5 & 5 \end{matrix} \right) $$Impleméntalo usando un bucle for
y vectorizando el cálculo usando lo anteriormente visto para ver la diferencias de tiempos usando ambas variantes. Para medir el tiempo, puedes usar el módulo time
.
In [15]:
from time import time
def clona_cols_rows(size=1000, clone=500, print_matrix=False,
create_random=True):
if create_random:
m = np.random.random((size,size))
else:
m = np.arange(size*size).reshape(size,size)
n = np.zeros((size+clone*2, size+clone*2))
antes = time()
# en primer lugar, copiamos m en el centro de n
for i in range(size):
for j in range(size):
n[i+clone, j+clone] = m[i,j]
# después, copiamos la primera fila/columna en las
# primeras clone filas/columnas
for i in range(clone):
n[i,clone:clone+size] = m[0]
n[clone:clone+size, i] = m[:,0]
# una vez copiada la primera fila/columna, pasamos a
# copiar la última/columna
for i in range(clone+size, size+clone*2):
n[i, clone:clone+size] = m[-1]
n[clone:clone+size, i] = m[:,-1]
# por último, copiamos los valores de los extremos en las esquinas
for i in range(clone):
n[i, :clone] = np.full(clone, m[0,0])
n[i, size+clone:] = np.full(clone, m[0,-1])
n[i+size+clone, :clone] = np.full(clone, m[-1,0])
n[i+size+clone, size+clone:] = np.full(clone, m[-1,-1])
despues = time()
if print_matrix:
print(m)
print(n)
return despues-antes
clona_cols_rows(size=3, clone=2, print_matrix=True, create_random=False)
print("Tiempo con bucle for: ", clona_cols_rows(), " s")
In [16]:
def clona_vec_cols_rows(size=1000, clone=500, print_matrix=False,
create_random=True):
if create_random:
m = np.random.random((size,size))
else:
m = np.arange(size*size).reshape(size,size)
n = np.zeros((size+clone*2, size+clone*2))
antes=time()
# en primer lugar, insertamos m en el centro de n
n[clone:clone+size, clone:clone+size] = m
# Copiamos la primera fila de m, en las primeras filas
# de n, y la última fila de m en las últimas filas de n
n[:clone, clone:clone+size] = m[0]
n[size+clone:, clone:size+clone] = m[-1]
# Lo mismo para las columnas
n[:, :clone] = np.repeat(n[:,clone],clone).reshape(2*clone+size, clone)
n[:, size+clone:] = np.repeat(n[:,-(clone+1)],clone).reshape(2*clone+size, clone)
despues=time()
if print_matrix:
print(m)
print(n)
return despues-antes
clona_vec_cols_rows(size=3, clone=2, print_matrix=True, create_random=False)
print("Tiempo vectorizando: ", clona_vec_cols_rows(), " s")
Una matriz de rotación $R$ es una matriz que representa una rotación en el espacio euclídeo. Esta matriz $R$ se representa como
$$ R = \left( \begin{matrix} \cos\theta & -\sin\theta \\ \sin\theta & -\cos\theta \end{matrix} \right) $$donde $\theta$ es el número de ángulos rotados en sentido antihorario.
Estas matrices son muy usadas en geometría, informática o física. Un ejemplo de uso de estas matrices puede ser el cálculo de una rotación de un objeto en un sistema gráfico, la rotación de una cámara respecto a un punto en el espacio, etc.
Estas matrices tienen como propiedades que son matrices ortogonales (su inversa y su traspuesta son iguales) y su determinante es igual a 1. Por tanto, genera un array y muestra si ese array es una matriz de rotación.
In [17]:
R = np.random.random((2,2))
if (R.T == np.linalg.inv(R)).all() and np.linalg.det(R) == 1:
print("Matriz de rotación!")
else:
print("No es matriz de rotación u_u")
In [18]:
array1 = np.array([ -1., 4., -9.])
Multiplica array1 por $\frac{\pi}{4}$ y calcula el seno del array resultante.
Genera un nuevo array cuyo valor sea el doble del resultado anterior mas el vector array1
.
Calcula la norma del vector resultante. Para ello, consulta la documentación para ver qué función realiza esta tarea, y ten en cuenta los parámetros que recibe.
In [19]:
array2 = np.sin(array1 * np.pi/4)
array2
Out[19]:
In [20]:
array3 = array2 * 2 + array1
array3
Out[20]:
In [21]:
np.linalg.norm(array3)
Out[21]:
In [22]:
n_array1 = np.array([[ 1., 3., 5.], [7., -9., 2.], [4., 6., 8.]])
In [23]:
media = np.mean(n_array1)
desv_tipica = np.std(n_array1)
print("Media =", media, " y desv típica =", desv_tipica)
In [24]:
maximo = np.max(n_array1)
minimo = np.min(n_array1)
print("Máximo =", maximo, " y minimo =", minimo)
In [25]:
det = np.linalg.det(n_array1)
traza = np.trace(n_array1)
traspuesta = n_array1.T
In [27]:
U, S, V = np.linalg.svd(n_array1)
print(U)
print(S)
print(V)
In [30]:
result = np.diag(array1).sum()
print("Resultado: ", result)
A veces, es necesario en nuestro problema, tener que eliminar los elementos repetidos de una lista, dejando aquellos que solo aparezcan una sola vez. Es muy común, que muchos usuarios llamen a la función set
para esta tarea, haciendo de la lista un conjunto sin elementos repetidos, ordenándolos y luego, el resultado de esto, volverlo a convertir en una lista. Esto, puede no estar mal del todo, pero puede ser que en el caso peor, puede que estemos haciendo un gasto inútil de memoria, tiempo y cálculos, para que, en el caso de que no haya elementos repetidos, sólo obtengamos una lista ordenada.
Es por ello, por lo que existe otra forma de hacerlo. Utilizando lo ya visto, obtén una lista sin elementos repetidos que mantengan el orden de la lista original. Para hacerlo aún más divertido, no uses más de 4 líneas.
In [35]:
a = [1,1,1,2,5,3,4,8,5,8]
b = []
list(filter(lambda x: b.append(x) if not x in b else False, a))
print("Lista original:\t\t", a)
print("Lista sin repetidos:\t", b)